$search
00001 // 00002 // address_v4.hpp 00003 // ~~~~~~~~~~~~~~ 00004 // 00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) 00006 // 00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00009 // 00010 00011 #ifndef ASIO_IP_ADDRESS_V4_HPP 00012 #define ASIO_IP_ADDRESS_V4_HPP 00013 00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 00015 # pragma once 00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 00017 00018 #include "asio/detail/push_options.hpp" 00019 00020 #include "asio/detail/push_options.hpp" 00021 #include <string> 00022 #include <boost/array.hpp> 00023 #include <boost/throw_exception.hpp> 00024 #include "asio/detail/pop_options.hpp" 00025 00026 #include "asio/error.hpp" 00027 #include "asio/detail/socket_ops.hpp" 00028 #include "asio/detail/socket_types.hpp" 00029 #include "asio/detail/throw_error.hpp" 00030 00031 namespace asio { 00032 namespace ip { 00033 00035 00043 class address_v4 00044 { 00045 public: 00047 typedef boost::array<unsigned char, 4> bytes_type; 00048 00050 address_v4() 00051 { 00052 addr_.s_addr = 0; 00053 } 00054 00056 explicit address_v4(const bytes_type& bytes) 00057 { 00058 using namespace std; // For memcpy. 00059 memcpy(&addr_.s_addr, bytes.elems, 4); 00060 } 00061 00063 explicit address_v4(unsigned long addr) 00064 { 00065 addr_.s_addr = asio::detail::socket_ops::host_to_network_long(addr); 00066 } 00067 00069 address_v4(const address_v4& other) 00070 : addr_(other.addr_) 00071 { 00072 } 00073 00075 address_v4& operator=(const address_v4& other) 00076 { 00077 addr_ = other.addr_; 00078 return *this; 00079 } 00080 00082 bytes_type to_bytes() const 00083 { 00084 using namespace std; // For memcpy. 00085 bytes_type bytes; 00086 memcpy(bytes.elems, &addr_.s_addr, 4); 00087 return bytes; 00088 } 00089 00091 unsigned long to_ulong() const 00092 { 00093 return asio::detail::socket_ops::network_to_host_long(addr_.s_addr); 00094 } 00095 00097 std::string to_string() const 00098 { 00099 asio::error_code ec; 00100 std::string addr = to_string(ec); 00101 asio::detail::throw_error(ec); 00102 return addr; 00103 } 00104 00106 std::string to_string(asio::error_code& ec) const 00107 { 00108 char addr_str[asio::detail::max_addr_v4_str_len]; 00109 const char* addr = 00110 asio::detail::socket_ops::inet_ntop(AF_INET, &addr_, addr_str, 00111 asio::detail::max_addr_v4_str_len, 0, ec); 00112 if (addr == 0) 00113 return std::string(); 00114 return addr; 00115 } 00116 00118 static address_v4 from_string(const char* str) 00119 { 00120 asio::error_code ec; 00121 address_v4 addr = from_string(str, ec); 00122 asio::detail::throw_error(ec); 00123 return addr; 00124 } 00125 00127 static address_v4 from_string(const char* str, asio::error_code& ec) 00128 { 00129 address_v4 tmp; 00130 if (asio::detail::socket_ops::inet_pton( 00131 AF_INET, str, &tmp.addr_, 0, ec) <= 0) 00132 return address_v4(); 00133 return tmp; 00134 } 00135 00137 static address_v4 from_string(const std::string& str) 00138 { 00139 return from_string(str.c_str()); 00140 } 00141 00143 static address_v4 from_string(const std::string& str, 00144 asio::error_code& ec) 00145 { 00146 return from_string(str.c_str(), ec); 00147 } 00148 00150 bool is_class_a() const 00151 { 00152 return IN_CLASSA(to_ulong()); 00153 } 00154 00156 bool is_class_b() const 00157 { 00158 return IN_CLASSB(to_ulong()); 00159 } 00160 00162 bool is_class_c() const 00163 { 00164 return IN_CLASSC(to_ulong()); 00165 } 00166 00168 bool is_multicast() const 00169 { 00170 return IN_MULTICAST(to_ulong()); 00171 } 00172 00174 friend bool operator==(const address_v4& a1, const address_v4& a2) 00175 { 00176 return a1.addr_.s_addr == a2.addr_.s_addr; 00177 } 00178 00180 friend bool operator!=(const address_v4& a1, const address_v4& a2) 00181 { 00182 return a1.addr_.s_addr != a2.addr_.s_addr; 00183 } 00184 00186 friend bool operator<(const address_v4& a1, const address_v4& a2) 00187 { 00188 return a1.to_ulong() < a2.to_ulong(); 00189 } 00190 00192 friend bool operator>(const address_v4& a1, const address_v4& a2) 00193 { 00194 return a1.to_ulong() > a2.to_ulong(); 00195 } 00196 00198 friend bool operator<=(const address_v4& a1, const address_v4& a2) 00199 { 00200 return a1.to_ulong() <= a2.to_ulong(); 00201 } 00202 00204 friend bool operator>=(const address_v4& a1, const address_v4& a2) 00205 { 00206 return a1.to_ulong() >= a2.to_ulong(); 00207 } 00208 00210 static address_v4 any() 00211 { 00212 return address_v4(static_cast<unsigned long>(INADDR_ANY)); 00213 } 00214 00216 static address_v4 loopback() 00217 { 00218 return address_v4(static_cast<unsigned long>(INADDR_LOOPBACK)); 00219 } 00220 00222 static address_v4 broadcast() 00223 { 00224 return address_v4(static_cast<unsigned long>(INADDR_BROADCAST)); 00225 } 00226 00229 static address_v4 broadcast(const address_v4& addr, const address_v4& mask) 00230 { 00231 return address_v4(addr.to_ulong() | ~mask.to_ulong()); 00232 } 00233 00236 static address_v4 netmask(const address_v4& addr) 00237 { 00238 if (addr.is_class_a()) 00239 return address_v4(0xFF000000); 00240 if (addr.is_class_b()) 00241 return address_v4(0xFFFF0000); 00242 if (addr.is_class_c()) 00243 return address_v4(0xFFFFFF00); 00244 return address_v4(0xFFFFFFFF); 00245 } 00246 00247 private: 00248 // The underlying IPv4 address. 00249 asio::detail::in4_addr_type addr_; 00250 }; 00251 00253 00264 template <typename Elem, typename Traits> 00265 std::basic_ostream<Elem, Traits>& operator<<( 00266 std::basic_ostream<Elem, Traits>& os, const address_v4& addr) 00267 { 00268 asio::error_code ec; 00269 std::string s = addr.to_string(ec); 00270 if (ec) 00271 { 00272 if (os.exceptions() & std::ios::failbit) 00273 asio::detail::throw_error(ec); 00274 else 00275 os.setstate(std::ios_base::failbit); 00276 } 00277 else 00278 for (std::string::iterator i = s.begin(); i != s.end(); ++i) 00279 os << os.widen(*i); 00280 return os; 00281 } 00282 00283 } // namespace ip 00284 } // namespace asio 00285 00286 #include "asio/detail/pop_options.hpp" 00287 00288 #endif // ASIO_IP_ADDRESS_V4_HPP