LCOV - code coverage report
Current view: top level - corosio - local_endpoint.hpp (source / functions) Coverage Total Hit
Test: coverage_remapped.info Lines: 100.0 % 14 14
Test Date: 2026-10-28 12:45:41 Functions: 100.0 % 6 6

           TLA  Line data    Source code
       1                 : //
       2                 : // Copyright (c) 2026 Michael Vandeberg
       3                 : //
       4                 : // Distributed under the Boost Software License, Version 1.0. (See accompanying
       5                 : // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6                 : //
       7                 : // Official repository: https://github.com/cppalliance/corosio
       8                 : //
       9                 : 
      10                 : #ifndef BOOST_COROSIO_LOCAL_ENDPOINT_HPP
      11                 : #define BOOST_COROSIO_LOCAL_ENDPOINT_HPP
      12                 : 
      13                 : #include <boost/corosio/detail/config.hpp>
      14                 : 
      15                 : #include <boost/capy/results.hpp>
      16                 : 
      17                 : #include <algorithm>
      18                 : #include <compare>
      19                 : #include <cstddef>
      20                 : #include <cstdint>
      21                 : #include <cstring>
      22                 : #include <iosfwd>
      23                 : #include <string_view>
      24                 : #include <system_error>
      25                 : 
      26                 : namespace boost::corosio {
      27                 : 
      28                 : /** Holds the filesystem path that names a Unix domain socket.
      29                 : 
      30                 :     Stores the path in a fixed-size buffer, avoiding heap
      31                 :     allocation. The object is trivially copyable.
      32                 : 
      33                 :     Abstract sockets (Linux-only) are represented by paths whose
      34                 :     first character is '\0'. The full path including the leading
      35                 :     null byte is stored.
      36                 : 
      37                 :     The library does NOT automatically unlink the socket path on
      38                 :     close. Callers are responsible for cleanup.
      39                 : 
      40                 :     @par Thread Safety
      41                 :     Distinct objects: Safe.@n
      42                 :     Shared objects: Safe.
      43                 : 
      44                 :     @see @ref boost::corosio::make_local_endpoint
      45                 : */
      46                 : class BOOST_COROSIO_DECL local_endpoint
      47                 : {
      48                 :     struct from_path_t
      49                 :     {};
      50                 : 
      51                 :     // Callers have already checked the length against max_path_length.
      52                 :     local_endpoint(from_path_t, std::string_view path) noexcept;
      53                 : 
      54                 :     friend BOOST_COROSIO_DECL capy::results<local_endpoint>
      55                 :     make_local_endpoint(std::string_view path) noexcept;
      56                 : 
      57                 :     // sun_path is 108 on Linux, 104 on macOS/FreeBSD. Use the
      58                 :     // minimum so local_endpoint is portable across all three.
      59                 :     char path_[104]{};
      60                 :     std::uint8_t len_ = 0;
      61                 : 
      62                 : public:
      63                 :     /// Maximum path length for a Unix domain socket (excluding null terminator).
      64                 :     static constexpr std::size_t max_path_length = 103;
      65                 : 
      66                 :     /// Default constructor. Creates an empty (unbound) endpoint.
      67 HIT        9231 :     local_endpoint() noexcept = default;
      68                 : 
      69                 :     /** Return the socket path.
      70                 : 
      71                 :         For abstract sockets, the returned view includes the
      72                 :         leading null byte.
      73                 : 
      74                 :         @return A view over the stored path bytes.
      75                 :     */
      76             328 :     std::string_view path() const noexcept
      77                 :     {
      78             328 :         return std::string_view(path_, len_);
      79                 :     }
      80                 : 
      81                 :     /** Check if this is an abstract socket (Linux-only).
      82                 : 
      83                 :         Abstract sockets live in a kernel namespace rather than
      84                 :         the filesystem. They are identified by a leading null byte
      85                 :         in the path.
      86                 : 
      87                 :         @return `true` if the path starts with '\\0'.
      88                 :     */
      89             307 :     bool is_abstract() const noexcept
      90                 :     {
      91             307 :         return len_ > 0 && path_[0] == '\0';
      92                 :     }
      93                 : 
      94                 :     /// Return true if the endpoint has no path.
      95              31 :     bool empty() const noexcept
      96                 :     {
      97              31 :         return len_ == 0;
      98                 :     }
      99                 : 
     100                 :     /// Compare endpoints for equality.
     101                 :     friend bool
     102               9 :     operator==(local_endpoint const& a, local_endpoint const& b) noexcept
     103                 :     {
     104               9 :         return a.len_ == b.len_ && std::memcmp(a.path_, b.path_, a.len_) == 0;
     105                 :     }
     106                 : 
     107                 :     /** Format the endpoint for stream output.
     108                 : 
     109                 :         Non-abstract paths are printed as-is. Abstract paths
     110                 :         (leading null byte) are printed as `[abstract:name]`.
     111                 :         Empty endpoints produce no output.
     112                 : 
     113                 :         @param os The output stream.
     114                 :         @param ep The endpoint to format.
     115                 : 
     116                 :         @return A reference to @p os.
     117                 :     */
     118                 :     friend BOOST_COROSIO_DECL std::ostream&
     119                 :     operator<<(std::ostream& os, local_endpoint const& ep);
     120                 : 
     121                 :     /// Lexicographic ordering on stored path bytes.
     122                 :     friend std::strong_ordering
     123              44 :     operator<=>(local_endpoint const& a, local_endpoint const& b) noexcept
     124                 :     {
     125              44 :         auto common = (std::min)(a.len_, b.len_);
     126              44 :         if (int cmp = std::memcmp(a.path_, b.path_, common); cmp != 0)
     127              19 :             return cmp <=> 0;
     128              25 :         return a.len_ <=> b.len_;
     129                 :     }
     130                 : };
     131                 : 
     132                 : /** Make a local endpoint from a filesystem path.
     133                 : 
     134                 :     A path longer than @ref local_endpoint::max_path_length cannot be
     135                 :     represented in a socket address. Such a path reports
     136                 :     `errc::filename_too_long` with an empty endpoint.
     137                 : 
     138                 :     @par Example
     139                 :     @par !example make_local_endpoint
     140                 : 
     141                 :     @param path The socket path; an empty path yields an unbound endpoint.
     142                 : 
     143                 :     @return The error code and the endpoint.
     144                 : */
     145                 : [[nodiscard]] BOOST_COROSIO_DECL capy::results<local_endpoint>
     146                 : make_local_endpoint(std::string_view path) noexcept;
     147                 : 
     148                 : } // namespace boost::corosio
     149                 : 
     150                 : #endif // BOOST_COROSIO_LOCAL_ENDPOINT_HPP
        

Generated by: LCOV version 2.3