You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.8 KiB
92 lines
2.8 KiB
// Copyright 2018 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#ifndef OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_
|
|
#define OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_
|
|
|
|
#include <cstdint>
|
|
#include <ostream>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "absl/strings/string_view.h"
|
|
#include "platform/base/error.h"
|
|
#include "util/osp_logging.h"
|
|
|
|
namespace openscreen {
|
|
namespace osp {
|
|
|
|
struct DomainName {
|
|
static ErrorOr<DomainName> Append(const DomainName& first,
|
|
const DomainName& second);
|
|
|
|
template <typename It>
|
|
static ErrorOr<DomainName> FromLabels(It first, It last) {
|
|
size_t total_length = 1;
|
|
for (auto label = first; label != last; ++label) {
|
|
if (label->size() > kDomainNameMaxLabelLength)
|
|
return Error::Code::kDomainNameLabelTooLong;
|
|
|
|
total_length += label->size() + 1;
|
|
}
|
|
if (total_length > kDomainNameMaxLength)
|
|
return Error::Code::kDomainNameTooLong;
|
|
|
|
DomainName result;
|
|
result.domain_name_.resize(total_length);
|
|
auto result_it = result.domain_name_.begin();
|
|
for (auto label = first; label != last; ++label) {
|
|
*result_it++ = static_cast<uint8_t>(label->size());
|
|
result_it = std::copy(label->begin(), label->end(), result_it);
|
|
}
|
|
*result_it = 0;
|
|
return std::move(result);
|
|
}
|
|
|
|
static DomainName GetLocalDomain();
|
|
|
|
static constexpr uint8_t kDomainNameMaxLabelLength = 63u;
|
|
static constexpr uint16_t kDomainNameMaxLength = 256u;
|
|
|
|
DomainName();
|
|
explicit DomainName(std::vector<uint8_t>&& domain_name);
|
|
DomainName(const DomainName&);
|
|
DomainName(DomainName&&) noexcept;
|
|
~DomainName();
|
|
DomainName& operator=(const DomainName&);
|
|
DomainName& operator=(DomainName&&) noexcept;
|
|
|
|
bool operator==(const DomainName& other) const;
|
|
bool operator!=(const DomainName& other) const;
|
|
|
|
bool EndsWithLocalDomain() const;
|
|
bool IsEmpty() const { return domain_name_.size() == 1 && !domain_name_[0]; }
|
|
|
|
Error Append(const DomainName& after);
|
|
std::vector<absl::string_view> GetLabels() const;
|
|
|
|
const std::vector<uint8_t>& domain_name() const { return domain_name_; }
|
|
|
|
private:
|
|
// RFC 1035 domain name format: sequence of 1 octet label length followed by
|
|
// label data, ending with a 0 octet. May not exceed 256 bytes (including
|
|
// terminating 0).
|
|
// For example, openscreen.org would be encoded as:
|
|
// {10, 'o', 'p', 'e', 'n', 's', 'c', 'r', 'e', 'e', 'n',
|
|
// 3, 'o', 'r', 'g', 0}
|
|
std::vector<uint8_t> domain_name_;
|
|
};
|
|
|
|
class DomainNameComparator {
|
|
public:
|
|
bool operator()(const DomainName& a, const DomainName& b) const;
|
|
};
|
|
|
|
std::ostream& operator<<(std::ostream& os, const DomainName& domain_name);
|
|
|
|
} // namespace osp
|
|
} // namespace openscreen
|
|
|
|
#endif // OSP_IMPL_DISCOVERY_MDNS_DOMAIN_NAME_H_
|