xref: /aosp_15_r20/external/openscreen/discovery/dnssd/impl/service_key.h (revision 3f982cf4871df8771c9d4abe6e9a6f8d829b2736)
1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard 
5*3f982cf4SFabien Sanglard #ifndef DISCOVERY_DNSSD_IMPL_SERVICE_KEY_H_
6*3f982cf4SFabien Sanglard #define DISCOVERY_DNSSD_IMPL_SERVICE_KEY_H_
7*3f982cf4SFabien Sanglard 
8*3f982cf4SFabien Sanglard #include <string>
9*3f982cf4SFabien Sanglard #include <utility>
10*3f982cf4SFabien Sanglard 
11*3f982cf4SFabien Sanglard #include "absl/strings/string_view.h"
12*3f982cf4SFabien Sanglard #include "platform/base/error.h"
13*3f982cf4SFabien Sanglard 
14*3f982cf4SFabien Sanglard namespace openscreen {
15*3f982cf4SFabien Sanglard namespace discovery {
16*3f982cf4SFabien Sanglard 
17*3f982cf4SFabien Sanglard class DomainName;
18*3f982cf4SFabien Sanglard class MdnsRecord;
19*3f982cf4SFabien Sanglard 
20*3f982cf4SFabien Sanglard // This class is intended to be used as the key of a std::unordered_map or a
21*3f982cf4SFabien Sanglard // std::map when referencing data related to a service type
22*3f982cf4SFabien Sanglard class ServiceKey {
23*3f982cf4SFabien Sanglard  public:
24*3f982cf4SFabien Sanglard   // NOTE: The record provided must have valid service domain labels.
25*3f982cf4SFabien Sanglard   explicit ServiceKey(const MdnsRecord& record);
26*3f982cf4SFabien Sanglard   explicit ServiceKey(const DomainName& domain);
27*3f982cf4SFabien Sanglard   virtual ~ServiceKey() = default;
28*3f982cf4SFabien Sanglard 
29*3f982cf4SFabien Sanglard   // NOTE: The provided service and domain labels must be valid.
30*3f982cf4SFabien Sanglard   ServiceKey(absl::string_view service, absl::string_view domain);
31*3f982cf4SFabien Sanglard   ServiceKey(const ServiceKey& other);
32*3f982cf4SFabien Sanglard   ServiceKey(ServiceKey&& other);
33*3f982cf4SFabien Sanglard 
34*3f982cf4SFabien Sanglard   ServiceKey& operator=(const ServiceKey& rhs);
35*3f982cf4SFabien Sanglard   ServiceKey& operator=(ServiceKey&& rhs);
36*3f982cf4SFabien Sanglard 
37*3f982cf4SFabien Sanglard   virtual DomainName GetName() const;
38*3f982cf4SFabien Sanglard 
service_id()39*3f982cf4SFabien Sanglard   const std::string& service_id() const { return service_id_; }
domain_id()40*3f982cf4SFabien Sanglard   const std::string& domain_id() const { return domain_id_; }
41*3f982cf4SFabien Sanglard 
42*3f982cf4SFabien Sanglard  private:
43*3f982cf4SFabien Sanglard   static ErrorOr<ServiceKey> TryCreate(const MdnsRecord& record);
44*3f982cf4SFabien Sanglard   static ErrorOr<ServiceKey> TryCreate(const DomainName& domain);
45*3f982cf4SFabien Sanglard 
46*3f982cf4SFabien Sanglard   std::string service_id_;
47*3f982cf4SFabien Sanglard   std::string domain_id_;
48*3f982cf4SFabien Sanglard 
49*3f982cf4SFabien Sanglard   template <typename H>
50*3f982cf4SFabien Sanglard   friend H AbslHashValue(H h, const ServiceKey& key);
51*3f982cf4SFabien Sanglard 
52*3f982cf4SFabien Sanglard   friend bool operator<(const ServiceKey& lhs, const ServiceKey& rhs);
53*3f982cf4SFabien Sanglard 
54*3f982cf4SFabien Sanglard   // Validation method which needs the same code as CreateFromRecord(). Use a
55*3f982cf4SFabien Sanglard   // friend declaration to avoid duplicating this code while still keeping the
56*3f982cf4SFabien Sanglard   // factory private.
57*3f982cf4SFabien Sanglard   friend bool HasValidDnsRecordAddress(const MdnsRecord& record);
58*3f982cf4SFabien Sanglard   friend bool HasValidDnsRecordAddress(const DomainName& domain);
59*3f982cf4SFabien Sanglard };
60*3f982cf4SFabien Sanglard 
61*3f982cf4SFabien Sanglard // Hashing functions to allow for using with absl::Hash<...>.
62*3f982cf4SFabien Sanglard template <typename H>
AbslHashValue(H h,const ServiceKey & key)63*3f982cf4SFabien Sanglard H AbslHashValue(H h, const ServiceKey& key) {
64*3f982cf4SFabien Sanglard   return H::combine(std::move(h), key.service_id_, key.domain_id_);
65*3f982cf4SFabien Sanglard }
66*3f982cf4SFabien Sanglard 
67*3f982cf4SFabien Sanglard // Comparison operators for using above keys with an std::map
68*3f982cf4SFabien Sanglard inline bool operator<(const ServiceKey& lhs, const ServiceKey& rhs) {
69*3f982cf4SFabien Sanglard   int comp = lhs.domain_id_.compare(rhs.domain_id_);
70*3f982cf4SFabien Sanglard   if (comp != 0) {
71*3f982cf4SFabien Sanglard     return comp < 0;
72*3f982cf4SFabien Sanglard   }
73*3f982cf4SFabien Sanglard   return lhs.service_id_ < rhs.service_id_;
74*3f982cf4SFabien Sanglard }
75*3f982cf4SFabien Sanglard 
76*3f982cf4SFabien Sanglard inline bool operator>(const ServiceKey& lhs, const ServiceKey& rhs) {
77*3f982cf4SFabien Sanglard   return rhs < lhs;
78*3f982cf4SFabien Sanglard }
79*3f982cf4SFabien Sanglard 
80*3f982cf4SFabien Sanglard inline bool operator<=(const ServiceKey& lhs, const ServiceKey& rhs) {
81*3f982cf4SFabien Sanglard   return !(rhs > lhs);
82*3f982cf4SFabien Sanglard }
83*3f982cf4SFabien Sanglard 
84*3f982cf4SFabien Sanglard inline bool operator>=(const ServiceKey& lhs, const ServiceKey& rhs) {
85*3f982cf4SFabien Sanglard   return !(rhs < lhs);
86*3f982cf4SFabien Sanglard }
87*3f982cf4SFabien Sanglard 
88*3f982cf4SFabien Sanglard inline bool operator==(const ServiceKey& lhs, const ServiceKey& rhs) {
89*3f982cf4SFabien Sanglard   return lhs <= rhs && lhs >= rhs;
90*3f982cf4SFabien Sanglard }
91*3f982cf4SFabien Sanglard 
92*3f982cf4SFabien Sanglard inline bool operator!=(const ServiceKey& lhs, const ServiceKey& rhs) {
93*3f982cf4SFabien Sanglard   return !(lhs == rhs);
94*3f982cf4SFabien Sanglard }
95*3f982cf4SFabien Sanglard 
96*3f982cf4SFabien Sanglard }  // namespace discovery
97*3f982cf4SFabien Sanglard }  // namespace openscreen
98*3f982cf4SFabien Sanglard 
99*3f982cf4SFabien Sanglard #endif  // DISCOVERY_DNSSD_IMPL_SERVICE_KEY_H_
100