
/*!
	@brief  インターネットワーク端末のアドレスを表します。
	@author OverTaker
	@date   2008/10/18
*/



Namespace System
Namespace Net


Class IPEndPoint
	Inherits EndPoint
Public

	/*!
	@brief  コンストラクタ
	*/
	Sub IPEndPoint()
	End Sub

	/*!
	@brief  コンストラクタ
	@param  IPアドレスを表した32ビット値(ネットワークバイトオーダー)
	@param  ポート番号(ホストバイトオーダー)
	*/
	Sub IPEndPoint(ip As DWord, port As Word)
		init( New IPAddress(ip), port )
	End Sub

	/*!
	@brief  コンストラクタ
	@param  IPAddressクラス
	@param  ポート番号(ホストバイトオーダー)
	*/
	Sub IPEndPoint(ip As IPAddress, port As Word)
		init(ip, port)
	End Sub

	/*!
	@brief 等しいかどうかを取得する
	@retval True  等しい
	@retval Flase 等しくない
	*/
	Function Equals(endPoint As IPEndPoint) As Boolean
		Return socketAddress.Equals(endPoint.socketAddress)
	End Function

	/*!
	@brief  IPEndPointを文字列で表す
	@return アドレスとポート番号が文字列で表されます
	*/
	Override Function ToString() As String
		Dim temp[64] As TCHAR
		If WSAAddressToString(socketAddress.Items As sockaddr, socketAddress.Size, ByVal 0, temp, Len(temp)) Then
			Throw New System.Net.Sockets.SocketException(WSAGetLastError(), "IPEndPoint.ToString: Failed to WSAAddressToString.")
		Else
			Return New String(temp)
		End If
	End Function

	/*!
	@brief  IPEndPointが表すIPアドレスを取得する
	@return IPAddressクラス
	*/
	Function Address() As IPAddress
		Return New IPAddress(socketAddress.Items)
	End Function

	/*!
	@brief  ポート番号を設定する
	@param  ポート番号(ホストバイトオーダー)
	*/
	Sub Port(port As Word)
		Select Case AddressFamily
			Case System.Net.Sockets.AddressFamily.InterNetwork
				Dim addr4 = socketAddress.Items As *sockaddr_in
				addr4->sin_port = htons(port)
			Case System.Net.Sockets.AddressFamily.InterNetworkV6
				Dim addr6 = socketAddress.Items As *sockaddr_in6
				addr6->sin6_port = htons(port)
			Case Else
				Throw New NotSupportedException("IPEndPoint.Port: Unknown AddressFamily.")
		End Select
	End Sub

	/*!
	@brief  ポート番号を取得する
	@return ポート番号(ホストバイトオーダー)
	*/
	Function Port() As Word
		Select Case AddressFamily
			Case System.Net.Sockets.AddressFamily.InterNetwork
				Dim addr4 = socketAddress.Items As *sockaddr_in
				Return ntohs(addr4->sin_port)
			Case System.Net.Sockets.AddressFamily.InterNetworkV6
				Dim addr6 = socketAddress.Items As *sockaddr_in6
				Return ntohs(addr6->sin6_port)
			Case Else
				Throw New NotSupportedException("IPEndPoint.Port: Unknown AddressFamily.")
		End Select
	End Function

	/*!
	@brief  SocketAddressクラスから作成する
	@param  SocketAddressクラス
	@return SocketAddressを元に作成したIPEndPoint
	*/
	Static Function Create(address As SocketAddress) As IPEndPoint
		Dim point = New IPEndPoint
		point.socketAddress = address
		Return point
	End Function

	/*!
	@brief  最大のポート番号を取得する
	@return ポート番号(ホストバイトオーダー)
	*/
	Static Function MaxPort() As Word
		Return &HFFFF
	End Function

	/*!
	@brief  最小のポート番号を取得する
	@return ポート番号(ホストバイトオーダー)
	*/
	Static Function MinPort() As Word
		Return 0
	End Function

Private

	/*!
	@brief  IPAddressクラスとポート番号から初期化する
	@param  IPAddressクラス
	@param  ポート番号(ホストバイトオーダー)
	*/
	Sub init(ip As IPAddress, port As Word)
		socketAddress = New SocketAddress(ip.AddressFamily)
		Select Case ip.AddressFamily
			Case System.Net.Sockets.AddressFamily.InterNetwork
				Dim addr4 = socketAddress.Items As *sockaddr_in
				memcpy(VarPtr(addr4->sin_addr.s_addr), ip.Address, SizeOf(in_addr))
			Case System.Net.Sockets.AddressFamily.InterNetworkV6
				Dim addr6 = socketAddress.Items As *sockaddr_in6
				memcpy(VarPtr(addr6->sin6_addr.s6_addr), ip.Address, SizeOf(in6_addr))
			Case Else
				Throw New NotSupportedException("IPEndPoint.init: Not Supported AddressFamily.")
		End Select
		Port = port
	End Sub
End Class

End Namespace
End Namespace