$search
00001 // 00002 // basic_endpoint.hpp 00003 // ~~~~~~~~~~~~~~~~~~ 00004 // 00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com) 00006 // Derived from a public domain implementation written by Daniel Casimiro. 00007 // 00008 // Distributed under the Boost Software License, Version 1.0. (See accompanying 00009 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 00010 // 00011 00012 #ifndef ASIO_LOCAL_BASIC_ENDPOINT_HPP 00013 #define ASIO_LOCAL_BASIC_ENDPOINT_HPP 00014 00015 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 00016 # pragma once 00017 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 00018 00019 #include "asio/detail/push_options.hpp" 00020 00021 #include "asio/detail/push_options.hpp" 00022 #include <boost/throw_exception.hpp> 00023 #include <cstddef> 00024 #include <cstring> 00025 #include <ostream> 00026 #include "asio/detail/pop_options.hpp" 00027 00028 #include "asio/error.hpp" 00029 #include "asio/system_error.hpp" 00030 #include "asio/detail/socket_ops.hpp" 00031 #include "asio/detail/socket_types.hpp" 00032 #include "asio/detail/throw_error.hpp" 00033 00034 #if !defined(ASIO_DISABLE_LOCAL_SOCKETS) 00035 # if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) 00036 # define ASIO_HAS_LOCAL_SOCKETS 1 00037 # endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__) 00038 #endif // !defined(ASIO_DISABLE_LOCAL_SOCKETS) 00039 00040 #if defined(ASIO_HAS_LOCAL_SOCKETS) \ 00041 || defined(GENERATING_DOCUMENTATION) 00042 00043 00044 namespace asio { 00045 namespace local { 00046 00048 00059 template <typename Protocol> 00060 class basic_endpoint 00061 { 00062 public: 00064 typedef Protocol protocol_type; 00065 00068 #if defined(GENERATING_DOCUMENTATION) 00069 typedef implementation_defined data_type; 00070 #else 00071 typedef asio::detail::socket_addr_type data_type; 00072 #endif 00073 00075 basic_endpoint() 00076 { 00077 init("", 0); 00078 } 00079 00081 basic_endpoint(const char* path) 00082 { 00083 using namespace std; // For strlen. 00084 init(path, strlen(path)); 00085 } 00086 00088 basic_endpoint(const std::string& path) 00089 { 00090 init(path.data(), path.length()); 00091 } 00092 00094 basic_endpoint(const basic_endpoint& other) 00095 : data_(other.data_), 00096 path_length_(other.path_length_) 00097 { 00098 } 00099 00101 basic_endpoint& operator=(const basic_endpoint& other) 00102 { 00103 data_ = other.data_; 00104 path_length_ = other.path_length_; 00105 return *this; 00106 } 00107 00109 protocol_type protocol() const 00110 { 00111 return protocol_type(); 00112 } 00113 00115 data_type* data() 00116 { 00117 return &data_.base; 00118 } 00119 00121 const data_type* data() const 00122 { 00123 return &data_.base; 00124 } 00125 00127 std::size_t size() const 00128 { 00129 return path_length_ 00130 + offsetof(asio::detail::sockaddr_un_type, sun_path); 00131 } 00132 00134 void resize(std::size_t size) 00135 { 00136 if (size > sizeof(asio::detail::sockaddr_un_type)) 00137 { 00138 asio::system_error e(asio::error::invalid_argument); 00139 boost::throw_exception(e); 00140 } 00141 else if (size == 0) 00142 { 00143 path_length_ = 0; 00144 } 00145 else 00146 { 00147 path_length_ = size 00148 - offsetof(asio::detail::sockaddr_un_type, sun_path); 00149 00150 // The path returned by the operating system may be NUL-terminated. 00151 if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0) 00152 --path_length_; 00153 } 00154 } 00155 00157 std::size_t capacity() const 00158 { 00159 return sizeof(asio::detail::sockaddr_un_type); 00160 } 00161 00163 std::string path() const 00164 { 00165 return std::string(data_.local.sun_path, path_length_); 00166 } 00167 00169 void path(const char* p) 00170 { 00171 using namespace std; // For strlen. 00172 init(p, strlen(p)); 00173 } 00174 00176 void path(const std::string& p) 00177 { 00178 init(p.data(), p.length()); 00179 } 00180 00182 friend bool operator==(const basic_endpoint<Protocol>& e1, 00183 const basic_endpoint<Protocol>& e2) 00184 { 00185 return e1.path() == e2.path(); 00186 } 00187 00189 friend bool operator!=(const basic_endpoint<Protocol>& e1, 00190 const basic_endpoint<Protocol>& e2) 00191 { 00192 return e1.path() != e2.path(); 00193 } 00194 00196 friend bool operator<(const basic_endpoint<Protocol>& e1, 00197 const basic_endpoint<Protocol>& e2) 00198 { 00199 return e1.path() < e2.path(); 00200 } 00201 00202 private: 00203 // The underlying UNIX socket address. 00204 union data_union 00205 { 00206 asio::detail::socket_addr_type base; 00207 asio::detail::sockaddr_un_type local; 00208 } data_; 00209 00210 // The length of the path associated with the endpoint. 00211 std::size_t path_length_; 00212 00213 // Initialise with a specified path. 00214 void init(const char* path, std::size_t path_length) 00215 { 00216 if (path_length > sizeof(data_.local.sun_path) - 1) 00217 { 00218 // The buffer is not large enough to store this address. 00219 asio::error_code ec(asio::error::name_too_long); 00220 asio::detail::throw_error(ec); 00221 } 00222 00223 using namespace std; // For memcpy. 00224 data_.local = asio::detail::sockaddr_un_type(); 00225 data_.local.sun_family = AF_UNIX; 00226 memcpy(data_.local.sun_path, path, path_length); 00227 path_length_ = path_length; 00228 00229 // NUL-terminate normal path names. Names that start with a NUL are in the 00230 // UNIX domain protocol's "abstract namespace" and are not NUL-terminated. 00231 if (path_length > 0 && data_.local.sun_path[0] == 0) 00232 data_.local.sun_path[path_length] = 0; 00233 } 00234 }; 00235 00237 00248 template <typename Elem, typename Traits, typename Protocol> 00249 std::basic_ostream<Elem, Traits>& operator<<( 00250 std::basic_ostream<Elem, Traits>& os, 00251 const basic_endpoint<Protocol>& endpoint) 00252 { 00253 os << endpoint.path(); 00254 return os; 00255 } 00256 00257 } // namespace local 00258 } // namespace asio 00259 00260 #endif // defined(ASIO_HAS_LOCAL_SOCKETS) 00261 // || defined(GENERATING_DOCUMENTATION) 00262 00263 #include "asio/detail/pop_options.hpp" 00264 00265 #endif // ASIO_LOCAL_BASIC_ENDPOINT_HPP