Index: trunk/ab5.0/ablib/src/Classes/System/Net/IPAddress.ab
===================================================================
--- trunk/ab5.0/ablib/src/Classes/System/Net/IPAddress.ab	(revision 639)
+++ trunk/ab5.0/ablib/src/Classes/System/Net/IPAddress.ab	(revision 647)
@@ -3,5 +3,5 @@
 	@brief  IPアドレスを表すクラス
 	@author OverTaker
-	@date   2008/10/05
+	@date   2008/10/18
 */
 
@@ -11,13 +11,22 @@
 
 Class IPAddress
-	Address As *sockaddr
-	Length As Long
+	item As *Byte
+	size As Long
+	family As DWord
 Public
 
 	/*!
+	@brief  アドレスをバイト配列で取得する
+	@return アドレスを表したバイト列
+	@note   このメソッドはライブラリ内のみで使用する目的で作られています。
+	*/
+	Function Address() As *Byte
+		Return item As *Byte
+	End Function
+
+	/*!
 	@brief コンストラクタ
 	*/
 	Sub IPAddress()
-		Address = NULL
 	End Sub
 
@@ -27,9 +36,8 @@
 	*/
 	Sub IPAddress(ip As DWord)
-		Length = SizeOf(sockaddr_in)
-		Dim temp = calloc(Length) As *sockaddr_in
-		temp->sin_addr.s_addr = ip
-		temp->sin_family = AF_INET
-		Address = temp
+		family = AF_INET
+		size = SizeOf(in_addr)
+		item = malloc(size)
+		memcpy(item, VarPtr(ip), size)
 	End Sub
 
@@ -38,6 +46,10 @@
 	*/
 	Sub ~IPAddress()
-		If Address Then free(Address)
+		If item <> NULL Then free(item)
 	End Sub
+
+	Function Operator== (address As IPAddress) As Boolean
+		Return Equals(address)
+	End Function
 
 	/*!
@@ -46,5 +58,5 @@
 	*/
 	Function AddressFamily() As Sockets.AddressFamily
-		Return New Sockets.AddressFamily(Address->sa_family, "AddressFamily")
+		Return New System.Net.Sockets.AddressFamily(family, "AddressFamily")
 	End Function
 
@@ -53,30 +65,7 @@
 	@return スコープ 
 	*/
-	Function ScopeId() As DWord
-		If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
-			Dim sock = Address As *sockaddr_in6
-			Return sock->sin6_scope_id
-		Else
-			Throw New System.Net.Sockets.SocketException("IPAddress.ScopeId: AddressFamily is not IPv6.")
-		End If
-	End Function
-
-	/*!
-	@brief スコープを設定する。
-	@param スコープ 
-	*/
-	Sub ScopeId(id As DWord)
-		If id > &HFFFFFFFF Then 
-			Throw New ArgumentOutOfRangeException("IPAddress.ScopeId", New Int32(id), "id")
-		End If
-
-		If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
-			Dim sock = Address As *sockaddr_in6
-			sock->sin6_scope_id = id
-		Else
-			Throw New System.Net.Sockets.SocketException("IPAddress.ScopeId: AddressFamily is not IPv6.")
-		End If
-	End Sub
-
+/*	Function ScopeId() As DWord
+	End Function
+*/
 	/*!
 	@brief リンクローカルアドレスかどうかを取得する。
@@ -85,7 +74,6 @@
 	*/
 	Function IsIPv6LinkLocal() As Boolean
-		If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
-			Dim sock = Address As *sockaddr_in6
-			Return (sock->sin6_addr.s6_addr[0] = &HFF) And (sock->sin6_addr.s6_addr[1] = &H00)
+		If family = AF_INET6 Then
+			Return (item[0] = &HFF) And (item[1] = &H00)
 		Else
 			Throw New System.Net.Sockets.SocketException("IPAddress.IsIPv6LinkLocal: AddressFamily is not IPv6.")
@@ -99,7 +87,6 @@
 	*/
 	Function IsIPv6Multicast() As Boolean
-		If AddressFamily = System.Net.Sockets.AddressFamily.InterNetworkV6 Then
-			Dim sock = Address As *sockaddr_in6
-			Return (sock->sin6_addr.s6_addr[0] = &HFE) And (sock->sin6_addr.s6_addr[1] = &H80)
+		If family = AF_INET6 Then
+			Return (item[0] = &HFE) And (item[1] = &H80)
 		Else
 			Throw New System.Net.Sockets.SocketException("IPAddress.IsIPv6Multicast: AddressFamily is not IPv6.")
@@ -111,8 +98,15 @@
 	@retval True  等しい
 	@retval Flase 等しくない
-	@note   手抜き実装
-	*/
-	Override Function Equals(ip As Object) As Boolean
-		Return This.ToString() = ip.ToString()
+	*/
+	Function Equals(ip As IPAddress) As Boolean
+		If family = ip.family Then
+			Dim i As Long
+			For i = 0 To ELM(size)
+				If item[i] <> ip.item[i] Then Return False
+			Next
+			Return True
+		Else
+			Return False
+		End If
 	End Function
 
@@ -123,12 +117,26 @@
 	Override Function ToString() As String
 		Dim temp[ELM(64)] As TCHAR
-		If WSAAddressToString(Address As sockaddr, Length, ByVal 0, temp, Len(temp)) Then
-			Throw New System.Net.Sockets.SocketException(WSAGetLastError())
+		Dim ret As Long
+		Select Case family
+			Case AF_INET
+				Dim addr4 As sockaddr_in
+				addr4.sin_family = family As Integer
+				addr4.sin_addr.s_addr = GetDWord(item)
+				ret = WSAAddressToString(addr4 As sockaddr, SizeOf(sockaddr_in), ByVal 0, temp, Len(temp))
+			Case AF_INET6
+				Dim addr6 As sockaddr_in6
+				addr6.sin6_family = family As Word
+				memcpy(addr6.sin6_addr.s6_addr, item, size)
+				ret = WSAAddressToString(addr6 As sockaddr, SizeOf(sockaddr_in6), ByVal 0, temp, Len(temp))
+			Case Else
+				Throw New NotSupportedException("IPAddress.ToString: Unknown Protocol.")
+		End Select
+
+		If ret Then
+			Throw New System.Net.Sockets.SocketException(WSAGetLastError(), "IPAddress.ToString: Failed to WSAAddressToString.")
 		Else
 			Return New String(temp)
 		End If
 	End Function
-
-
 
 
@@ -140,9 +148,9 @@
 	*/
 	Static Function Parse(ip As String) As IPAddress
-		Dim address = New IPAddress
-		If TryParse(ip, address) Then
-			Return address
-		Else
-			Throw New System.Net.Sockets.SocketException(WSAGetLastError())
+		Dim ipAddress = New IPAddress
+		If TryParse(ip, ipAddress) Then
+			Return ipAddress
+		Else
+			Throw New System.Net.Sockets.SocketException(WSAGetLastError(), "IPAddress.Parse: Failed to Parse.")
 		End If
 	End Function
@@ -155,20 +163,22 @@
 	@retval False 失敗
 	*/
-	Static Function TryParse(ip As String, ByRef ipAddress As IPAddress) As Boolean
-		If ipAddress.Address Then free(ipAddress.Address)		
-
+	Static Function TryParse(ip As String, ByRef address As IPAddress) As Boolean
+		address = New IPAddress
 		If ip.Contains(".") Then
-			ipAddress.Address = Detail.CreateAddressFromIPv4String(ip)
-			ipAddress.Length = SizeOf(sockaddr_in)
+			address.family = AF_INET
+			address.item = Detail.CreateAddressFromIPv4String(ip)
+			address.size = SizeOf(in_addr)
 		ElseIf ip.Contains(":") Then
-			ipAddress.Address = Detail.CreateAddressFromIPv6String(ip)
-			ipAddress.Length = SizeOf(sockaddr_in6)
+			address.family = AF_INET6
+			address.item = Detail.CreateAddressFromIPv6String(ip)
+			address.size = SizeOf(in6_addr)
 		Else
 			Return False
 		End If
 
-		If ipAddress.Address Then
+		If address.item <> NULL Then
 			Return True
 		Else
+			address = Nothing
 			Return False
 		End If
@@ -196,5 +206,5 @@
 	*/
 	Static Function Loopback() As IPAddress
-		Return New IPAddress( HostToNetworkOrder(&HFF000000) )
+		Return New IPAddress( HostToNetworkOrder(&H7F000001) )
 	End Function
 
@@ -273,28 +283,32 @@
 
 	/*!
-	@brief IPv4アドレスを表した文字列から、IPアドレスが設定されたsockaddr構造体を作成します
-	@param IPv4アドレスを表した文字列
-	@return sockaddr構造体を示すアドレス
-	*/
-	Function CreateAddressFromIPv4String(ip As String) As *sockaddr
-		Dim address = malloc(SizeOf(sockaddr_in)) As *sockaddr_in
-		If WSAStringToAddress(ToTCStr(ip), AF_INET, ByVal 0, address As sockaddr, SizeOf(sockaddr_in)) Then
+	@brief IPv4アドレスを表した文字列からアドレスを作成する
+	@param IPv4アドレスを表したバイト列
+	@return バイト列
+	*/
+	Function CreateAddressFromIPv4String(ip As String) As *Byte
+		Dim addr4 As sockaddr_in
+		If WSAStringToAddress(ToTCStr(ip), AF_INET, ByVal 0, addr4 As sockaddr, SizeOf(sockaddr_in)) Then
 			Return NULL
 		Else
-			Return address
-		End If
-	End Function
-
-	/*!
-	@brief IPv6アドレスを表した文字列からIPアドレスが設定されたsockaddr構造体を作成します
-	@param IPv6アドレスを表した文字列
-	@return sockaddr構造体を示すアドレス
-	*/
-	Function CreateAddressFromIPv6String(ip As String) As *sockaddr
-		Dim address = malloc(SizeOf(sockaddr_in6)) As *sockaddr_in6
-		If WSAStringToAddress(ToTCStr(ip), AF_INET6, ByVal 0, address As sockaddr, SizeOf(sockaddr_in6)) Then
+			Dim item = malloc(SizeOf(in_addr)) As *Byte
+			memcpy(item, VarPtr(addr4.sin_addr.s_addr), SizeOf(in_addr))
+			Return item
+		End If
+	End Function
+
+	/*!
+	@brief IPv6アドレスを表した文字列からアドレスを作成する
+	@param IPv6アドレスを表したバイト列
+	@return バイト列
+	*/
+	Function CreateAddressFromIPv6String(ip As String) As *Byte
+		Dim addr6 As sockaddr_in6
+		If WSAStringToAddress(ToTCStr(ip), AF_INET6, ByVal 0, addr6 As sockaddr, SizeOf(sockaddr_in6)) Then
 			Return NULL
 		Else
-			Return address
+			Dim item = malloc(SizeOf(in6_addr)) As *Byte
+			memcpy(item, addr6.sin6_addr.s6_addr, SizeOf(in6_addr))
+			Return item
 		End If
 	End Function
