/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. #ifndef ESF_SOCKET_ADDRESS_H
  17. #include <ESFSocketAddress.h>
  18. #endif
  19. #ifndef ESF_ASSERT_H
  20. #include <ESFAssert.h>
  21. #endif
  22. #ifndef ESF_SOCKET_H
  23. #include <ESFSocket.h>
  24. #endif
  25. #ifdef HAVE_STRING_H
  26. #include <string.h>
  27. #endif
  28. #ifdef HAVE_ARPA_INET_H
  29. #include <arpa/inet.h>
  30. #endif
  31. #ifdef HAVE_NETDB_H
  32. #include <netdb.h>
  33. #endif
  34. #ifdef HAVE_SYS_PARAM_H
  35. #include <sys/param.h>
  36. #endif
  37. #ifdef HAVE_UNISTD_H
  38. #include <unistd.h>
  39. #endif
  40. #ifdef HAVE_SYS_SOCKET_H
  41. #include <sys/socket.h>
  42. #endif
  43. ESFSocketAddress::ESFSocketAddress() :
  44. _magic(0) {
  45. #ifdef HAVE_MEMSET
  46. memset(&_address, 0, sizeof(Address));
  47. #else
  48. #error "memset equivalent is required."
  49. #endif
  50. #ifdef HAVE_STRUCT_SOCKADDR_IN
  51. _address.sin_family = AF_INET;
  52. _address.sin_port = 0;
  53. #if defined HAVE_HTONL && defined HAVE_DECL_INADDR_ANY
  54. _address.sin_addr.s_addr = htonl(INADDR_ANY);
  55. #else
  56. #error "htonl or equivalent is required."
  57. #endif
  58. #else /* ! HAVE_STRUCT_SOCKADDR_IN */
  59. #error "sockaddr_in or equivalent is required"
  60. #endif
  61. _transport = NONE;
  62. }
  63. ESFSocketAddress::ESFSocketAddress(const char *dottedIp, ESFUInt16 port, TransportType transport) :
  64. _magic(0) {
  65. #ifdef HAVE_MEMSET
  66. memset(&_address, 0, sizeof(Address));
  67. #else
  68. #error "memset equivalent is required."
  69. #endif
  70. _magic = ESF_MAGIC;
  71. #ifdef HAVE_STRUCT_SOCKADDR_IN
  72. _address.sin_family = AF_INET;
  73. #if defined HAVE_INET_PTON
  74. if (1 != inet_pton(AF_INET, dottedIp, &_address.sin_addr)) {
  75. _magic = 0;
  76. }
  77. #elif defined HAVE_INET_ADDR && defined HAVE_DECL_INADDR_NONE
  78. ESFUInt32 ip = inet_addr( dottedIp );
  79. if ( INADDR_NONE == ip )
  80. {
  81. _magic = 0;
  82. }
  83. else
  84. {
  85. _address.sin_addr.s_addr = ip;
  86. }
  87. #else
  88. #error "inet_pton equivalent is required."
  89. #endif
  90. #else /* ! HAVE_STRUCT_SOCKADDR_IN */
  91. #error "sockaddr_in or equivalent is required"
  92. #endif
  93. #ifdef HAVE_HTONS
  94. _address.sin_port = htons(port);
  95. #else
  96. #error "htons equivalent is required."
  97. #endif
  98. _transport = transport;
  99. switch (transport) {
  100. case TCP:
  101. case UDP:
  102. case TLS:
  103. break;
  104. default:
  105. _magic = 0;
  106. }
  107. }
  108. ESFSocketAddress::ESFSocketAddress(const ESFSocketAddress &address) {
  109. #ifdef HAVE_MEMCPY
  110. memcpy(&_address, &address._address, sizeof(Address));
  111. #else
  112. #error "memcpy equivalent is required"
  113. #endif
  114. _transport = address._transport;
  115. _magic = address._magic;
  116. }
  117. ESFSocketAddress &
  118. ESFSocketAddress::operator=(const ESFSocketAddress &address) {
  119. #ifdef HAVE_MEMCPY
  120. memcpy(&_address, &address._address, sizeof(Address));
  121. #else
  122. #error "memcpy equivalent is required"
  123. #endif
  124. _transport = address._transport;
  125. _magic = address._magic;
  126. return *this;
  127. }
  128. ESFSocketAddress::Address *
  129. ESFSocketAddress::getAddress() {
  130. return &_address;
  131. }
  132. void ESFSocketAddress::getIPAddress(char *address, int size) const {
  133. if (!address || 16 > size) {
  134. return;
  135. }
  136. #ifdef HAVE_STRUCT_SOCKADDR_IN
  137. #if defined HAVE_INET_NTOP
  138. inet_ntop(AF_INET, &_address.sin_addr, address, size);
  139. #elif defined HAVE_INET_NTOA && defined HAVE_STRNCPY
  140. // Solaris actually uses thread-specific data to make this safe.
  141. strncpy( address, inet_ntoa( _address.sin_addr ), size );
  142. #else
  143. #error "inet_ntop and sockaddr_in or equivalent is required"
  144. #endif
  145. #else /* ! HAVE_STRUCT_SOCKADDR_IN */
  146. #error "sockaddr_in or equivalent is required"
  147. #endif
  148. }
  149. ESFUInt16 ESFSocketAddress::getPort() const {
  150. #if defined HAVE_NTOHS && defined HAVE_STRUCT_SOCKADDR_IN
  151. return ntohs(_address.sin_port);
  152. #else
  153. #error "ntohs and sockaddr_in or equivalent is required"
  154. #endif
  155. }
  156. void ESFSocketAddress::setPort(ESFUInt16 port) {
  157. #if defined HAVE_HTONS && defined HAVE_STRUCT_SOCKADDR_IN
  158. _address.sin_port = htons(port);
  159. #else
  160. #error "htons and sockaddr_in or equivalent is required"
  161. #endif
  162. }
  163. ESFSocketAddress::TransportType ESFSocketAddress::getTransport() const {
  164. return _transport;
  165. }
  166. void ESFSocketAddress::setTransport(TransportType transport) {
  167. _transport = transport;
  168. switch (_transport) {
  169. case TCP:
  170. case UDP:
  171. case TLS:
  172. break;
  173. default:
  174. _magic = 0;
  175. }
  176. }
  177. bool ESFSocketAddress::isValid() {
  178. return ESF_MAGIC == _magic;
  179. }