00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CNetworkAddress.h"
00016 #include "XSocket.h"
00017 #include "CArch.h"
00018 #include "XArch.h"
00019 #include <cstdlib>
00020
00021
00022
00023
00024
00025
00026
00027 CNetworkAddress::CNetworkAddress() :
00028 m_address(NULL),
00029 m_hostname(),
00030 m_port(0)
00031 {
00032
00033
00034 }
00035
00036 CNetworkAddress::CNetworkAddress(int port) :
00037 m_address(NULL),
00038 m_hostname(),
00039 m_port(port)
00040 {
00041 checkPort();
00042 m_address = ARCH->newAnyAddr(IArchNetwork::kINET);
00043 ARCH->setAddrPort(m_address, m_port);
00044 }
00045
00046 CNetworkAddress::CNetworkAddress(const CNetworkAddress& addr) :
00047 m_address(addr.m_address != NULL ? ARCH->copyAddr(addr.m_address) : NULL),
00048 m_hostname(addr.m_hostname),
00049 m_port(addr.m_port)
00050 {
00051
00052 }
00053
00054 CNetworkAddress::CNetworkAddress(const CString& hostname, int port) :
00055 m_address(NULL),
00056 m_hostname(hostname),
00057 m_port(port)
00058 {
00059
00060 CString::size_type i = m_hostname.rfind(':');
00061 if (i != CString::npos && i + 1 < m_hostname.size()) {
00062
00063 bool colonNotation = false;
00064 bool dotNotation = false;
00065 bool doubleColon = false;
00066 for (CString::size_type j = 0; j < i; ++j) {
00067 if (m_hostname[j] == ':') {
00068 colonNotation = true;
00069 dotNotation = false;
00070 if (m_hostname[j + 1] == ':') {
00071 doubleColon = true;
00072 }
00073 }
00074 else if (m_hostname[j] == '.' && colonNotation) {
00075 dotNotation = true;
00076 }
00077 }
00078
00079
00080
00081
00082
00083
00084 if ((!doubleColon || dotNotation) || !colonNotation) {
00085
00086 char* end;
00087 const char* chostname = m_hostname.c_str();
00088 long suffixPort = strtol(chostname + i + 1, &end, 10);
00089 if (end == chostname + i + 1 || *end != '\0') {
00090 throw XSocketAddress(XSocketAddress::kBadPort,
00091 m_hostname, m_port);
00092 }
00093
00094
00095 m_hostname.erase(i);
00096
00097
00098 m_port = static_cast<int>(suffixPort);
00099 }
00100 }
00101
00102
00103 checkPort();
00104 }
00105
00106 CNetworkAddress::~CNetworkAddress()
00107 {
00108 if (m_address != NULL) {
00109 ARCH->closeAddr(m_address);
00110 }
00111 }
00112
00113 CNetworkAddress&
00114 CNetworkAddress::operator=(const CNetworkAddress& addr)
00115 {
00116 CArchNetAddress newAddr = NULL;
00117 if (addr.m_address != NULL) {
00118 newAddr = ARCH->copyAddr(addr.m_address);
00119 }
00120 if (m_address != NULL) {
00121 ARCH->closeAddr(m_address);
00122 }
00123 m_address = newAddr;
00124 m_hostname = addr.m_hostname;
00125 m_port = addr.m_port;
00126 return *this;
00127 }
00128
00129 void
00130 CNetworkAddress::resolve()
00131 {
00132
00133 if (m_address != NULL) {
00134 ARCH->closeAddr(m_address);
00135 m_address = NULL;
00136 }
00137
00138 try {
00139
00140
00141 if (m_hostname.empty()) {
00142 m_address = ARCH->newAnyAddr(IArchNetwork::kINET);
00143 }
00144 else {
00145 m_address = ARCH->nameToAddr(m_hostname);
00146 }
00147 }
00148 catch (XArchNetworkNameUnknown&) {
00149 throw XSocketAddress(XSocketAddress::kNotFound, m_hostname, m_port);
00150 }
00151 catch (XArchNetworkNameNoAddress&) {
00152 throw XSocketAddress(XSocketAddress::kNoAddress, m_hostname, m_port);
00153 }
00154 catch (XArchNetworkNameUnsupported&) {
00155 throw XSocketAddress(XSocketAddress::kUnsupported, m_hostname, m_port);
00156 }
00157 catch (XArchNetworkName&) {
00158 throw XSocketAddress(XSocketAddress::kUnknown, m_hostname, m_port);
00159 }
00160
00161
00162 ARCH->setAddrPort(m_address, m_port);
00163 }
00164
00165 bool
00166 CNetworkAddress::operator==(const CNetworkAddress& addr) const
00167 {
00168 return ARCH->isEqualAddr(m_address, addr.m_address);
00169 }
00170
00171 bool
00172 CNetworkAddress::operator!=(const CNetworkAddress& addr) const
00173 {
00174 return !operator==(addr);
00175 }
00176
00177 bool
00178 CNetworkAddress::isValid() const
00179 {
00180 return (m_address != NULL);
00181 }
00182
00183 const CArchNetAddress&
00184 CNetworkAddress::getAddress() const
00185 {
00186 return m_address;
00187 }
00188
00189 int
00190 CNetworkAddress::getPort() const
00191 {
00192 return m_port;
00193 }
00194
00195 CString
00196 CNetworkAddress::getHostname() const
00197 {
00198 return m_hostname;
00199 }
00200
00201 void
00202 CNetworkAddress::checkPort()
00203 {
00204
00205 if (m_port <= 0 || m_port > 65535) {
00206 throw XSocketAddress(XSocketAddress::kBadPort, m_hostname, m_port);
00207 }
00208 }