1  
//
1  
//
2  
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot com)
2  
// Copyright (c) 2025 Vinnie Falco (vinnie dot falco at gmail dot 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(
49  
    resolver_entry(
50  
        endpoint ep,
50  
        endpoint ep,
51  
        std::string_view host,
51  
        std::string_view host,
52  
        std::string_view service)
52  
        std::string_view service)
53  
        : ep_(ep)
53  
        : ep_(ep)
54  
        , host_name_(host)
54  
        , host_name_(host)
55  
        , service_name_(service)
55  
        , service_name_(service)
56  
    {
56  
    {
57  
    }
57  
    }
58  

58  

59  
    /** Get the endpoint. */
59  
    /** Get the endpoint. */
60  
    endpoint
60  
    endpoint
61  
    get_endpoint() const noexcept
61  
    get_endpoint() const noexcept
62  
    {
62  
    {
63  
        return ep_;
63  
        return ep_;
64  
    }
64  
    }
65  

65  

66  
    /** Implicit conversion to endpoint. */
66  
    /** Implicit conversion to endpoint. */
67  
    operator endpoint() const noexcept
67  
    operator endpoint() const noexcept
68  
    {
68  
    {
69  
        return ep_;
69  
        return ep_;
70  
    }
70  
    }
71  

71  

72  
    /** Get the host name from the query. */
72  
    /** Get the host name from the query. */
73  
    std::string const&
73  
    std::string const&
74  
    host_name() const noexcept
74  
    host_name() const noexcept
75  
    {
75  
    {
76  
        return host_name_;
76  
        return host_name_;
77  
    }
77  
    }
78  

78  

79  
    /** Get the service name from the query. */
79  
    /** Get the service name from the query. */
80  
    std::string const&
80  
    std::string const&
81  
    service_name() const noexcept
81  
    service_name() const noexcept
82  
    {
82  
    {
83  
        return service_name_;
83  
        return service_name_;
84  
    }
84  
    }
85  
};
85  
};
86  

86  

87  
//------------------------------------------------------------------------------
87  
//------------------------------------------------------------------------------
88  

88  

89  
/** A range of entries produced by a resolver.
89  
/** A range of entries produced by a resolver.
90  

90  

91  
    This class holds the results of a DNS resolution query.
91  
    This class holds the results of a DNS resolution query.
92  
    It provides a range interface for iterating over the
92  
    It provides a range interface for iterating over the
93  
    resolved endpoints.
93  
    resolved endpoints.
94  

94  

95  
    @par Thread Safety
95  
    @par Thread Safety
96  
    Distinct objects: Safe.@n
96  
    Distinct objects: Safe.@n
97  
    Shared objects: Safe (immutable after construction).
97  
    Shared objects: Safe (immutable after construction).
98  
*/
98  
*/
99  
class resolver_results
99  
class resolver_results
100  
{
100  
{
101  
public:
101  
public:
102  
    using value_type = resolver_entry;
102  
    using value_type = resolver_entry;
103  
    using const_reference = value_type const&;
103  
    using const_reference = value_type const&;
104  
    using reference = const_reference;
104  
    using reference = const_reference;
105  
    using const_iterator = std::vector<resolver_entry>::const_iterator;
105  
    using const_iterator = std::vector<resolver_entry>::const_iterator;
106  
    using iterator = const_iterator;
106  
    using iterator = const_iterator;
107  
    using difference_type = std::ptrdiff_t;
107  
    using difference_type = std::ptrdiff_t;
108  
    using size_type = std::size_t;
108  
    using size_type = std::size_t;
109  

109  

110  
private:
110  
private:
111  
    std::shared_ptr<std::vector<resolver_entry>> entries_;
111  
    std::shared_ptr<std::vector<resolver_entry>> entries_;
112  

112  

113  
public:
113  
public:
114  
    /** Default constructor creates an empty range. */
114  
    /** Default constructor creates an empty range. */
115  
    resolver_results() = default;
115  
    resolver_results() = default;
116  

116  

117  
    /** Construct from a vector of entries.
117  
    /** Construct from a vector of entries.
118  

118  

119  
        @param entries The resolved entries.
119  
        @param entries The resolved entries.
120  
    */
120  
    */
121  
    explicit
121  
    explicit
122  
    resolver_results(std::vector<resolver_entry> entries)
122  
    resolver_results(std::vector<resolver_entry> entries)
123  
        : entries_(std::make_shared<std::vector<resolver_entry>>(
123  
        : entries_(std::make_shared<std::vector<resolver_entry>>(
124  
            std::move(entries)))
124  
            std::move(entries)))
125  
    {
125  
    {
126  
    }
126  
    }
127  

127  

128  
    /** Get the number of entries. */
128  
    /** Get the number of entries. */
129  
    size_type
129  
    size_type
130  
    size() const noexcept
130  
    size() const noexcept
131  
    {
131  
    {
132  
        return entries_ ? entries_->size() : 0;
132  
        return entries_ ? entries_->size() : 0;
133  
    }
133  
    }
134  

134  

135  
    /** Check if the results are empty. */
135  
    /** Check if the results are empty. */
136  
    bool
136  
    bool
137  
    empty() const noexcept
137  
    empty() const noexcept
138  
    {
138  
    {
139  
        return !entries_ || entries_->empty();
139  
        return !entries_ || entries_->empty();
140  
    }
140  
    }
141  

141  

142  
    /** Get an iterator to the first entry. */
142  
    /** Get an iterator to the first entry. */
143  
    const_iterator
143  
    const_iterator
144  
    begin() const noexcept
144  
    begin() const noexcept
145  
    {
145  
    {
146  
        if (entries_)
146  
        if (entries_)
147  
            return entries_->begin();
147  
            return entries_->begin();
148  
        return std::vector<resolver_entry>::const_iterator();
148  
        return std::vector<resolver_entry>::const_iterator();
149  
    }
149  
    }
150  

150  

151  
    /** Get an iterator past the last entry. */
151  
    /** Get an iterator past the last entry. */
152  
    const_iterator
152  
    const_iterator
153  
    end() const noexcept
153  
    end() const noexcept
154  
    {
154  
    {
155  
        if (entries_)
155  
        if (entries_)
156  
            return entries_->end();
156  
            return entries_->end();
157  
        return std::vector<resolver_entry>::const_iterator();
157  
        return std::vector<resolver_entry>::const_iterator();
158  
    }
158  
    }
159  

159  

160  
    /** Get an iterator to the first entry. */
160  
    /** Get an iterator to the first entry. */
161  
    const_iterator
161  
    const_iterator
162  
    cbegin() const noexcept
162  
    cbegin() const noexcept
163  
    {
163  
    {
164  
        return begin();
164  
        return begin();
165  
    }
165  
    }
166  

166  

167  
    /** Get an iterator past the last entry. */
167  
    /** Get an iterator past the last entry. */
168  
    const_iterator
168  
    const_iterator
169  
    cend() const noexcept
169  
    cend() const noexcept
170  
    {
170  
    {
171  
        return end();
171  
        return end();
172  
    }
172  
    }
173  

173  

174  
    /** Swap with another results object. */
174  
    /** Swap with another results object. */
175  
    void
175  
    void
176  
    swap(resolver_results& other) noexcept
176  
    swap(resolver_results& other) noexcept
177  
    {
177  
    {
178  
        entries_.swap(other.entries_);
178  
        entries_.swap(other.entries_);
179  
    }
179  
    }
180  

180  

181  
    /** Test for equality. */
181  
    /** Test for equality. */
182  
    friend
182  
    friend
183  
    bool
183  
    bool
184  
    operator==(
184  
    operator==(
185  
        resolver_results const& a,
185  
        resolver_results const& a,
186  
        resolver_results const& b) noexcept
186  
        resolver_results const& b) noexcept
187  
    {
187  
    {
188  
        return a.entries_ == b.entries_;
188  
        return a.entries_ == b.entries_;
189  
    }
189  
    }
190  

190  

191  
    /** Test for inequality. */
191  
    /** Test for inequality. */
192  
    friend
192  
    friend
193  
    bool
193  
    bool
194  
    operator!=(
194  
    operator!=(
195  
        resolver_results const& a,
195  
        resolver_results const& a,
196  
        resolver_results const& b) noexcept
196  
        resolver_results const& b) noexcept
197  
    {
197  
    {
198  
        return !(a == b);
198  
        return !(a == b);
199  
    }
199  
    }
200  
};
200  
};
201  

201  

202  
//------------------------------------------------------------------------------
202  
//------------------------------------------------------------------------------
203  

203  

204  
/** The result of a reverse DNS resolution.
204  
/** The result of a reverse DNS resolution.
205  

205  

206  
    This class holds the result of resolving an endpoint
206  
    This class holds the result of resolving an endpoint
207  
    into a hostname and service name.
207  
    into a hostname and service name.
208  

208  

209  
    @par Thread Safety
209  
    @par Thread Safety
210  
    Distinct objects: Safe.@n
210  
    Distinct objects: Safe.@n
211  
    Shared objects: Safe.
211  
    Shared objects: Safe.
212  
*/
212  
*/
213  
class reverse_resolver_result
213  
class reverse_resolver_result
214  
{
214  
{
215  
    corosio::endpoint ep_;
215  
    corosio::endpoint ep_;
216  
    std::string host_;
216  
    std::string host_;
217  
    std::string service_;
217  
    std::string service_;
218  

218  

219  
public:
219  
public:
220  
    /** Default constructor. */
220  
    /** Default constructor. */
221  
    reverse_resolver_result() = default;
221  
    reverse_resolver_result() = default;
222  

222  

223  
    /** Construct with endpoint, host name, and service name.
223  
    /** Construct with endpoint, host name, and service name.
224  

224  

225  
        @param ep The endpoint that was resolved.
225  
        @param ep The endpoint that was resolved.
226  
        @param host The resolved host name.
226  
        @param host The resolved host name.
227  
        @param service The resolved service name.
227  
        @param service The resolved service name.
228  
    */
228  
    */
229  
    reverse_resolver_result(
229  
    reverse_resolver_result(
230  
        corosio::endpoint ep,
230  
        corosio::endpoint ep,
231  
        std::string host,
231  
        std::string host,
232  
        std::string service)
232  
        std::string service)
233  
        : ep_(ep)
233  
        : ep_(ep)
234  
        , host_(std::move(host))
234  
        , host_(std::move(host))
235  
        , service_(std::move(service))
235  
        , service_(std::move(service))
236  
    {
236  
    {
237  
    }
237  
    }
238  

238  

239  
    /** Get the endpoint that was resolved. */
239  
    /** Get the endpoint that was resolved. */
240  
    corosio::endpoint
240  
    corosio::endpoint
241  
    endpoint() const noexcept
241  
    endpoint() const noexcept
242  
    {
242  
    {
243  
        return ep_;
243  
        return ep_;
244  
    }
244  
    }
245  

245  

246  
    /** Get the resolved host name. */
246  
    /** Get the resolved host name. */
247  
    std::string const&
247  
    std::string const&
248  
    host_name() const noexcept
248  
    host_name() const noexcept
249  
    {
249  
    {
250  
        return host_;
250  
        return host_;
251  
    }
251  
    }
252  

252  

253  
    /** Get the resolved service name. */
253  
    /** Get the resolved service name. */
254  
    std::string const&
254  
    std::string const&
255  
    service_name() const noexcept
255  
    service_name() const noexcept
256  
    {
256  
    {
257  
        return service_;
257  
        return service_;
258  
    }
258  
    }
259  
};
259  
};
260  

260  

261  
} // namespace boost::corosio
261  
} // namespace boost::corosio
262  

262  

263  
#endif
263  
#endif