blob: c29ef9db8c68d8d02cb7748ad90739507ded3488 [file] [log] [blame]
// 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_