1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef DISCOVERY_MDNS_MDNS_WRITER_H_ 6 #define DISCOVERY_MDNS_MDNS_WRITER_H_ 7 8 #include <string> 9 #include <unordered_map> 10 #include <vector> 11 12 #include "discovery/mdns/mdns_records.h" 13 #include "util/big_endian.h" 14 15 namespace openscreen { 16 namespace discovery { 17 18 class MdnsWriter : public BigEndianWriter { 19 public: 20 using BigEndianWriter::BigEndianWriter; 21 using BigEndianWriter::Write; 22 23 // The following methods return true if the method was able to successfully 24 // write the value to the underlying buffer and advances current() to point 25 // right past the written data. Returns false if the method failed to write 26 // the value to the underlying buffer, current() remains unchanged. 27 bool Write(absl::string_view value); 28 bool Write(const std::string& value); 29 bool Write(const DomainName& name); 30 bool Write(const RawRecordRdata& rdata); 31 bool Write(const SrvRecordRdata& rdata); 32 bool Write(const ARecordRdata& rdata); 33 bool Write(const AAAARecordRdata& rdata); 34 bool Write(const PtrRecordRdata& rdata); 35 bool Write(const TxtRecordRdata& rdata); 36 bool Write(const NsecRecordRdata& rdata); 37 bool Write(const OptRecordRdata& rdata); 38 // Writes a DNS resource record with its RDATA. 39 // The correct type of RDATA to be written is contained in the type 40 // specified in the record. 41 bool Write(const MdnsRecord& record); 42 bool Write(const MdnsQuestion& question); 43 // Writes multiple mDNS questions and records that are a part of 44 // a mDNS message being read 45 bool Write(const MdnsMessage& message); 46 47 private: 48 bool Write(const IPAddress& address); 49 bool Write(const Rdata& rdata); 50 bool Write(const Header& header); 51 52 template <class ItemType> Write(const std::vector<ItemType> & collection)53 bool Write(const std::vector<ItemType>& collection) { 54 Cursor cursor(this); 55 for (const ItemType& entry : collection) { 56 if (!Write(entry)) { 57 return false; 58 } 59 } 60 cursor.Commit(); 61 return true; 62 } 63 64 // Domain name compression dictionary. 65 // Maps hashes of previously written domain (sub)names 66 // to the label pointers of the first occurrences in the underlying buffer. 67 // Compression of multiple domain names is supported on the same instance of 68 // the MdnsWriter. Underlying buffer may contain other data in addition to the 69 // domain names. The compression dictionary persists between calls to 70 // Write. 71 // Label pointer is only 16 bits in size as per RFC 1035. Only lower 14 bits 72 // are allocated for storing the offset. 73 std::unordered_map<uint64_t, uint16_t> dictionary_; 74 }; 75 76 } // namespace discovery 77 } // namespace openscreen 78 79 #endif // DISCOVERY_MDNS_MDNS_WRITER_H_ 80