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  
    /// Construct a default empty entry.
40  
    /// Construct a default empty entry.
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  
    /// Return the resolved endpoint.
56  
    /// Return the resolved 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  
    /// Convert to endpoint.
62  
    /// Convert 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  
    /// Return the host name from the query.
68  
    /// Return 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  
    /// Return the service name from the query.
74  
    /// Return 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  
    /// The entry type.
94  
    /// The entry type.
95  
    using value_type = resolver_entry;
95  
    using value_type = resolver_entry;
96  

96  

97  
    /// Const reference to an entry.
97  
    /// Const reference to an entry.
98  
    using const_reference = value_type const&;
98  
    using const_reference = value_type const&;
99  

99  

100  
    /// Reference to an entry (always const).
100  
    /// Reference to an entry (always const).
101  
    using reference = const_reference;
101  
    using reference = const_reference;
102  

102  

103  
    /// Const iterator over entries.
103  
    /// Const iterator over entries.
104  
    using const_iterator = std::vector<resolver_entry>::const_iterator;
104  
    using const_iterator = std::vector<resolver_entry>::const_iterator;
105  

105  

106  
    /// Iterator over entries (always const).
106  
    /// Iterator over entries (always const).
107  
    using iterator = const_iterator;
107  
    using iterator = const_iterator;
108  

108  

109  
    /// Signed difference type.
109  
    /// Signed difference type.
110  
    using difference_type = std::ptrdiff_t;
110  
    using difference_type = std::ptrdiff_t;
111  

111  

112  
    /// Unsigned size type.
112  
    /// Unsigned size type.
113  
    using size_type = std::size_t;
113  
    using size_type = std::size_t;
114  

114  

115  
private:
115  
private:
116  
    std::shared_ptr<std::vector<resolver_entry>> entries_;
116  
    std::shared_ptr<std::vector<resolver_entry>> entries_;
117  

117  

118  
public:
118  
public:
119  
    /// Construct an empty results range.
119  
    /// Construct an empty results range.
120  
    resolver_results() = default;
120  
    resolver_results() = default;
121  

121  

122  
    /** Construct from a vector of entries.
122  
    /** Construct from a vector of entries.
123  

123  

124  
        @param entries The resolved entries.
124  
        @param entries The resolved entries.
125  
    */
125  
    */
126  
    explicit resolver_results(std::vector<resolver_entry> entries)
126  
    explicit resolver_results(std::vector<resolver_entry> entries)
127  
        : entries_(
127  
        : entries_(
128  
              std::make_shared<std::vector<resolver_entry>>(std::move(entries)))
128  
              std::make_shared<std::vector<resolver_entry>>(std::move(entries)))
129  
    {
129  
    {
130  
    }
130  
    }
131  

131  

132  
    /// Return the number of entries.
132  
    /// Return the number of entries.
133  
    size_type size() const noexcept
133  
    size_type size() const noexcept
134  
    {
134  
    {
135  
        return entries_ ? entries_->size() : 0;
135  
        return entries_ ? entries_->size() : 0;
136  
    }
136  
    }
137  

137  

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

143  

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

151  

152  
    /// Return an iterator past the last entry.
152  
    /// Return an iterator past the last entry.
153  
    const_iterator end() const noexcept
153  
    const_iterator 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  
    /// Return an iterator to the first entry.
160  
    /// Return an iterator to the first entry.
161  
    const_iterator cbegin() const noexcept
161  
    const_iterator cbegin() const noexcept
162  
    {
162  
    {
163  
        return begin();
163  
        return begin();
164  
    }
164  
    }
165  

165  

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

171  

172  
    /// Swap with another results object.
172  
    /// Swap with another results object.
173  
    void swap(resolver_results& other) noexcept
173  
    void swap(resolver_results& other) noexcept
174  
    {
174  
    {
175  
        entries_.swap(other.entries_);
175  
        entries_.swap(other.entries_);
176  
    }
176  
    }
177  

177  

178  
    /// Test for equality.
178  
    /// Test for equality.
179  
    friend bool
179  
    friend bool
180  
    operator==(resolver_results const& a, resolver_results const& b) noexcept
180  
    operator==(resolver_results const& a, resolver_results const& b) noexcept
181  
    {
181  
    {
182  
        return a.entries_ == b.entries_;
182  
        return a.entries_ == b.entries_;
183  
    }
183  
    }
184  

184  

185  
    /// Test for inequality.
185  
    /// Test for inequality.
186  
    friend bool
186  
    friend bool
187  
    operator!=(resolver_results const& a, resolver_results const& b) noexcept
187  
    operator!=(resolver_results const& a, resolver_results const& b) noexcept
188  
    {
188  
    {
189  
        return !(a == b);
189  
        return !(a == b);
190  
    }
190  
    }
191  
};
191  
};
192  

192  

193  
/** The result of a reverse DNS resolution.
193  
/** The result of a reverse DNS resolution.
194  

194  

195  
    This class holds the result of resolving an endpoint
195  
    This class holds the result of resolving an endpoint
196  
    into a hostname and service name.
196  
    into a hostname and service name.
197  

197  

198  
    @par Thread Safety
198  
    @par Thread Safety
199  
    Distinct objects: Safe.@n
199  
    Distinct objects: Safe.@n
200  
    Shared objects: Safe.
200  
    Shared objects: Safe.
201  
*/
201  
*/
202  
class reverse_resolver_result
202  
class reverse_resolver_result
203  
{
203  
{
204  
    corosio::endpoint ep_;
204  
    corosio::endpoint ep_;
205  
    std::string host_;
205  
    std::string host_;
206  
    std::string service_;
206  
    std::string service_;
207  

207  

208  
public:
208  
public:
209  
    /// Construct a default empty result.
209  
    /// Construct a default empty result.
210  
    reverse_resolver_result() = default;
210  
    reverse_resolver_result() = default;
211  

211  

212  
    /** Construct with endpoint, host name, and service name.
212  
    /** Construct with endpoint, host name, and service name.
213  

213  

214  
        @param ep The endpoint that was resolved.
214  
        @param ep The endpoint that was resolved.
215  
        @param host The resolved host name.
215  
        @param host The resolved host name.
216  
        @param service The resolved service name.
216  
        @param service The resolved service name.
217  
    */
217  
    */
218  
    reverse_resolver_result(
218  
    reverse_resolver_result(
219  
        corosio::endpoint ep, std::string host, std::string service)
219  
        corosio::endpoint ep, std::string host, std::string service)
220  
        : ep_(ep)
220  
        : ep_(ep)
221  
        , host_(std::move(host))
221  
        , host_(std::move(host))
222  
        , service_(std::move(service))
222  
        , service_(std::move(service))
223  
    {
223  
    {
224  
    }
224  
    }
225  

225  

226  
    /// Return the endpoint that was resolved.
226  
    /// Return the endpoint that was resolved.
227  
    corosio::endpoint endpoint() const noexcept
227  
    corosio::endpoint endpoint() const noexcept
228  
    {
228  
    {
229  
        return ep_;
229  
        return ep_;
230  
    }
230  
    }
231  

231  

232  
    /// Return the resolved host name.
232  
    /// Return the resolved host name.
233  
    std::string const& host_name() const noexcept
233  
    std::string const& host_name() const noexcept
234  
    {
234  
    {
235  
        return host_;
235  
        return host_;
236  
    }
236  
    }
237  

237  

238  
    /// Return the resolved service name.
238  
    /// Return the resolved service name.
239  
    std::string const& service_name() const noexcept
239  
    std::string const& service_name() const noexcept
240  
    {
240  
    {
241  
        return service_;
241  
        return service_;
242  
    }
242  
    }
243  
};
243  
};
244  

244  

245  
} // namespace boost::corosio
245  
} // namespace boost::corosio
246  

246  

247  
#endif
247  
#endif