00001 #ifndef TCPIP_ENDPOINT_HPP_
00002 #define TCPIP_ENDPOINT_HPP_
00003
00004 #include<string>
00005
00006 #include<boost/tr1/functional.hpp>
00007 #include<boost/asio.hpp>
00008
00009 #include "detail/address_convenience.hpp"
00010 #include "port_address.hpp"
00011 #include "ip_address.hpp"
00012
00013 namespace ariba {
00014 namespace addressing {
00015
00016 using boost::asio::ip::tcp;
00017 using namespace std;
00018
00019 struct tcp_address_info {
00020 static const uint16_t type_id;
00021 static const std::string type_name;
00022 };
00023
00024 typedef port_address_tpl<tcp_address_info> tcp_port_address;
00025
00031 class tcpip_endpoint : public detail::address_convenience<tcpip_endpoint> {
00032 private:
00033 ip_address ip;
00034 tcp_port_address port_;
00035 static const std::string protocol_name;
00036
00037 public:
00038 typedef tcpip_endpoint self;
00039
00040 public:
00041 tcpip_endpoint() :
00042 ip(), port_() {
00043 }
00044
00045 tcpip_endpoint( const tcpip_endpoint& copy ) {
00046 assign(copy);
00047 }
00048
00049 tcpip_endpoint( uint16_t port ) : ip(address_v6::any()), port_(port) {
00050 }
00051
00052 tcpip_endpoint( const ip_address& ip, const tcp_port_address& port) :
00053 ip(ip), port_(port) {
00054 }
00055
00056 tcpip_endpoint(const std::string& ip, const std::string& port) :
00057 ip(ip), port_(port) {
00058 }
00059
00060 tcpip_endpoint(const std::string& ip, uint16_t port) :
00061 ip(ip), port_(port) {
00062 }
00063
00064 tcpip_endpoint(const std::string& text) {
00065 assign( text );
00066 }
00067
00068 tcpip_endpoint(const char* text) {
00069 assign( std::string(text) );
00070 }
00071
00072 tcpip_endpoint(const uint8_t* bytes, size_t size) {
00073 assign( bytes, size );
00074 }
00075
00076 bool assign( const self& copy ) {
00077 this->ip = copy.ip;
00078 this->port_ = copy.port_;
00079 return false;
00080 }
00081
00082
00083
00085 int compare_to(const self& rhs) const {
00086 if (ip.compare_to(rhs.ip)==0 && port_.compare_to(rhs.port_)==0) return 0;
00087 return 1;
00088 }
00089
00090
00091
00093 bool is_bytes_size_static() const {
00094 return false;
00095 }
00096
00098 size_t to_bytes_size() const {
00099 return ip.to_bytes_size() + port_.to_bytes_size();
00100 }
00101
00103 void to_bytes(uint8_t* bytes) const {
00104 ip.to_bytes(bytes);
00105 port_.to_bytes(bytes+ip.to_bytes_size());
00106 }
00107
00109 bool assign(const uint8_t* bytes, size_t size) {
00110 assert(size==6 || size==18);
00111 if (size==6) {
00112 ip.assign(bytes,4);
00113 port_.assign(bytes+4,2);
00114 } else {
00115 ip.assign(bytes,16);
00116 port_.assign(bytes+16,2);
00117 }
00118 return false;
00119 }
00120
00121
00122
00124 std::string to_string() const {
00125 if (ip.asio().is_v4())
00126 return ip.to_string()+std::string(":")+port_.to_string();
00127 else
00128 return std::string("[")+ip.to_string()+std::string("]:")+port_.to_string();
00129 }
00130
00132 bool assign(const std::string& text) {
00133 std::string ip_str;
00134 std::string port_str;
00135 if (text.at(0)=='[') {
00136 int i = text.find(']',1);
00137 ip_str = text.substr(1,i-1);
00138 port_str = text.substr(i+2, text.size()-i-1);
00139 } else {
00140 int i = text.find(':',1);
00141 ip_str = text.substr(0,i);
00142 port_str = text.substr(i+1, text.size()-i-1);
00143 }
00144 return ip.assign(ip_str) || port_.assign(port_str);
00145 }
00146
00147
00148
00150 const string& type_name() const {
00151 return protocol_name;
00152 }
00153
00155 uint16_t type_id() const {
00156 return 6;
00157 }
00158
00159
00160
00161 ip_address& address() {
00162 return ip;
00163 }
00164
00165 const ip_address& address() const {
00166 return ip;
00167 }
00168
00169 tcp_port_address& port() {
00170 return port_;
00171 }
00172
00173 const tcp_port_address& port() const {
00174 return port_;
00175 }
00176
00177
00178
00180 tcp::endpoint asio() const {
00181 return tcp::endpoint(ip.asio(), port_.asio());
00182 }
00183
00185 void asio( tcp::endpoint& endp ) {
00186 ip.asio(endp.address());
00187 port_.asio(endp.port());
00188 }
00189 };
00190
00191 }}
00192
00193 namespace boost {
00194
00195 template<>
00196 struct hash<ariba::addressing::tcpip_endpoint>:
00197 public std::unary_function<ariba::addressing::tcpip_endpoint, std::size_t> {
00198 std::size_t operator()(const ariba::addressing::tcpip_endpoint& ep) const {
00199 return hash_value(ep.to_string());
00200 }
00201 };
00202
00203 }
00204
00205
00206 #endif