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 -

 
81  

80  

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

82  

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

86  

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

101  

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

104  

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

108  

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

110  

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

118  

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

124  

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

130  

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

138  

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

146  

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

152  

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

158  

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

164  

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

171  

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

 
180  
};
178  
};
181  

179  

182  
/** The result of a reverse DNS resolution.
180  
/** The result of a reverse DNS resolution.
183  

181  

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

184  

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

194  

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

198  

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

200  

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

212  

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

218  

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

224  

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

231  

234  
} // namespace boost::corosio
232  
} // namespace boost::corosio
235  

233  

236  
#endif
234  
#endif