1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
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)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/corosio
7  
// Official repository: https://github.com/cppalliance/corosio
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_COROSIO_RESOLVER_RESULTS_HPP
10  
#ifndef BOOST_COROSIO_RESOLVER_RESULTS_HPP
11  
#define BOOST_COROSIO_RESOLVER_RESULTS_HPP
11  
#define BOOST_COROSIO_RESOLVER_RESULTS_HPP
12  

12  

13  
#include <boost/corosio/detail/config.hpp>
13  
#include <boost/corosio/detail/config.hpp>
14  
#include <boost/corosio/endpoint.hpp>
14  
#include <boost/corosio/endpoint.hpp>
15  

15  

16  
#include <cstddef>
16  
#include <cstddef>
17  
#include <memory>
17  
#include <memory>
18  
#include <string>
18  
#include <string>
19  
#include <string_view>
19  
#include <string_view>
20  
#include <vector>
20  
#include <vector>
21  

21  

22  
namespace boost::corosio {
22  
namespace boost::corosio {
23  

23  

24  
/** A single entry produced by a resolver.
24  
/** A single entry produced by a resolver.
25  

25  

26  
    This class represents one resolved endpoint along with
26  
    This class represents one resolved endpoint along with
27  
    the host and service names used in the query.
27  
    the host and service names used in the query.
28  

28  

29  
    @par Thread Safety
29  
    @par Thread Safety
30  
    Distinct objects: Safe.@n
30  
    Distinct objects: Safe.@n
31  
    Shared objects: Safe.
31  
    Shared objects: Safe.
32  
*/
32  
*/
33  
class resolver_entry
33  
class resolver_entry
34  
{
34  
{
35  
    endpoint ep_;
35  
    endpoint ep_;
36  
    std::string host_name_;
36  
    std::string host_name_;
37  
    std::string service_name_;
37  
    std::string service_name_;
38  

38  

39  
public:
39  
public:
40  
    /** Default constructor. */
40  
    /** Default constructor. */
41  
    resolver_entry() = default;
41  
    resolver_entry() = default;
42  

42  

43  
    /** Construct with endpoint, host name, and service name.
43  
    /** Construct with endpoint, host name, and service name.
44  

44  

45  
        @param ep The resolved endpoint.
45  
        @param ep The resolved endpoint.
46  
        @param host The host name from the query.
46  
        @param host The host name from the query.
47  
        @param service The service name from the query.
47  
        @param service The service name from the query.
48  
    */
48  
    */
49  
    resolver_entry(endpoint ep, std::string_view host, std::string_view service)
49  
    resolver_entry(endpoint ep, std::string_view host, std::string_view service)
50  
        : ep_(ep)
50  
        : ep_(ep)
51  
        , host_name_(host)
51  
        , host_name_(host)
52  
        , service_name_(service)
52  
        , service_name_(service)
53  
    {
53  
    {
54  
    }
54  
    }
55  

55  

56  
    /** Get the endpoint. */
56  
    /** Get the endpoint. */
57  
    endpoint get_endpoint() const noexcept
57  
    endpoint get_endpoint() const noexcept
58  
    {
58  
    {
59  
        return ep_;
59  
        return ep_;
60  
    }
60  
    }
61  

61  

62  
    /** Implicit conversion to endpoint. */
62  
    /** Implicit conversion to endpoint. */
63  
    operator endpoint() const noexcept
63  
    operator endpoint() const noexcept
64  
    {
64  
    {
65  
        return ep_;
65  
        return ep_;
66  
    }
66  
    }
67  

67  

68  
    /** Get the host name from the query. */
68  
    /** Get the host name from the query. */
69  
    std::string const& host_name() const noexcept
69  
    std::string const& host_name() const noexcept
70  
    {
70  
    {
71  
        return host_name_;
71  
        return host_name_;
72  
    }
72  
    }
73  

73  

74  
    /** Get the service name from the query. */
74  
    /** Get the service name from the query. */
75  
    std::string const& service_name() const noexcept
75  
    std::string const& service_name() const noexcept
76  
    {
76  
    {
77  
        return service_name_;
77  
        return service_name_;
78  
    }
78  
    }
79  
};
79  
};
80  

80  

81  
/** A range of entries produced by a resolver.
81  
/** A range of entries produced by a resolver.
82  

82  

83  
    This class holds the results of a DNS resolution query.
83  
    This class holds the results of a DNS resolution query.
84  
    It provides a range interface for iterating over the
84  
    It provides a range interface for iterating over the
85  
    resolved endpoints.
85  
    resolved endpoints.
86  

86  

87  
    @par Thread Safety
87  
    @par Thread Safety
88  
    Distinct objects: Safe.@n
88  
    Distinct objects: Safe.@n
89  
    Shared objects: Safe (immutable after construction).
89  
    Shared objects: Safe (immutable after construction).
90  
*/
90  
*/
91  
class resolver_results
91  
class resolver_results
92  
{
92  
{
93  
public:
93  
public:
94  
    using value_type      = resolver_entry;
94  
    using value_type      = resolver_entry;
95  
    using const_reference = value_type const&;
95  
    using const_reference = value_type const&;
96  
    using reference       = const_reference;
96  
    using reference       = const_reference;
97  
    using const_iterator  = std::vector<resolver_entry>::const_iterator;
97  
    using const_iterator  = std::vector<resolver_entry>::const_iterator;
98  
    using iterator        = const_iterator;
98  
    using iterator        = const_iterator;
99  
    using difference_type = std::ptrdiff_t;
99  
    using difference_type = std::ptrdiff_t;
100  
    using size_type       = std::size_t;
100  
    using size_type       = std::size_t;
101  

101  

102  
private:
102  
private:
103  
    std::shared_ptr<std::vector<resolver_entry>> entries_;
103  
    std::shared_ptr<std::vector<resolver_entry>> entries_;
104  

104  

105  
public:
105  
public:
106  
    /** Default constructor creates an empty range. */
106  
    /** Default constructor creates an empty range. */
107  
    resolver_results() = default;
107  
    resolver_results() = default;
108  

108  

109  
    /** Construct from a vector of entries.
109  
    /** Construct from a vector of entries.
110  

110  

111  
        @param entries The resolved entries.
111  
        @param entries The resolved entries.
112  
    */
112  
    */
113  
    explicit resolver_results(std::vector<resolver_entry> entries)
113  
    explicit resolver_results(std::vector<resolver_entry> entries)
114  
        : entries_(
114  
        : entries_(
115  
              std::make_shared<std::vector<resolver_entry>>(std::move(entries)))
115  
              std::make_shared<std::vector<resolver_entry>>(std::move(entries)))
116  
    {
116  
    {
117  
    }
117  
    }
118  

118  

119  
    /** Get the number of entries. */
119  
    /** Get the number of entries. */
120  
    size_type size() const noexcept
120  
    size_type size() const noexcept
121  
    {
121  
    {
122  
        return entries_ ? entries_->size() : 0;
122  
        return entries_ ? entries_->size() : 0;
123  
    }
123  
    }
124  

124  

125  
    /** Check if the results are empty. */
125  
    /** Check if the results are empty. */
126  
    bool empty() const noexcept
126  
    bool empty() const noexcept
127  
    {
127  
    {
128  
        return !entries_ || entries_->empty();
128  
        return !entries_ || entries_->empty();
129  
    }
129  
    }
130  

130  

131  
    /** Get an iterator to the first entry. */
131  
    /** Get an iterator to the first entry. */
132  
    const_iterator begin() const noexcept
132  
    const_iterator begin() const noexcept
133  
    {
133  
    {
134  
        if (entries_)
134  
        if (entries_)
135  
            return entries_->begin();
135  
            return entries_->begin();
136  
        return std::vector<resolver_entry>::const_iterator();
136  
        return std::vector<resolver_entry>::const_iterator();
137  
    }
137  
    }
138  

138  

139  
    /** Get an iterator past the last entry. */
139  
    /** Get an iterator past the last entry. */
140  
    const_iterator end() const noexcept
140  
    const_iterator end() const noexcept
141  
    {
141  
    {
142  
        if (entries_)
142  
        if (entries_)
143  
            return entries_->end();
143  
            return entries_->end();
144  
        return std::vector<resolver_entry>::const_iterator();
144  
        return std::vector<resolver_entry>::const_iterator();
145  
    }
145  
    }
146  

146  

147  
    /** Get an iterator to the first entry. */
147  
    /** Get an iterator to the first entry. */
148  
    const_iterator cbegin() const noexcept
148  
    const_iterator cbegin() const noexcept
149  
    {
149  
    {
150  
        return begin();
150  
        return begin();
151  
    }
151  
    }
152  

152  

153  
    /** Get an iterator past the last entry. */
153  
    /** Get an iterator past the last entry. */
154  
    const_iterator cend() const noexcept
154  
    const_iterator cend() const noexcept
155  
    {
155  
    {
156  
        return end();
156  
        return end();
157  
    }
157  
    }
158  

158  

159  
    /** Swap with another results object. */
159  
    /** Swap with another results object. */
160  
    void swap(resolver_results& other) noexcept
160  
    void swap(resolver_results& other) noexcept
161  
    {
161  
    {
162  
        entries_.swap(other.entries_);
162  
        entries_.swap(other.entries_);
163  
    }
163  
    }
164  

164  

165  
    /** Test for equality. */
165  
    /** Test for equality. */
166  
    friend bool
166  
    friend bool
167  
    operator==(resolver_results const& a, resolver_results const& b) noexcept
167  
    operator==(resolver_results const& a, resolver_results const& b) noexcept
168  
    {
168  
    {
169  
        return a.entries_ == b.entries_;
169  
        return a.entries_ == b.entries_;
170  
    }
170  
    }
171  

171  

172  
    /** Test for inequality. */
172  
    /** Test for inequality. */
173  
    friend bool
173  
    friend bool
174  
    operator!=(resolver_results const& a, resolver_results const& b) noexcept
174  
    operator!=(resolver_results const& a, resolver_results const& b) noexcept
175  
    {
175  
    {
176  
        return !(a == b);
176  
        return !(a == b);
177  
    }
177  
    }
178  
};
178  
};
179  

179  

180  
/** The result of a reverse DNS resolution.
180  
/** The result of a reverse DNS resolution.
181  

181  

182  
    This class holds the result of resolving an endpoint
182  
    This class holds the result of resolving an endpoint
183  
    into a hostname and service name.
183  
    into a hostname and service name.
184  

184  

185  
    @par Thread Safety
185  
    @par Thread Safety
186  
    Distinct objects: Safe.@n
186  
    Distinct objects: Safe.@n
187  
    Shared objects: Safe.
187  
    Shared objects: Safe.
188  
*/
188  
*/
189  
class reverse_resolver_result
189  
class reverse_resolver_result
190  
{
190  
{
191  
    corosio::endpoint ep_;
191  
    corosio::endpoint ep_;
192  
    std::string host_;
192  
    std::string host_;
193  
    std::string service_;
193  
    std::string service_;
194  

194  

195  
public:
195  
public:
196  
    /** Default constructor. */
196  
    /** Default constructor. */
197  
    reverse_resolver_result() = default;
197  
    reverse_resolver_result() = default;
198  

198  

199  
    /** Construct with endpoint, host name, and service name.
199  
    /** Construct with endpoint, host name, and service name.
200  

200  

201  
        @param ep The endpoint that was resolved.
201  
        @param ep The endpoint that was resolved.
202  
        @param host The resolved host name.
202  
        @param host The resolved host name.
203  
        @param service The resolved service name.
203  
        @param service The resolved service name.
204  
    */
204  
    */
205  
    reverse_resolver_result(
205  
    reverse_resolver_result(
206  
        corosio::endpoint ep, std::string host, std::string service)
206  
        corosio::endpoint ep, std::string host, std::string service)
207  
        : ep_(ep)
207  
        : ep_(ep)
208  
        , host_(std::move(host))
208  
        , host_(std::move(host))
209  
        , service_(std::move(service))
209  
        , service_(std::move(service))
210  
    {
210  
    {
211  
    }
211  
    }
212  

212  

213  
    /** Get the endpoint that was resolved. */
213  
    /** Get the endpoint that was resolved. */
214  
    corosio::endpoint endpoint() const noexcept
214  
    corosio::endpoint endpoint() const noexcept
215  
    {
215  
    {
216  
        return ep_;
216  
        return ep_;
217  
    }
217  
    }
218  

218  

219  
    /** Get the resolved host name. */
219  
    /** Get the resolved host name. */
220  
    std::string const& host_name() const noexcept
220  
    std::string const& host_name() const noexcept
221  
    {
221  
    {
222  
        return host_;
222  
        return host_;
223  
    }
223  
    }
224  

224  

225  
    /** Get the resolved service name. */
225  
    /** Get the resolved service name. */
226  
    std::string const& service_name() const noexcept
226  
    std::string const& service_name() const noexcept
227  
    {
227  
    {
228  
        return service_;
228  
        return service_;
229  
    }
229  
    }
230  
};
230  
};
231  

231  

232  
} // namespace boost::corosio
232  
} // namespace boost::corosio
233  

233  

234  
#endif
234  
#endif