Kea 2.7.5
opaque_data_tuple.cc
Go to the documentation of this file.
1// Copyright (C) 2014-2024 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#include <util/io.h>
11
12namespace isc {
13namespace dhcp {
14
16 : length_field_type_(length_field_type) {
17}
18
19void
20OpaqueDataTuple::append(const std::string& text) {
21 // Don't do anything if text is empty.
22 if (!text.empty()) {
23 append(&text[0], text.size());
24 }
25}
26
27void
28OpaqueDataTuple::assign(const std::string& text) {
29 // If empty string is being assigned, reset the buffer.
30 if (text.empty()) {
31 clear();
32 } else {
33 assign(&text[0], text.size());
34 }
35}
36
37void
39 data_.clear();
40}
41
42bool
43OpaqueDataTuple::equals(const std::string& other) const {
44 return (getText() == other);
45}
46
47std::string
49 // Convert the data carried in the buffer to a string.
50 return (std::string(data_.begin(), data_.end()));
51}
52
53void
55 if ((1 << (getDataFieldSize() * 8)) <= getLength()) {
56 isc_throw(OpaqueDataTupleError, "failed to create on-wire format of the"
57 " opaque data field, because current data length "
58 << getLength() << " exceeds the maximum size for the length"
59 << " field size " << getDataFieldSize());
60 }
61
62 if (getDataFieldSize() == 1) {
63 buf.writeUint8(static_cast<uint8_t>(getLength()));
64 } else {
65 buf.writeUint16(getLength());
66 }
67
68 if (getLength() > 0) {
69 buf.writeData(&getData()[0], getLength());
70 }
71}
72
73int
75 return (length_field_type_ == LENGTH_1_BYTE ? 1 : 2);
76}
77
79OpaqueDataTuple::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
85bool
86OpaqueDataTuple::operator==(const std::string& other) const {
87 return (equals(other));
88}
89
90bool
91OpaqueDataTuple::operator!=(const std::string& other) {
92 return (!equals(other));
93}
94
95std::ostream& operator<<(std::ostream& os, const OpaqueDataTuple& tuple) {
96 os << tuple.getText();
97 return (os);
98}
99
100std::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
116void
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
Exception to be thrown when the operation on OpaqueDataTuple object results in an error.
Represents a single instance of the opaque data preceded by length.
bool operator==(const std::string &other) const
Equality operator.
void clear()
Removes the contents of the tuple.
int getDataFieldSize() const
Returns the size of the tuple length field.
OpaqueDataTuple & operator=(const std::string &other)
Assignment operator.
OpaqueDataTuple(LengthFieldType length_field_type)
Default constructor.
const Buffer & getData() const
Returns a reference to the buffer holding tuple data.
LengthFieldType
Size of the length field in the tuple.
void pack(isc::util::OutputBuffer &buf) const
Renders the tuple to a buffer in the wire format.
Buffer::const_iterator InputIterator
void assign(const char *data, const size_t len)
Assigns data to the tuple.
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.
bool equals(const std::string &other) const
Checks if the data carried in the tuple match the string.
void unpack(InputIterator begin, InputIterator end)
Parses wire data and creates a tuple from it.
bool operator!=(const std::string &other)
Inequality operator.
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:490
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition buffer.h:343
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::istream & operator>>(std::istream &is, OpaqueDataTuple &tuple)
Inserts data carried in the stream into the tuple.
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
Definition io.h:76
Defines the logger used by the top-level component of kea-lfc.