Browse Source

latest changes from main repository

Guenter Obiltschnig 19 years ago
parent
commit
ba1384e12d

+ 2 - 1
Foundation/include/Poco/AbstractCache.h

@@ -1,7 +1,7 @@
 //
 // AbstractCache.h
 //
-// $Id: //poco/Main/Foundation/include/Poco/AbstractCache.h#13 $
+// $Id: //poco/Main/Foundation/include/Poco/AbstractCache.h#14 $
 //
 // Library: Foundation
 // Package: Cache
@@ -50,6 +50,7 @@
 #include "Poco/SharedPtr.h"
 #include <map>
 #include <set>
+#include <cstddef>
 
 
 namespace Poco {

+ 2 - 1
Foundation/include/Poco/DynamicAnyHolder.h

@@ -1,7 +1,7 @@
 //
 // DynamicAnyHolder.h
 //
-// $Id: //poco/Main/Foundation/include/Poco/DynamicAnyHolder.h#3 $
+// $Id: //poco/Main/Foundation/include/Poco/DynamicAnyHolder.h#4 $
 //
 // Library: Poco
 // Package: Core
@@ -211,6 +211,7 @@ class DynamicAnyHolderImpl: public DynamicAnyHolder
 	///		RangeException (if an attempt is made to assign a numeric value outside of the target min/max limits
 	///		SyntaxException (if an attempt is made to convert a string containing non-numeric characters to number)
 {
+public:
 	DynamicAnyHolderImpl()
 	{
 	}

+ 5 - 5
Foundation/include/Poco/HashTable.h

@@ -1,7 +1,7 @@
 //
 // HashTable.h
 //
-// $Id: //poco/Main/Foundation/include/Poco/HashTable.h#8 $
+// $Id: //poco/Main/Foundation/include/Poco/HashTable.h#9 $
 //
 // Library: Foundation
 // Package: Hashing
@@ -46,7 +46,7 @@
 #include "Poco/HashStatistic.h"
 #include <vector>
 #include <map>
-#include <stddef.h>
+#include <cstddef>
 
 
 namespace Poco {
@@ -293,7 +293,7 @@ public:
 		return _entries[hsh] && (_entries[hsh]->end() != _entries[hsh]->find(key));
 	}
 
-	size_t size() const
+	std::size_t size() const
 		/// Returns the number of elements already inserted into the HashTable
 	{
 		return _size;
@@ -379,8 +379,8 @@ public:
 
 private:
 	HashTableVector _entries;
-	size_t _size;
-	UInt32 _maxCapacity;
+	std::size_t     _size;
+	UInt32          _maxCapacity;
 	KeyHashFunction _hash;
 };
 

+ 9 - 8
Foundation/include/Poco/LRUStrategy.h

@@ -1,7 +1,7 @@
 //
 // LRUStrategy.h
 //
-// $Id: //poco/Main/Foundation/include/Poco/LRUStrategy.h#4 $
+// $Id: //poco/Main/Foundation/include/Poco/LRUStrategy.h#5 $
 //
 // Library: Foundation
 // Package: Cache
@@ -47,6 +47,7 @@
 #include "Poco/Exception.h"
 #include <list>
 #include <map>
+#include <cstddef>
 
 
 namespace Poco {
@@ -65,7 +66,7 @@ public:
 	typedef typename KeyIndex::const_iterator ConstIndexIterator;
 
 public:
-	LRUStrategy(size_t size): 
+	LRUStrategy(std::size_t size): 
 		_size(size)
 	{
 		if (_size < 1) throw InvalidArgumentException("size must be > 0");
@@ -127,16 +128,16 @@ public:
 		// Note: replace only informs the cache which elements
 		// it would like to remove!
 		// it does not remove them on its own!
-		size_t curSize = _keyIndex.size();
+		std::size_t curSize = _keyIndex.size();
 
 		if (curSize < _size)
 		{
 			return;
 		}
 
-		size_t diff = curSize - _size;
+		std::size_t diff = curSize - _size;
 		Iterator it = --_keys.end(); //--keys can never be invoked on an empty list due to the minSize==1 requirement of LRU
-		size_t i = 0;
+		std::size_t i = 0;
 
 		while (i++ < diff) 
 		{
@@ -149,9 +150,9 @@ public:
 	}
 
 protected:
-	size_t   _size;     /// Number of keys the cache can store.
-	Keys     _keys;
-	KeyIndex _keyIndex; /// For faster access to _keys
+	std::size_t _size;     /// Number of keys the cache can store.
+	Keys        _keys;
+	KeyIndex    _keyIndex; /// For faster access to _keys
 };
 
 

+ 2 - 1
Foundation/include/Poco/SharedMemory.h

@@ -1,7 +1,7 @@
 //
 // SharedMemory.h
 //
-// $Id: //poco/Main/Foundation/include/Poco/SharedMemory.h#3 $
+// $Id: //poco/Main/Foundation/include/Poco/SharedMemory.h#4 $
 //
 // Library: Poco
 // Package: Processes
@@ -42,6 +42,7 @@
 
 #include "Poco/Poco.h"
 #include <algorithm>
+#include <cstddef>
 
 
 namespace Poco {

+ 5 - 1
Foundation/src/SharedMemory_POSIX.cpp

@@ -1,7 +1,7 @@
 //
 // SharedMemoryImpl.cpp
 //
-// $Id: //poco/Main/Foundation/src/SharedMemory_POSIX.cpp#7 $
+// $Id: //poco/Main/Foundation/src/SharedMemory_POSIX.cpp#8 $
 //
 // Library: Poco
 // Package: Processes
@@ -55,6 +55,10 @@ SharedMemoryImpl::SharedMemoryImpl(const std::string& name, std::size_t size, Sh
 	_name("/"),
 	_fileMapped(false)
 {
+#if POCO_OS == POCO_OS_HPUX
+	_name.append("tmp/");
+#endif
+
 	_name.append(name);
 
 	int flags = O_CREAT;

+ 4 - 3
Net/include/Poco/Net/HTTPChunkedStream.h

@@ -1,7 +1,7 @@
 //
 // HTTPChunkedStream.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/HTTPChunkedStream.h#3 $
+// $Id: //poco/Main/Net/include/Poco/Net/HTTPChunkedStream.h#4 $
 //
 // Library: Net
 // Package: HTTP
@@ -43,6 +43,7 @@
 #include "Poco/Net/Net.h"
 #include "Poco/Net/HTTPBasicStreamBuf.h"
 #include "Poco/MemoryPool.h"
+#include <cstddef>
 #include <istream>
 #include <ostream>
 
@@ -97,7 +98,7 @@ public:
 	HTTPChunkedInputStream(HTTPSession& session);
 	~HTTPChunkedInputStream();
 	
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:
@@ -112,7 +113,7 @@ public:
 	HTTPChunkedOutputStream(HTTPSession& session);
 	~HTTPChunkedOutputStream();
 
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:

+ 4 - 3
Net/include/Poco/Net/HTTPFixedLengthStream.h

@@ -1,7 +1,7 @@
 //
 // HTTPFixedLengthStream.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/HTTPFixedLengthStream.h#2 $
+// $Id: //poco/Main/Net/include/Poco/Net/HTTPFixedLengthStream.h#3 $
 //
 // Library: Net
 // Package: HTTP
@@ -42,6 +42,7 @@
 
 #include "Poco/Net/Net.h"
 #include "Poco/Net/HTTPBasicStreamBuf.h"
+#include <cstddef>
 #include <istream>
 #include <ostream>
 
@@ -96,7 +97,7 @@ public:
 	HTTPFixedLengthInputStream(HTTPSession& session, std::streamsize length);
 	~HTTPFixedLengthInputStream();
 	
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:
@@ -111,7 +112,7 @@ public:
 	HTTPFixedLengthOutputStream(HTTPSession& session, std::streamsize length);
 	~HTTPFixedLengthOutputStream();
 
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:

+ 4 - 3
Net/include/Poco/Net/HTTPHeaderStream.h

@@ -1,7 +1,7 @@
 //
 // HTTPHeaderStream.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/HTTPHeaderStream.h#2 $
+// $Id: //poco/Main/Net/include/Poco/Net/HTTPHeaderStream.h#3 $
 //
 // Library: Net
 // Package: HTTP
@@ -43,6 +43,7 @@
 #include "Poco/Net/Net.h"
 #include "Poco/Net/HTTPBasicStreamBuf.h"
 #include "Poco/MemoryPool.h"
+#include <cstddef>
 #include <istream>
 #include <ostream>
 
@@ -94,7 +95,7 @@ public:
 	HTTPHeaderInputStream(HTTPSession& session);
 	~HTTPHeaderInputStream();
 
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:
@@ -109,7 +110,7 @@ public:
 	HTTPHeaderOutputStream(HTTPSession& session);
 	~HTTPHeaderOutputStream();
 
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:

+ 2 - 1
Net/include/Poco/Net/HTTPServerResponse.h

@@ -1,7 +1,7 @@
 //
 // HTTPServerResponse.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/HTTPServerResponse.h#5 $
+// $Id: //poco/Main/Net/include/Poco/Net/HTTPServerResponse.h#6 $
 //
 // Library: Net
 // Package: HTTPServer
@@ -42,6 +42,7 @@
 
 #include "Poco/Net/Net.h"
 #include "Poco/Net/HTTPResponse.h"
+#include <cstddef>
 #include <ostream>
 
 

+ 1 - 2
Net/include/Poco/Net/HTTPServerResponseImpl.h

@@ -1,7 +1,7 @@
 //
 // HTTPServerResponseImpl.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/HTTPServerResponseImpl.h#2 $
+// $Id: //poco/Main/Net/include/Poco/Net/HTTPServerResponseImpl.h#3 $
 //
 // Library: Net
 // Package: HTTPServer
@@ -42,7 +42,6 @@
 
 #include "Poco/Net/Net.h"
 #include "Poco/Net/HTTPServerResponse.h"
-#include <ostream>
 
 
 namespace Poco {

+ 4 - 3
Net/include/Poco/Net/HTTPStream.h

@@ -1,7 +1,7 @@
 //
 // HTTPStream.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/HTTPStream.h#2 $
+// $Id: //poco/Main/Net/include/Poco/Net/HTTPStream.h#3 $
 //
 // Library: Net
 // Package: HTTP
@@ -43,6 +43,7 @@
 #include "Poco/Net/Net.h"
 #include "Poco/Net/HTTPBasicStreamBuf.h"
 #include "Poco/MemoryPool.h"
+#include <cstddef>
 #include <istream>
 #include <ostream>
 
@@ -95,7 +96,7 @@ public:
 	HTTPInputStream(HTTPSession& session);
 	~HTTPInputStream();
 
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:
@@ -110,7 +111,7 @@ public:
 	HTTPOutputStream(HTTPSession& session);
 	~HTTPOutputStream();
 
-	void* operator new(size_t size);
+	void* operator new(std::size_t size);
 	void operator delete(void* ptr);
 	
 private:

+ 13 - 1
Net/include/Poco/Net/IPAddress.h

@@ -1,7 +1,7 @@
 //
 // IPAddress.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/IPAddress.h#2 $
+// $Id: //poco/Main/Net/include/Poco/Net/IPAddress.h#3 $
 //
 // Library: Net
 // Package: NetCore
@@ -288,6 +288,18 @@ public:
 	int af() const;
 		/// Returns the address family (AF_INET or AF_INET6) of the address.
 		
+	void mask(const IPAddress& mask);
+		/// Masks the IP address using the given netmask, which is usually
+		/// a IPv4 subnet mask. Only supported for IPv4 addresses.
+		///
+		/// The new address is (address & mask).
+		
+	void mask(const IPAddress& mask, const IPAddress& set);
+		/// Masks the IP address using the given netmask, which is usually
+		/// a IPv4 subnet mask. Only supported for IPv4 addresses.
+		///
+		/// The new address is (address & mask) | (set & ~mask).
+		
 	static IPAddress parse(const std::string& addr);
 		/// Creates an IPAddress from the string containing
 		/// an IP address in presentation format (dotted decimal

+ 17 - 37
Net/include/Poco/Net/NetworkInterface.h

@@ -1,7 +1,7 @@
 //
 // NetworkInterface.h
 //
-// $Id: //poco/Main/Net/include/Poco/Net/NetworkInterface.h#2 $
+// $Id: //poco/Main/Net/include/Poco/Net/NetworkInterface.h#3 $
 //
 // Library: Net
 // Package: Sockets
@@ -50,6 +50,9 @@ namespace Poco {
 namespace Net {
 
 
+class NetworkInterfaceImpl;
+
+
 class Net_API NetworkInterface
 	/// This class represents a network interface.
 	/// 
@@ -76,6 +79,9 @@ public:
 	NetworkInterface& operator = (const NetworkInterface& interface);
 		/// Assigns another NetworkInterface.
 		
+	void swap(NetworkInterface& other);
+		/// Swaps the NetworkInterface with another one.	
+		
 	int index() const;
 		/// Returns the interface index.
 		///
@@ -88,6 +94,12 @@ public:
 	const IPAddress& address() const;
 		/// Returns the IP address bound to the interface.
 		
+	const IPAddress& subnetMask() const;
+		/// Returns the IPv4 subnet mask for this network interface.
+		
+	const IPAddress& broadcastAddress() const;
+		/// Returns the IPv4 broadcast address for this network interface.
+		
 	bool supportsIPv4() const;
 		/// Returns true if the interface supports IPv4.
 		
@@ -130,6 +142,9 @@ public:
 protected:
 	NetworkInterface(const std::string& name, const IPAddress& address, int index = -1);
 		/// Creates the NetworkInterface.
+
+	NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index = -1);
+		/// Creates the NetworkInterface.
 		
 	IPAddress interfaceNameToAddress(const std::string& interfaceName) const;
 		/// Determines the IPAddress bound to the interface with the given name.
@@ -138,47 +153,12 @@ protected:
 		/// Determines the interface index of the interface with the given name.
 
 private:
-	std::string _name;
-	IPAddress   _address;
-	int         _index;
+	NetworkInterfaceImpl* _pImpl;
 	
 	static Poco::FastMutex _mutex;
 };
 
 
-//
-// inlines
-//
-inline int NetworkInterface::index() const
-{
-	return _index;
-}
-
-
-inline const std::string& NetworkInterface::name() const
-{
-	return _name;
-}
-
-
-inline const IPAddress& NetworkInterface::address() const
-{
-	return _address;
-}
-
-
-inline bool NetworkInterface::supportsIPv4() const
-{
-	return _index == -1;
-}
-
-	
-inline bool NetworkInterface::supportsIPv6() const
-{
-	return _index != -1;
-}
-
-
 } } // namespace Poco::Net
 
 

+ 3 - 3
Net/src/HTTPChunkedStream.cpp

@@ -1,7 +1,7 @@
 //
 // HTTPChunkedStream.cpp
 //
-// $Id: //poco/Main/Net/src/HTTPChunkedStream.cpp#12 $
+// $Id: //poco/Main/Net/src/HTTPChunkedStream.cpp#13 $
 //
 // Library: Net
 // Package: HTTP
@@ -172,7 +172,7 @@ HTTPChunkedInputStream::~HTTPChunkedInputStream()
 }
 
 
-void* HTTPChunkedInputStream::operator new(size_t size)
+void* HTTPChunkedInputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }
@@ -204,7 +204,7 @@ HTTPChunkedOutputStream::~HTTPChunkedOutputStream()
 }
 
 
-void* HTTPChunkedOutputStream::operator new(size_t size)
+void* HTTPChunkedOutputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }

+ 3 - 3
Net/src/HTTPFixedLengthStream.cpp

@@ -1,7 +1,7 @@
 //
 // HTTPFixedLengthStream.cpp
 //
-// $Id: //poco/Main/Net/src/HTTPFixedLengthStream.cpp#9 $
+// $Id: //poco/Main/Net/src/HTTPFixedLengthStream.cpp#10 $
 //
 // Library: Net
 // Package: HTTP
@@ -142,7 +142,7 @@ HTTPFixedLengthInputStream::~HTTPFixedLengthInputStream()
 }
 
 
-void* HTTPFixedLengthInputStream::operator new(size_t size)
+void* HTTPFixedLengthInputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }
@@ -174,7 +174,7 @@ HTTPFixedLengthOutputStream::~HTTPFixedLengthOutputStream()
 }
 
 
-void* HTTPFixedLengthOutputStream::operator new(size_t size)
+void* HTTPFixedLengthOutputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }

+ 3 - 3
Net/src/HTTPHeaderStream.cpp

@@ -1,7 +1,7 @@
 //
 // HTTPHeaderStream.cpp
 //
-// $Id: //poco/Main/Net/src/HTTPHeaderStream.cpp#9 $
+// $Id: //poco/Main/Net/src/HTTPHeaderStream.cpp#10 $
 //
 // Library: Net
 // Package: HTTP
@@ -139,7 +139,7 @@ HTTPHeaderInputStream::~HTTPHeaderInputStream()
 }
 
 
-void* HTTPHeaderInputStream::operator new(size_t size)
+void* HTTPHeaderInputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }
@@ -171,7 +171,7 @@ HTTPHeaderOutputStream::~HTTPHeaderOutputStream()
 }
 
 
-void* HTTPHeaderOutputStream::operator new(size_t size)
+void* HTTPHeaderOutputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }

+ 3 - 3
Net/src/HTTPStream.cpp

@@ -1,7 +1,7 @@
 //
 // HTTPStream.cpp
 //
-// $Id: //poco/Main/Net/src/HTTPStream.cpp#9 $
+// $Id: //poco/Main/Net/src/HTTPStream.cpp#10 $
 //
 // Library: Net
 // Package: HTTP
@@ -133,7 +133,7 @@ HTTPInputStream::~HTTPInputStream()
 }
 
 
-void* HTTPInputStream::operator new(size_t size)
+void* HTTPInputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }
@@ -165,7 +165,7 @@ HTTPOutputStream::~HTTPOutputStream()
 }
 
 
-void* HTTPOutputStream::operator new(size_t size)
+void* HTTPOutputStream::operator new(std::size_t size)
 {
 	return _pool.get();
 }

+ 28 - 1
Net/src/IPAddress.cpp

@@ -1,7 +1,7 @@
 //
 // IPAddress.cpp
 //
-// $Id: //poco/Main/Net/src/IPAddress.cpp#13 $
+// $Id: //poco/Main/Net/src/IPAddress.cpp#15 $
 //
 // Library: Net
 // Package: NetCore
@@ -81,6 +81,7 @@ public:
 	virtual bool isSiteLocalMC() const = 0;
 	virtual bool isOrgLocalMC() const = 0;
 	virtual bool isGlobalMC() const = 0;
+	virtual void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet) = 0;
 
 protected:
 	IPAddressImpl()
@@ -237,6 +238,14 @@ public:
 			return 0;
 #endif
 	}
+	
+	void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet)
+	{
+		poco_assert (pMask->af() == AF_INET && pSet->af() == AF_INET);
+		
+		_addr.s_addr &= static_cast<const IPv4AddressImpl*>(pMask)->_addr.s_addr;
+		_addr.s_addr |= static_cast<const IPv4AddressImpl*>(pSet)->_addr.s_addr & ~static_cast<const IPv4AddressImpl*>(pMask)->_addr.s_addr;
+	}
 		
 private:
 	struct in_addr _addr;	
@@ -435,6 +444,11 @@ public:
 			return 0;
 #endif
 	}
+	
+	void mask(const IPAddressImpl* pMask, const IPAddressImpl* pSet)
+	{
+		throw Poco::NotImplementedException("mask() is only supported for IPv4 addresses");
+	}
 
 private:
 	struct in6_addr _addr;	
@@ -744,4 +758,17 @@ bool IPAddress::tryParse(const std::string& addr, IPAddress& result)
 }
 
 
+void IPAddress::mask(const IPAddress& mask)
+{
+	IPAddress null;
+	_pImpl->mask(mask._pImpl, null._pImpl);
+}
+
+
+void IPAddress::mask(const IPAddress& mask, const IPAddress& set)
+{
+	_pImpl->mask(mask._pImpl, set._pImpl);
+}
+
+
 } } // namespace Poco::Net

+ 219 - 45
Net/src/NetworkInterface.cpp

@@ -1,7 +1,7 @@
 //
 // NetworkInterface.cpp
 //
-// $Id: //poco/Main/Net/src/NetworkInterface.cpp#16 $
+// $Id: //poco/Main/Net/src/NetworkInterface.cpp#18 $
 //
 // Library: Net
 // Package: Sockets
@@ -38,6 +38,7 @@
 #include "Poco/Net/DatagramSocket.h"
 #include "Poco/Net/NetException.h"
 #include "Poco/NumberFormatter.h"
+#include "Poco/RefCountedObject.h"
 #include <string.h>
 
 
@@ -49,48 +50,215 @@ namespace Poco {
 namespace Net {
 
 
-FastMutex NetworkInterface::_mutex;
+//
+// NetworkInterfaceImpl
+//
 
 
-NetworkInterface::NetworkInterface():
-	_index(0)
+class NetworkInterfaceImpl: public Poco::RefCountedObject
+{
+public:
+	NetworkInterfaceImpl();
+	NetworkInterfaceImpl(const std::string& name, const IPAddress& address, int index = -1);
+	NetworkInterfaceImpl(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index = -1);
+
+	int index() const;		
+	const std::string& name() const;
+	const IPAddress& address() const;
+	const IPAddress& subnetMask() const;
+	const IPAddress& broadcastAddress() const;
+
+protected:
+	~NetworkInterfaceImpl();
+
+private:	
+	std::string _name;
+	IPAddress   _address;
+	IPAddress   _subnetMask;
+	IPAddress   _broadcastAddress;
+	int         _index;
+};
+
+
+NetworkInterfaceImpl::NetworkInterfaceImpl():
+	_index(-1)
 {
 }
 
 
-NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, int index):
+NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const IPAddress& address, int index):
 	_name(name),
 	_address(address),
 	_index(index)
 {
+#ifndef _WIN32
+	if (index == -1) // IPv4
+	{
+		struct ifreq ifr;
+		strncpy(ifr.ifr_name, name.c_str(), IFNAMSIZ);
+		DatagramSocket ds(IPAddress::IPv4);
+		ds.impl()->ioctl(SIOCGIFNETMASK, &ifr);
+		if (ifr.ifr_addr.sa_family == AF_INET)
+			_subnetMask = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));
+		if (!address.isLoopback())
+		{
+			try
+			{
+				// Not every interface (e.g. loopback) has a broadcast address
+				ds.impl()->ioctl(SIOCGIFBRDADDR, &ifr);
+				if (ifr.ifr_addr.sa_family == AF_INET)
+					_broadcastAddress = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));
+			}
+			catch (...)
+			{
+			}
+		}
+	}
+#endif
+}
+
+
+NetworkInterfaceImpl::NetworkInterfaceImpl(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index):
+	_name(name),
+	_address(address),
+	_subnetMask(subnetMask),
+	_broadcastAddress(broadcastAddress),
+	_index(index)
+{
+}
+
+
+NetworkInterfaceImpl::~NetworkInterfaceImpl()
+{
+}
+
+
+inline int NetworkInterfaceImpl::index() const
+{
+	return _index;
+}
+
+
+inline const std::string& NetworkInterfaceImpl::name() const
+{
+	return _name;
+}
+
+
+inline const IPAddress& NetworkInterfaceImpl::address() const
+{
+	return _address;
+}
+
+
+inline const IPAddress& NetworkInterfaceImpl::subnetMask() const
+{
+	return _subnetMask;
+}
+
+
+inline const IPAddress& NetworkInterfaceImpl::broadcastAddress() const
+{
+	return _broadcastAddress;
+}
+
+
+//
+// NetworkInterface
+//
+
+
+FastMutex NetworkInterface::_mutex;
+
+
+NetworkInterface::NetworkInterface():
+	_pImpl(new NetworkInterfaceImpl)
+{
 }
 
 
 NetworkInterface::NetworkInterface(const NetworkInterface& interface):
-	_name(interface._name),
-	_address(interface._address),
-	_index(interface._index)
+	_pImpl(interface._pImpl)
+{
+	_pImpl->duplicate();
+}
+
+
+NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, int index):
+	_pImpl(new NetworkInterfaceImpl(name, address, index))
+{
+}
+
+
+NetworkInterface::NetworkInterface(const std::string& name, const IPAddress& address, const IPAddress& subnetMask, const IPAddress& broadcastAddress, int index):
+	_pImpl(new NetworkInterfaceImpl(name, address, subnetMask, broadcastAddress, index))
 {
 }
 
 
 NetworkInterface::~NetworkInterface()
 {
+	_pImpl->release();
 }
 
 
 NetworkInterface& NetworkInterface::operator = (const NetworkInterface& interface)
 {
-	if (&interface != this)
-	{
-		_name    = interface._name;
-		_address = interface._address;
-		_index   = interface._index;
-	}
+	NetworkInterface tmp(interface);
+	swap(tmp);
 	return *this;
 }
 
 
+void NetworkInterface::swap(NetworkInterface& other)
+{
+	using std::swap;
+	swap(_pImpl, other._pImpl);
+}
+
+
+int NetworkInterface::index() const
+{
+	return _pImpl->index();
+}
+
+
+const std::string& NetworkInterface::name() const
+{
+	return _pImpl->name();
+}
+
+
+const IPAddress& NetworkInterface::address() const
+{
+	return _pImpl->address();
+}
+
+
+const IPAddress& NetworkInterface::subnetMask() const
+{
+	return _pImpl->subnetMask();
+}
+
+
+const IPAddress& NetworkInterface::broadcastAddress() const
+{
+	return _pImpl->broadcastAddress();
+}
+
+
+bool NetworkInterface::supportsIPv4() const
+{
+	return _pImpl->index() == -1;
+}
+
+	
+bool NetworkInterface::supportsIPv6() const
+{
+	return _pImpl->index() != -1;
+}
+
+
 NetworkInterface NetworkInterface::forName(const std::string& name, bool requireIPv6)
 {
 #if defined(_WIN32)
@@ -114,12 +282,14 @@ NetworkInterface NetworkInterface::forName(const std::string& name, bool require
 		addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));
 	else if (ifr.ifr_addr.sa_family == AF_INET6)
 		addr = IPAddress(&reinterpret_cast<const struct sockaddr_in6*>(&ifr.ifr_addr)->sin6_addr, sizeof(struct in6_addr));
-	else throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");
+	else
+		throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");
 	int index = if_nametoindex(name.c_str());
 #else
 	if (ifr.ifr_addr.sa_family == AF_INET)
 		addr = IPAddress(&reinterpret_cast<const struct sockaddr_in*>(&ifr.ifr_addr)->sin_addr, sizeof(struct in_addr));
-	else throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");
+	else
+		throw InterfaceNotFoundException(addr.toString(), "interface has no IP address");
 	int index = 0;
 #endif
 	return NetworkInterface(name, addr, index);
@@ -178,20 +348,21 @@ NetworkInterface::NetworkInterfaceList NetworkInterface::list()
 {
 	FastMutex::ScopedLock lock(_mutex);
 	NetworkInterfaceList result;
-	
+	DWORD rc;
+
 #if defined(POCO_HAVE_IPv6)
 	// On Windows XP/Server 2003 and later we use GetAdaptersAddresses.
 	PIP_ADAPTER_ADDRESSES pAdapterAddresses;
-	PIP_ADAPTER_ADDRESSES pAdapter = 0;
-	ULONG len         = sizeof(IP_ADAPTER_ADDRESSES);
-	pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[len]);
+	PIP_ADAPTER_ADDRESSES pAddress = 0;
+	ULONG addrLen     = sizeof(IP_ADAPTER_ADDRESSES);
+	pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[addrLen]);
 	// Make an initial call to GetAdaptersAddresses to get
-	// the necessary size into len
-	DWORD rc = GetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &len);
+	// the necessary size into addrLen
+	rc = GetAdaptersAddresses(AF_INET6, 0, 0, pAdapterAddresses, &addrLen);
 	if (rc == ERROR_BUFFER_OVERFLOW) 
 	{
 		delete [] reinterpret_cast<char*>(pAdapterAddresses);
-		pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[len]);
+		pAdapterAddresses = reinterpret_cast<IP_ADAPTER_ADDRESSES*>(new char[addrLen]);
 	}
 	else if (rc != ERROR_SUCCESS)
 	{
@@ -199,16 +370,16 @@ NetworkInterface::NetworkInterfaceList NetworkInterface::list()
 	}
 	try
 	{
-		if (GetAdaptersAddresses(AF_UNSPEC, 0, 0, pAdapterAddresses, &len) == NO_ERROR) 
+		if (GetAdaptersAddresses(AF_INET6, 0, 0, pAdapterAddresses, &addrLen) == NO_ERROR) 
 		{
-			pAdapter = pAdapterAddresses;
-			while (pAdapter) 
+			pAddress = pAdapterAddresses;
+			while (pAddress) 
 			{
-				if (pAdapter->FirstUnicastAddress)
+				if (pAddress->FirstUnicastAddress)
 				{
-					IPAddress addr(pAdapter->FirstUnicastAddress->Address.lpSockaddr, pAdapter->FirstUnicastAddress->Address.iSockaddrLength);
-					result.push_back(NetworkInterface(std::string(pAdapter->AdapterName), addr, pAdapter->Ipv6IfIndex));
-					pAdapter = pAdapter->Next;
+					IPAddress addr(pAddress->FirstUnicastAddress->Address.lpSockaddr, pAddress->FirstUnicastAddress->Address.iSockaddrLength);
+					result.push_back(NetworkInterface(std::string(pAddress->AdapterName), addr, pAddress->Ipv6IfIndex));
+					pAddress = pAddress->Next;
 				}
 			}
 		}
@@ -220,21 +391,22 @@ NetworkInterface::NetworkInterfaceList NetworkInterface::list()
 		throw;
 	}
 	delete [] reinterpret_cast<char*>(pAdapterAddresses);
-#else
-	// Add loopback interface (not returned by GetAdaptersInfo)
+#endif
+
+	// Add IPv4 loopback interface (not returned by GetAdaptersInfo)
 	result.push_back(NetworkInterface("Loopback", IPAddress("127.0.0.1"), -1));
 	// On Windows 2000 we use GetAdaptersInfo.
 	PIP_ADAPTER_INFO pAdapterInfo;
-	PIP_ADAPTER_INFO pAdapter = 0;
-	ULONG len    = sizeof(IP_ADAPTER_INFO);
-	pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
+	PIP_ADAPTER_INFO pInfo = 0;
+	ULONG infoLen = sizeof(IP_ADAPTER_INFO);
+	pAdapterInfo  = reinterpret_cast<IP_ADAPTER_INFO*>(new char[infoLen]);
 	// Make an initial call to GetAdaptersInfo to get
-	// the necessary size into len
-	DWORD rc = GetAdaptersInfo(pAdapterInfo, &len);
+	// the necessary size into infoLen
+	rc = GetAdaptersInfo(pAdapterInfo, &infoLen);
 	if (rc == ERROR_BUFFER_OVERFLOW) 
 	{
 		delete [] reinterpret_cast<char*>(pAdapterInfo);
-		pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[len]);
+		pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO*>(new char[infoLen]);
 	}
 	else if (rc != ERROR_SUCCESS)
 	{
@@ -242,14 +414,17 @@ NetworkInterface::NetworkInterfaceList NetworkInterface::list()
 	}
 	try
 	{
-		if (GetAdaptersInfo(pAdapterInfo, &len) == NO_ERROR) 
+		if (GetAdaptersInfo(pAdapterInfo, &infoLen) == NO_ERROR) 
 		{
-			pAdapter = pAdapterInfo;
-			while (pAdapter) 
+			pInfo = pAdapterInfo;
+			while (pInfo) 
 			{
-				IPAddress addr(std::string(pAdapter->IpAddressList.IpAddress.String));
-				result.push_back(NetworkInterface(std::string(pAdapter->AdapterName), addr));
-				pAdapter = pAdapter->Next;
+				IPAddress address(std::string(pInfo->IpAddressList.IpAddress.String));
+				IPAddress subnetMask(std::string(pInfo->IpAddressList.IpMask.String));
+				IPAddress broadcastAddress(address);
+				broadcastAddress.mask(subnetMask, IPAddress("255.255.255.255"));
+				result.push_back(NetworkInterface(std::string(pInfo->AdapterName), address, subnetMask, broadcastAddress));
+				pInfo = pInfo->Next;
 			}
 		}
 		else throw NetException("cannot get network adapter list");
@@ -260,7 +435,6 @@ NetworkInterface::NetworkInterfaceList NetworkInterface::list()
 		throw;
 	}
 	delete [] reinterpret_cast<char*>(pAdapterInfo);
-#endif
 
 	return result;
 }

+ 3 - 1
Net/src/POP3ClientSession.cpp

@@ -1,7 +1,7 @@
 //
 // POP3ClientSession.cpp
 //
-// $Id: //poco/Main/Net/src/POP3ClientSession.cpp#6 $
+// $Id: //poco/Main/Net/src/POP3ClientSession.cpp#7 $
 //
 // Library: Net
 // Package: Mail
@@ -220,6 +220,7 @@ void POP3ClientSession::retrieveMessage(int id, MailMessage& message)
 	DialogInputStream sis(_socket);
 	MailInputStream mis(sis);
 	message.read(mis);
+	while (mis.good()) mis.get(); // read any remaining junk
 }
 
 
@@ -231,6 +232,7 @@ void POP3ClientSession::retrieveMessage(int id, MailMessage& message, PartHandle
 	DialogInputStream sis(_socket);
 	MailInputStream mis(sis);
 	message.read(mis, handler);
+	while (mis.good()) mis.get(); // read any remaining junk
 }
 
 

+ 2 - 1
Net/src/RemoteSyslogListener.cpp

@@ -1,7 +1,7 @@
 //
 // RemoteSyslogListener.cpp
 //
-// $Id: //poco/Main/Net/src/RemoteSyslogListener.cpp#6 $
+// $Id: //poco/Main/Net/src/RemoteSyslogListener.cpp#7 $
 //
 // Library: Net
 // Package: Logging
@@ -47,6 +47,7 @@
 #include "Poco/LoggingFactory.h"
 #include "Poco/Buffer.h"
 #include <cctype>
+#include <cstddef>
 
 
 namespace Poco {

+ 6 - 4
Net/testsuite/src/NetworkInterfaceTest.cpp

@@ -1,7 +1,7 @@
 //
 // NetworkInterfaceTest.cpp
 //
-// $Id: //poco/Main/Net/testsuite/src/NetworkInterfaceTest.cpp#5 $
+// $Id: //poco/Main/Net/testsuite/src/NetworkInterfaceTest.cpp#6 $
 //
 // Copyright (c) 2005-2006, Applied Informatics Software Engineering GmbH.
 // and Contributors.
@@ -56,9 +56,11 @@ void NetworkInterfaceTest::testList()
 	assert (!list.empty());
 	for (NetworkInterface::NetworkInterfaceList::const_iterator it = list.begin(); it != list.end(); ++it)
 	{
-		std::cout << "Name:    " << it->name() << std::endl;
-		std::cout << "Address: " << it->address().toString() << std::endl;
-		std::cout << "Index:   " << it->index() << std::endl;		
+		std::cout << "Name:      " << it->name() << std::endl;
+		std::cout << "Address:   " << it->address().toString() << std::endl;
+		std::cout << "Subnet:    " << it->subnetMask().toString() << std::endl;
+		std::cout << "Broadcast: " << it->broadcastAddress().toString() << std::endl;
+		std::cout << "Index:     " << it->index() << std::endl;		
 	}
 }