PageRenderTime 25ms CodeModel.GetById 11ms app.highlight 11ms RepoModel.GetById 1ms app.codeStats 0ms

/sparrowhawk/foundation/ESFSocketAddress.cpp

http://github.com/jtblatt/duderino
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}