| Kea 3.0.2-git

txt_like.h
Go to the documentation of this file.
1// Copyright (C) 2011-2025 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7#ifndef TXT_LIKE_H
8#define TXT_LIKE_H
9
10#include <dns/master_lexer.h>
11#include <dns/char_string.h>
12
13#include <stdint.h>
14#include <algorithm>
15#include <string>
16#include <sstream>
17#include <vector>
18
19 namespace isc {
20 namespace dns {
21 namespace rdata {
22 namespace generic {
23 namespace detail {
24
31 template<class Type, uint16_t typeCode>class TXTLikeImpl {
32 public:
43 TXTLikeImpl(util::InputBuffer& buffer, size_t rdata_len) {
44 if (rdata_len > MAX_RDLENGTH) {
45 isc_throw(InvalidRdataLength, "RDLENGTH too large: " << rdata_len);
46 }
47
48 if (rdata_len == 0) { // note that this couldn't happen in the loop.
49 isc_throw(DNSMessageFORMERR, "Error in parsing " <<
50 RRType(typeCode) << " RDATA: 0-length character string");
51 }
52
53 do {
54 const uint8_t len = buffer.readUint8();
55 if (rdata_len < static_cast<size_t>(len) + 1) {
56 isc_throw(DNSMessageFORMERR, "Error in parsing " <<
57 RRType(typeCode) <<
58 " RDATA: character string length is too large: " <<
59 static_cast<int>(len));
60 }
61 std::vector<uint8_t> data(len + 1);
62 data[0] = len;
63 buffer.readData(&data[0] + 1, len);
64 string_list_.push_back(data);
65
66 rdata_len -= (len + 1);
67 } while (rdata_len > 0);
68 }
69
74 explicit TXTLikeImpl(const std::string& txtstr) {
75 std::istringstream ss(txtstr);
76 MasterLexer lexer;
77 lexer.pushSource(ss);
78
79 try {
80 buildFromTextHelper(lexer);
81 if (lexer.getNextToken().getType() != MasterToken::END_OF_FILE) {
82 isc_throw(InvalidRdataText, "Failed to construct " <<
83 RRType(typeCode) << " RDATA from '" << txtstr <<
84 "': extra new line");
85 }
86 } catch (const MasterLexer::LexerError& ex) {
87 isc_throw(InvalidRdataText, "Failed to construct " <<
88 RRType(typeCode) << " RDATA from '" << txtstr << "': "
89 << ex.what());
90 }
91 }
92
100 TXTLikeImpl(MasterLexer& lexer) {
101 buildFromTextHelper(lexer);
102 }
103
104 private:
105 void buildFromTextHelper(MasterLexer& lexer) {
106 while (true) {
107 const MasterToken& token = lexer.getNextToken(
108 MasterToken::QSTRING, true);
109 if (token.getType() != MasterToken::STRING &&
110 token.getType() != MasterToken::QSTRING) {
111 break;
112 }
113 string_list_.push_back(std::vector<uint8_t>());
114 stringToCharString(token.getStringRegion(), string_list_.back());
115 }
116
117 // Let upper layer handle eol/eof.
118 lexer.ungetToken();
119
120 if (string_list_.empty()) {
121 isc_throw(InvalidRdataText, "Failed to construct " <<
122 RRType(typeCode) << " RDATA: empty input");
123 }
124 }
125
126 public:
130 TXTLikeImpl(const TXTLikeImpl& other) :
131 string_list_(other.string_list_)
132 {}
133
138 void
139 toWire(util::OutputBuffer& buffer) const {
140 for (std::vector<std::vector<uint8_t> >::const_iterator it =
141 string_list_.begin();
142 it != string_list_.end();
143 ++it)
144 {
145 buffer.writeData(&(*it)[0], (*it).size());
146 }
147 }
148
154 void
155 toWire(AbstractMessageRenderer& renderer) const {
156 for (std::vector<std::vector<uint8_t> >::const_iterator it =
157 string_list_.begin();
158 it != string_list_.end();
159 ++it)
160 {
161 renderer.writeData(&(*it)[0], (*it).size());
162 }
163 }
164
168 std::string
169 toText() const {
170 std::string s;
171
172 for (std::vector<std::vector<uint8_t> >::const_iterator it =
173 string_list_.begin(); it != string_list_.end(); ++it)
174 {
175 if (!s.empty()) {
176 s.push_back(' ');
177 }
178 s.push_back('"');
179 s.append(charStringToString(*it));
180 s.push_back('"');
181 }
182
183 return (s);
184 }
185
196 int
197 compare(const TXTLikeImpl& other) const {
198 // This implementation is not efficient. Revisit this (TBD).
199 util::OutputBuffer this_buffer(0);
200 toWire(this_buffer);
201 uint8_t const* const this_data = (uint8_t const*)this_buffer.getData();
202 const size_t this_len = this_buffer.getLength();
203
204 util::OutputBuffer other_buffer(0);
205 other.toWire(other_buffer);
206 uint8_t const* const other_data
207 = (uint8_t const*)other_buffer.getData();
208 const size_t other_len = other_buffer.getLength();
209
210 const size_t cmplen = std::min(this_len, other_len);
211 const int cmp = memcmp(this_data, other_data, cmplen);
212
213 if (cmp != 0) {
214 return (cmp);
215 } else {
216 return ((this_len == other_len) ? 0 :
217 (this_len < other_len) ? -1 : 1);
218 }
219 }
220
221 private:
224 std::vector<std::vector<uint8_t> > string_list_;
225};
226
227} // namespace detail
228} // namespace generic
229} // namespace rdata
230} // namespace dns
231} // namespace isc
232
233#endif // TXT_LIKE_H
char_string.h
isc::Exception::what
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
Definition exceptions/exceptions.cc:32
isc::dns::AbstractMessageRenderer
The AbstractMessageRenderer class is an abstract base class that provides common interfaces for rende...
Definition messagerenderer.h:69
isc::dns::AbstractMessageRenderer::writeData
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the internal buffer of the renderer object.
Definition messagerenderer.h:310
isc::dns::DNSMessageFORMERR
Definition dns/exceptions.h:56
isc::dns::MasterLexer::LexerError
Exception thrown from a wrapper version of MasterLexer::getNextToken() for non fatal errors.
Definition master_lexer.h:322
isc::dns::MasterLexer
Tokenizer for parsing DNS master files.
Definition master_lexer.h:303
isc::dns::MasterLexer::ungetToken
void ungetToken()
Return the last token back to the lexer.
isc::dns::MasterLexer::pushSource
bool pushSource(const char *filename, std::string *error=0)
Open a file and make it the current input source of MasterLexer.
isc::dns::MasterLexer::getNextToken
const MasterToken & getNextToken(Options options=NONE)
Parse and return another token from the input.
isc::dns::MasterToken
Tokens for MasterLexer.
Definition master_lexer.h:40
isc::dns::MasterToken::STRING
@ STRING
A single string.
Definition master_lexer.h:57
isc::dns::MasterToken::QSTRING
@ QSTRING
A single string quoted by double-quotes (").
Definition master_lexer.h:58
isc::dns::MasterToken::END_OF_FILE
@ END_OF_FILE
End of file detected.
Definition master_lexer.h:50
isc::dns::MasterToken::getType
Type getType() const
Return the token type.
Definition master_lexer.h:157
isc::dns::MasterToken::getStringRegion
const StringRegion & getStringRegion() const
Return the value of a string-variant token.
Definition master_lexer.h:166
isc::dns::RRType
The RRType class encapsulates DNS resource record types.
Definition rrtype.h:96
isc::dns::rdata::InvalidRdataLength
A standard DNS module exception that is thrown if RDATA parser encounters an invalid or inconsistent ...
Definition rdata.h:34
isc::dns::rdata::InvalidRdataText
A standard DNS module exception that is thrown if RDATA parser fails to recognize a given textual rep...
Definition rdata.h:44
isc::dns::rdata::generic::detail::TXTLikeImpl::TXTLikeImpl
TXTLikeImpl(const TXTLikeImpl &other)
The copy constructor.
Definition txt_like.h:130
isc::dns::rdata::generic::detail::TXTLikeImpl::TXTLikeImpl
TXTLikeImpl(util::InputBuffer &buffer, size_t rdata_len)
Constructor from wire-format data.
Definition txt_like.h:43
isc::dns::rdata::generic::detail::TXTLikeImpl::compare
int compare(const TXTLikeImpl &other) const
Compare two instances of TXT-like RDATA.
Definition txt_like.h:197
isc::dns::rdata::generic::detail::TXTLikeImpl::toText
std::string toText() const
Convert the TXT-like data to a string.
Definition txt_like.h:169
isc::dns::rdata::generic::detail::TXTLikeImpl::TXTLikeImpl
TXTLikeImpl(const std::string &txtstr)
Constructor from string.
Definition txt_like.h:74
isc::dns::rdata::generic::detail::TXTLikeImpl::TXTLikeImpl
TXTLikeImpl(MasterLexer &lexer)
Constructor using the master lexer.
Definition txt_like.h:100
isc::dns::rdata::generic::detail::TXTLikeImpl::toWire
void toWire(util::OutputBuffer &buffer) const
Render the TXT-like data in the wire format to an OutputBuffer object.
Definition txt_like.h:139
isc::dns::rdata::generic::detail::TXTLikeImpl::toWire
void toWire(AbstractMessageRenderer &renderer) const
Render the TXT-like data in the wire format to an AbstractMessageRenderer object.
Definition txt_like.h:155
isc::util::InputBuffer
The InputBuffer class is a buffer abstraction for manipulating read-only data.
Definition buffer.h:81
isc::util::InputBuffer::readUint8
uint8_t readUint8()
Read an unsigned 8-bit integer from the buffer and return it.
Definition buffer.h:138
isc::util::InputBuffer::readData
void readData(void *data, size_t len)
Read data of the specified length from the buffer and copy it to the caller supplied buffer.
Definition buffer.h:226
isc::util::OutputBuffer
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition buffer.h:346
isc::util::OutputBuffer::writeData
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition buffer.h:559
isc::util::OutputBuffer::getData
const uint8_t * getData() const
Return a pointer to the head of the data stored in the buffer.
Definition buffer.h:398
isc::util::OutputBuffer::getLength
size_t getLength() const
Return the length of data written in the buffer.
Definition buffer.h:412
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
master_lexer.h
isc::data
Definition base_stamped_element.cc:12
isc::dns::rdata::generic::detail
Definition char_string.cc:29
isc::dns::rdata::generic::detail::charStringToString
std::string charStringToString(const CharString &char_string)
Convert a CharString into a textual DNS character-string.
Definition char_string.cc:121
isc::dns::rdata::generic::detail::stringToCharString
void stringToCharString(const MasterToken::StringRegion &str_region, CharString &result)
Convert a DNS character-string into corresponding binary data.
Definition char_string.cc:55
isc::dns::rdata::generic
Definition char_string.cc:28
isc::dns::rdata
Definition char_string.cc:27
isc::dns::rdata::MAX_RDLENGTH
const size_t MAX_RDLENGTH
Possible maximum length of RDATA, which is the maximum unsigned 16 bit value.
Definition rdata.h:73
isc::dns
Definition char_string.cc:26
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148