Kea  2.1.7-git
opaque_data_tuple.cc
Go to the documentation of this file.
1 // Copyright (C) 2014-2022 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 ((1 << (getDataFieldSize() * 8)) <= getLength()) {
55  isc_throw(OpaqueDataTupleError, "failed to create on-wire format of the"
56  " opaque data field, because current data length "
57  << getLength() << " exceeds the maximum size for the length"
58  << " field size " << getDataFieldSize());
59  }
60 
61  if (getDataFieldSize() == 1) {
62  buf.writeUint8(static_cast<uint8_t>(getLength()));
63  } else {
64  buf.writeUint16(getLength());
65  }
66 
67  if (getLength() > 0) {
68  buf.writeData(&getData()[0], getLength());
69  }
70 }
71 
72 int
74  return (length_field_type_ == LENGTH_1_BYTE ? 1 : 2);
75 }
76 
78 OpaqueDataTuple::operator=(const std::string& other) {
79  // Replace existing data with the new data converted from a string.
80  assign(&other[0], other.length());
81  return (*this);
82 }
83 
84 bool
85 OpaqueDataTuple::operator==(const std::string& other) const {
86  return (equals(other));
87 }
88 
89 bool
90 OpaqueDataTuple::operator!=(const std::string& other) {
91  return (!equals(other));
92 }
93 
94 std::ostream& operator<<(std::ostream& os, const OpaqueDataTuple& tuple) {
95  os << tuple.getText();
96  return (os);
97 }
98 
99 std::istream& operator>>(std::istream& is, OpaqueDataTuple& tuple) {
100  // We will replace the current data with new data.
101  tuple.clear();
102  char buf[256];
103  // Read chunks of data as long as we haven't reached the end of the stream.
104  while (!is.eof()) {
105  is.read(buf, sizeof(buf));
106  // Append the chunk of data we have just read. It is fine if the
107  // gcount is 0, because append() function will check that.
108  tuple.append(buf, is.gcount());
109  }
110  // Clear eof flag, so as the stream can be read again.
111  is.clear();
112  return (is);
113 }
114 
115 void
117  // The buffer must at least hold the size of the data.
118  if (std::distance(begin, end) < getDataFieldSize()) {
120  "unable to parse the opaque data tuple, the buffer"
121  " length is " << std::distance(begin, end)
122  << ", expected at least " << getDataFieldSize());
123  }
124  // Read the data length from the length field, depending on the
125  // size of the data field (1 or 2 bytes).
126  size_t len = getDataFieldSize() == 1 ? *begin :
127  isc::util::readUint16(&(*begin), std::distance(begin, end));
128  // Now that we have the expected data size, let's check that the
129  // reminder of the buffer is long enough.
130  begin += getDataFieldSize();
131  // Attempt to parse as a length-value pair.
132  if (std::distance(begin, end) < len) {
134  // Fallback to parsing the rest of the option as a single value.
135  len = std::distance(begin, end);
136  } else {
138  "unable to parse the opaque data tuple, "
139  "the buffer length is " << std::distance(begin, end)
140  << ", but the tuple length is " << len);
141  }
142  }
143  // The buffer length is long enough to read the desired amount of data.
144  assign(begin, len);
145 }
146 
147 } // namespace dhcp
148 } // namespace isc
OpaqueDataTuple & operator=(const std::string &other)
Assignment operator.
Buffer::const_iterator InputIterator
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 pack(isc::util::OutputBuffer &buf) const
Renders the tuple to a buffer in the wire format.
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.
std::string getText() const
Return the tuple data in the textual 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.
bool equals(const std::string &other) const
Checks if the data carried in the tuple match the string.
Defines the logger used by the top-level component of kea-lfc.
int getDataFieldSize() const
Returns the size of the tuple length field.
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.
bool operator==(const std::string &other) const
Equality operator.
static bool lenient_parsing_
Governs whether options should be parsed less strictly.
Definition: option.h:483
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...