Kea  1.9.9-git
opaque_data_tuple.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2021 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 #include <config.h>
8 
10 
11 namespace isc {
12 namespace dhcp {
13 
15  : length_field_type_(length_field_type) {
16 }
17 
18 void
19 OpaqueDataTuple::append(const std::string& text) {
20  // Don't do anything if text is empty.
21  if (!text.empty()) {
22  append(&text[0], text.size());
23  }
24 }
25 
26 void
27 OpaqueDataTuple::assign(const std::string& text) {
28  // If empty string is being assigned, reset the buffer.
29  if (text.empty()) {
30  clear();
31  } else {
32  assign(&text[0], text.size());
33  }
34 }
35 
36 void
38  data_.clear();
39 }
40 
41 bool
42 OpaqueDataTuple::equals(const std::string& other) const {
43  return (getText() == other);
44 }
45 
46 std::string
48  // Convert the data carried in the buffer to a string.
49  return (std::string(data_.begin(), data_.end()));
50 }
51 
52 void
54  if (getLength() == 0) {
55  isc_throw(OpaqueDataTupleError, "failed to create on-wire format of the"
56  " opaque data field, because the field appears to be empty");
57  } else if ((1 << (getDataFieldSize() * 8)) <= getLength()) {
58  isc_throw(OpaqueDataTupleError, "failed to create on-wire format of the"
59  " opaque data field, because current data length "
60  << getLength() << " exceeds the maximum size for the length"
61  << " field size " << getDataFieldSize());
62  }
63 
64  if (getDataFieldSize() == 1) {
65  buf.writeUint8(static_cast<uint8_t>(getLength()));
66  } else {
67  buf.writeUint16(getLength());
68  }
69 
70  buf.writeData(&getData()[0], getLength());
71 }
72 
73 int
75  return (length_field_type_ == LENGTH_1_BYTE ? 1 : 2);
76 }
77 
79 OpaqueDataTuple::operator=(const std::string& other) {
80  // Replace existing data with the new data converted from a string.
81  assign(&other[0], other.length());
82  return (*this);
83 }
84 
85 bool
86 OpaqueDataTuple::operator==(const std::string& other) const {
87  return (equals(other));
88 }
89 
90 bool
91 OpaqueDataTuple::operator!=(const std::string& other) {
92  return (!equals(other));
93 }
94 
95 std::ostream& operator<<(std::ostream& os, const OpaqueDataTuple& tuple) {
96  os << tuple.getText();
97  return (os);
98 }
99 
100 std::istream& operator>>(std::istream& is, OpaqueDataTuple& tuple) {
101  // We will replace the current data with new data.
102  tuple.clear();
103  char buf[256];
104  // Read chunks of data as long as we haven't reached the end of the stream.
105  while (!is.eof()) {
106  is.read(buf, sizeof(buf));
107  // Append the chunk of data we have just read. It is fine if the
108  // gcount is 0, because append() function will check that.
109  tuple.append(buf, is.gcount());
110  }
111  // Clear eof flag, so as the stream can be read again.
112  is.clear();
113  return (is);
114 }
115 
116 void
118  // The buffer must at least hold the size of the data.
119  if (std::distance(begin, end) < getDataFieldSize()) {
121  "unable to parse the opaque data tuple, the buffer"
122  " length is " << std::distance(begin, end)
123  << ", expected at least " << getDataFieldSize());
124  }
125  // Read the data length from the length field, depending on the
126  // size of the data field (1 or 2 bytes).
127  size_t len = getDataFieldSize() == 1 ? *begin :
128  isc::util::readUint16(&(*begin), std::distance(begin, end));
129  // Now that we have the expected data size, let's check that the
130  // reminder of the buffer is long enough.
131  begin += getDataFieldSize();
132  // Attempt to parse as a length-value pair.
133  if (std::distance(begin, end) < len) {
135  // Fallback to parsing the rest of the option as a single value.
136  len = std::distance(begin, end);
137  } else {
139  "unable to parse the opaque data tuple, "
140  "the buffer length is " << std::distance(begin, end)
141  << ", but the tuple length is " << len);
142  }
143  }
144  // The buffer length is long enough to read the desired amount of data.
145  assign(begin, len);
146 }
147 
148 } // namespace dhcp
149 } // namespace isc
int getDataFieldSize() const
Returns the size of the tuple length field.
OpaqueDataTuple & operator=(const std::string &other)
Assignment operator.
Buffer::const_iterator InputIterator
bool equals(const std::string &other) const
Checks if the data carried in the tuple match the string.
std::string getText() const
Return the tuple data in the textual format.
bool operator!=(const std::string &other)
Inequality operator.
void assign(const char *data, const size_t len)
Assigns data to the tuple.
void unpack(InputIterator begin, InputIterator end)
Parses wire data and creates a tuple from it.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition: buffer.h:550
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
OpaqueDataTuple(LengthFieldType length_field_type)
Default constructor.
bool operator==(const std::string &other) const
Equality operator.
void pack(isc::util::OutputBuffer &buf) const
Renders the tuple to a buffer in the wire format.
void append(const char *data, const size_t len)
Appends data to the tuple.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:294
LengthFieldType
Size of the length field in the tuple.
Defines the logger used by the top-level component of kea-dhcp-ddns.
uint16_t readUint16(const void *buffer, size_t length)
Read Unsigned 16-Bit Integer from Buffer.
Definition: io_utilities.h:28
const Buffer & getData() const
Returns a reference to the buffer holding tuple data.
std::ostream & operator<<(std::ostream &os, const OpaqueDataTuple &tuple)
Inserts the OpaqueDataTuple as a string into stream.
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
Definition: buffer.h:466
Represents a single instance of the opaque data preceded by length.
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order...
Definition: buffer.h:490
size_t getLength() const
Returns the length of the data in the tuple.
static bool lenient_parsing_
Governs whether options should be parsed less strictly.
Definition: option.h:464
std::istream & operator>>(std::istream &is, OpaqueDataTuple &tuple)
Inserts data carried in the stream into the tuple.
void clear()
Removes the contents of the tuple.
Exception to be thrown when the operation on OpaqueDataTuple object results in an error...