Home | History | Annotate | Download | only in impl
      1 //
      2 // local/detail/impl/endpoint.hpp
      3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      4 //
      5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
      6 // Derived from a public domain implementation written by Daniel Casimiro.
      7 //
      8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
      9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
     10 //
     11 
     12 #ifndef ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
     13 #define ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
     14 
     15 
     16 #include "asio/detail/config.hpp"
     17 
     18 
     19 #include <cstring>
     20 #include "asio/detail/socket_ops.hpp"
     21 #include "asio/detail/throw_error.hpp"
     22 #include "asio/error.hpp"
     23 #include "asio/local/detail/endpoint.hpp"
     24 
     25 #include "asio/detail/push_options.hpp"
     26 
     27 namespace asio {
     28 namespace local {
     29 namespace detail {
     30 
     31 endpoint::endpoint()
     32 {
     33   init("", 0);
     34 }
     35 
     36 endpoint::endpoint(const char* path_name)
     37 {
     38   using namespace std; // For strlen.
     39   init(path_name, strlen(path_name));
     40 }
     41 
     42 endpoint::endpoint(const std::string& path_name)
     43 {
     44   init(path_name.data(), path_name.length());
     45 }
     46 
     47 void endpoint::resize(std::size_t new_size)
     48 {
     49   if (new_size > sizeof(asio::detail::sockaddr_un_type))
     50   {
     51     asio::error_code ec(asio::error::invalid_argument);
     52     asio::detail::throw_error(ec);
     53   }
     54   else if (new_size == 0)
     55   {
     56     path_length_ = 0;
     57   }
     58   else
     59   {
     60     path_length_ = new_size
     61       - offsetof(asio::detail::sockaddr_un_type, sun_path);
     62 
     63     // The path returned by the operating system may be NUL-terminated.
     64     if (path_length_ > 0 && data_.local.sun_path[path_length_ - 1] == 0)
     65       --path_length_;
     66   }
     67 }
     68 
     69 std::string endpoint::path() const
     70 {
     71   return std::string(data_.local.sun_path, path_length_);
     72 }
     73 
     74 void endpoint::path(const char* p)
     75 {
     76   using namespace std; // For strlen.
     77   init(p, strlen(p));
     78 }
     79 
     80 void endpoint::path(const std::string& p)
     81 {
     82   init(p.data(), p.length());
     83 }
     84 
     85 bool operator==(const endpoint& e1, const endpoint& e2)
     86 {
     87   return e1.path() == e2.path();
     88 }
     89 
     90 bool operator<(const endpoint& e1, const endpoint& e2)
     91 {
     92   return e1.path() < e2.path();
     93 }
     94 
     95 void endpoint::init(const char* path_name, std::size_t path_length)
     96 {
     97   if (path_length > sizeof(data_.local.sun_path) - 1)
     98   {
     99     // The buffer is not large enough to store this address.
    100     asio::error_code ec(asio::error::name_too_long);
    101     asio::detail::throw_error(ec);
    102   }
    103 
    104   using namespace std; // For memcpy.
    105   data_.local = asio::detail::sockaddr_un_type();
    106   data_.local.sun_family = AF_UNIX;
    107   memcpy(data_.local.sun_path, path_name, path_length);
    108   path_length_ = path_length;
    109 
    110   // NUL-terminate normal path names. Names that start with a NUL are in the
    111   // UNIX domain protocol's "abstract namespace" and are not NUL-terminated.
    112   if (path_length > 0 && data_.local.sun_path[0] == 0)
    113     data_.local.sun_path[path_length] = 0;
    114 }
    115 
    116 } // namespace detail
    117 } // namespace local
    118 } // namespace asio
    119 
    120 #include "asio/detail/pop_options.hpp"
    121 
    122 
    123 #endif // ASIO_LOCAL_DETAIL_IMPL_ENDPOINT_IPP
    124