/sparrowhawk/foundation/ESFSocketAddress.cpp
C++ | 224 lines | 163 code | 45 blank | 16 comment | 14 complexity | cb4ef692ec33c1645859d36865b1708c MD5 | raw file
1/** @file ESFSocketAddress.cpp 2 * @brief A transport address object 3 * 4 * Copyright (c) 2009 Yahoo! Inc. 5 * The copyrights embodied in the content of this file are licensed by Yahoo! Inc. 6 * under the BSD (revised) open source license. 7 * 8 * Derived from code that is Copyright (c) 2009 Joshua Blatt and offered under both 9 * BSD and Apache 2.0 licenses (http://sourceforge.net/projects/sparrowhawk/). 10 * 11 * $Author: blattj $ 12 * $Date: 2009/05/25 21:51:08 $ 13 * $Name: $ 14 * $Revision: 1.3 $ 15 */ 16 17#ifndef ESF_SOCKET_ADDRESS_H 18#include <ESFSocketAddress.h> 19#endif 20 21#ifndef ESF_ASSERT_H 22#include <ESFAssert.h> 23#endif 24 25#ifndef ESF_SOCKET_H 26#include <ESFSocket.h> 27#endif 28 29#ifdef HAVE_STRING_H 30#include <string.h> 31#endif 32 33#ifdef HAVE_ARPA_INET_H 34#include <arpa/inet.h> 35#endif 36 37#ifdef HAVE_NETDB_H 38#include <netdb.h> 39#endif 40 41#ifdef HAVE_SYS_PARAM_H 42#include <sys/param.h> 43#endif 44 45#ifdef HAVE_UNISTD_H 46#include <unistd.h> 47#endif 48 49#ifdef HAVE_SYS_SOCKET_H 50#include <sys/socket.h> 51#endif 52 53ESFSocketAddress::ESFSocketAddress() : 54 _magic(0) { 55#ifdef HAVE_MEMSET 56 memset(&_address, 0, sizeof(Address)); 57#else 58#error "memset equivalent is required." 59#endif 60 61#ifdef HAVE_STRUCT_SOCKADDR_IN 62 _address.sin_family = AF_INET; 63 _address.sin_port = 0; 64#if defined HAVE_HTONL && defined HAVE_DECL_INADDR_ANY 65 _address.sin_addr.s_addr = htonl(INADDR_ANY); 66#else 67#error "htonl or equivalent is required." 68#endif 69 70#else /* ! HAVE_STRUCT_SOCKADDR_IN */ 71#error "sockaddr_in or equivalent is required" 72#endif 73 74 _transport = NONE; 75} 76 77ESFSocketAddress::ESFSocketAddress(const char *dottedIp, ESFUInt16 port, TransportType transport) : 78 _magic(0) { 79#ifdef HAVE_MEMSET 80 memset(&_address, 0, sizeof(Address)); 81#else 82#error "memset equivalent is required." 83#endif 84 85 _magic = ESF_MAGIC; 86 87#ifdef HAVE_STRUCT_SOCKADDR_IN 88 89 _address.sin_family = AF_INET; 90 91#if defined HAVE_INET_PTON 92 93 if (1 != inet_pton(AF_INET, dottedIp, &_address.sin_addr)) { 94 _magic = 0; 95 } 96 97#elif defined HAVE_INET_ADDR && defined HAVE_DECL_INADDR_NONE 98 99 ESFUInt32 ip = inet_addr( dottedIp ); 100 101 if ( INADDR_NONE == ip ) 102 { 103 _magic = 0; 104 } 105 else 106 { 107 _address.sin_addr.s_addr = ip; 108 } 109 110#else 111#error "inet_pton equivalent is required." 112#endif 113 114#else /* ! HAVE_STRUCT_SOCKADDR_IN */ 115#error "sockaddr_in or equivalent is required" 116#endif 117 118#ifdef HAVE_HTONS 119 _address.sin_port = htons(port); 120#else 121#error "htons equivalent is required." 122#endif 123 124 _transport = transport; 125 126 switch (transport) { 127 case TCP: 128 case UDP: 129 case TLS: 130 break; 131 132 default: 133 _magic = 0; 134 } 135} 136 137ESFSocketAddress::ESFSocketAddress(const ESFSocketAddress &address) { 138#ifdef HAVE_MEMCPY 139 memcpy(&_address, &address._address, sizeof(Address)); 140#else 141#error "memcpy equivalent is required" 142#endif 143 144 _transport = address._transport; 145 _magic = address._magic; 146} 147 148ESFSocketAddress & 149ESFSocketAddress::operator=(const ESFSocketAddress &address) { 150#ifdef HAVE_MEMCPY 151 memcpy(&_address, &address._address, sizeof(Address)); 152#else 153#error "memcpy equivalent is required" 154#endif 155 156 _transport = address._transport; 157 _magic = address._magic; 158 159 return *this; 160} 161 162ESFSocketAddress::Address * 163ESFSocketAddress::getAddress() { 164 return &_address; 165} 166 167void ESFSocketAddress::getIPAddress(char *address, int size) const { 168 if (!address || 16 > size) { 169 return; 170 } 171 172#ifdef HAVE_STRUCT_SOCKADDR_IN 173 174#if defined HAVE_INET_NTOP 175 inet_ntop(AF_INET, &_address.sin_addr, address, size); 176#elif defined HAVE_INET_NTOA && defined HAVE_STRNCPY 177 // Solaris actually uses thread-specific data to make this safe. 178 strncpy( address, inet_ntoa( _address.sin_addr ), size ); 179#else 180#error "inet_ntop and sockaddr_in or equivalent is required" 181#endif 182 183#else /* ! HAVE_STRUCT_SOCKADDR_IN */ 184#error "sockaddr_in or equivalent is required" 185#endif 186} 187 188ESFUInt16 ESFSocketAddress::getPort() const { 189#if defined HAVE_NTOHS && defined HAVE_STRUCT_SOCKADDR_IN 190 return ntohs(_address.sin_port); 191#else 192#error "ntohs and sockaddr_in or equivalent is required" 193#endif 194} 195 196void ESFSocketAddress::setPort(ESFUInt16 port) { 197#if defined HAVE_HTONS && defined HAVE_STRUCT_SOCKADDR_IN 198 _address.sin_port = htons(port); 199#else 200#error "htons and sockaddr_in or equivalent is required" 201#endif 202} 203 204ESFSocketAddress::TransportType ESFSocketAddress::getTransport() const { 205 return _transport; 206} 207 208void ESFSocketAddress::setTransport(TransportType transport) { 209 _transport = transport; 210 211 switch (_transport) { 212 case TCP: 213 case UDP: 214 case TLS: 215 break; 216 217 default: 218 _magic = 0; 219 } 220} 221 222bool ESFSocketAddress::isValid() { 223 return ESF_MAGIC == _magic; 224}