| Kea 3.0.2-git

buffer.h
Go to the documentation of this file.
1// Copyright (C) 2009-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 BUFFER_H
8#define BUFFER_H
9
10#include <exceptions/exceptions.h>
11
12#include <cstdint>
13#include <cstdlib>
14#include <cstring>
15#include <vector>
16
17#include <boost/shared_ptr.hpp>
18
19 namespace isc {
20 namespace util {
21
81 class InputBuffer {
82 public:
90 InputBuffer(const void* data, size_t len)
91 : base_(static_cast<const uint8_t*>(data)), current_(base_),
92 end_(base_ + len) {
93 }
94
96 size_t getLength() const {
97 return (static_cast<size_t>(end_ - base_));
98 }
99
101 size_t getPosition() const {
102 return (static_cast<size_t>(current_ - base_));
103 }
104
112 void setPosition(size_t position) {
113 if (base_ + position > end_) {
114 isc_throw(OutOfRange,
115 "InputBuffer::setPosition position is too large");
116 }
117
118 current_ = base_ + position;
119 }
120
125 uint8_t peekUint8() {
126 if (current_ + sizeof(uint8_t) > end_) {
127 isc_throw(OutOfRange,
128 "InputBuffer::peekUint8 read beyond end of buffer");
129 }
130
131 return (*current_);
132 }
133
138 uint8_t readUint8() {
139 uint8_t ret = peekUint8();
140 current_ += sizeof(uint8_t);
141
142 return (ret);
143 }
144
149 uint16_t peekUint16() {
150 if (current_ + sizeof(uint16_t) > end_) {
151 isc_throw(OutOfRange,
152 "InputBuffer::peekUint16 read beyond end of buffer");
153 }
154
155 uint16_t ret;
156 ret = (static_cast<uint16_t>(current_[0])) << 8;
157 ret |= (static_cast<uint16_t>(current_[1]));
158
159 return (ret);
160 }
161
166 uint16_t readUint16() {
167 uint16_t ret = peekUint16();
168 current_ += sizeof(uint16_t);
169
170 return (ret);
171 }
172
177 uint32_t peekUint32() {
178 if (current_ + sizeof(uint32_t) > end_) {
179 isc_throw(OutOfRange,
180 "InputBuffer::peekUint32 read beyond end of buffer");
181 }
182
183 uint32_t ret;
184 ret = (static_cast<uint32_t>(current_[0])) << 24;
185 ret |= (static_cast<uint32_t>(current_[1])) << 16;
186 ret |= (static_cast<uint32_t>(current_[2])) << 8;
187 ret |= (static_cast<uint32_t>(current_[3]));
188
189 return (ret);
190 }
191
196 uint32_t readUint32() {
197 uint32_t ret = peekUint32();
198 current_ += sizeof(uint32_t);
199
200 return (ret);
201 }
202
210 void peekData(void* data, size_t len) {
211 if (current_ + len > end_) {
212 isc_throw(OutOfRange,
213 "InputBuffer::peekData read beyond end of buffer");
214 }
215
216 static_cast<void>(std::memmove(data, current_, len));
217 }
218
226 void readData(void* data, size_t len) {
227 peekData(data, len);
228 current_ += len;
229 }
230
241 void peekVector(std::vector<uint8_t>& data, size_t len) {
242 if (current_ + len > end_) {
243 isc_throw(OutOfRange,
244 "InputBuffer::peekVector read beyond end of buffer");
245 }
246
247 data.resize(len);
248 if (len) {
249 peekData(&data[0], len);
250 }
251 }
252
262 void readVector(std::vector<uint8_t>& data, size_t len) {
263 peekVector(data, len);
264 current_ += len;
265 }
266
267 private:
269 const uint8_t* base_;
270
272 const uint8_t* current_;
273
275 const uint8_t* end_;
276};
277
279 typedef boost::shared_ptr<InputBuffer> InputBufferPtr;
280
346 class OutputBuffer {
347 public:
351 explicit OutputBuffer(size_t len) : buffer_() {
352 if (len != 0) {
353 buffer_.reserve(len);
354 }
355 }
356
360 OutputBuffer(const OutputBuffer& other) : buffer_(other.buffer_) {
361 size_t len = other.buffer_.capacity();
362 if (len != 0) {
363 buffer_.reserve(len);
364 }
365 }
366
368 ~OutputBuffer() = default;
369
373 OutputBuffer& operator=(const OutputBuffer& other) {
374 if (this != &other) {
375 // Not self-assignment.
376 buffer_ = other.buffer_;
377 size_t len = other.buffer_.capacity();
378 if (len != 0) {
379 buffer_.reserve(len);
380 }
381 }
382
383 return (*this);
384 }
385
387 size_t getCapacity() const {
388 return (buffer_.capacity());
389 }
390
398 const uint8_t* getData() const {
399 if (!buffer_.empty()) {
400 return (&buffer_[0]);
401 } else {
402 return (0);
403 }
404 }
405
407 const void* getDataAsVoidPtr() const {
408 return (static_cast<const void*>(getData()));
409 }
410
412 size_t getLength() const {
413 return (buffer_.size());
414 }
415
423 uint8_t operator[](size_t position) const {
424 if (position >= buffer_.size()) {
425 isc_throw(OutOfRange,
426 "OutputBuffer::[]: pos (" << position
427 << ") >= size (" << buffer_.size() << ")");
428 }
429
430 return (buffer_[position]);
431 }
432
436 const std::vector<uint8_t>& getVector() const {
437 return (buffer_);
438 }
439
448 void skip(size_t len) {
449 buffer_.resize(buffer_.size() + len);
450 }
451
459 void trim(size_t len) {
460 if (len > buffer_.size()) {
461 isc_throw(OutOfRange,
462 "OutputBuffer::trim length too large from output buffer");
463 }
464
465 buffer_.resize(buffer_.size() - len);
466 }
467
469 void clear() {
470 buffer_.clear();
471 }
472
476 void writeUint8(uint8_t data) {
477 buffer_.push_back(data);
478 }
479
488 void writeUint8At(uint8_t data, size_t position) {
489 if (position + sizeof(data) > buffer_.size()) {
490 isc_throw(OutOfRange,
491 "OutputBuffer::writeUint8At write at invalid position");
492 }
493
494 buffer_[position] = data;
495 }
496
501 void writeUint16(uint16_t data) {
502 buffer_.push_back(static_cast<uint8_t>((data & 0xff00U) >> 8));
503 buffer_.push_back(static_cast<uint8_t>(data & 0x00ffU));
504 }
505
517 void writeUint16At(uint16_t data, size_t position) {
518 if (position + sizeof(data) > buffer_.size()) {
519 isc_throw(OutOfRange,
520 "OutputBuffer::writeUint16At write at invalid position");
521 }
522
523 buffer_[position] = static_cast<uint8_t>((data & 0xff00U) >> 8);
524 buffer_[position + 1] = static_cast<uint8_t>(data & 0x00ffU);
525 }
526
531 void writeUint32(uint32_t data) {
532 buffer_.push_back(static_cast<uint8_t>((data & 0xff000000) >> 24));
533 buffer_.push_back(static_cast<uint8_t>((data & 0x00ff0000) >> 16));
534 buffer_.push_back(static_cast<uint8_t>((data & 0x0000ff00) >> 8));
535 buffer_.push_back(static_cast<uint8_t>(data & 0x000000ff));
536 }
537
542 void writeUint64(uint64_t data) {
543 buffer_.push_back(static_cast<uint8_t>((data & 0xff00000000000000) >> 56));
544 buffer_.push_back(static_cast<uint8_t>((data & 0x00ff000000000000) >> 48));
545 buffer_.push_back(static_cast<uint8_t>((data & 0x0000ff0000000000) >> 40));
546 buffer_.push_back(static_cast<uint8_t>((data & 0x000000ff00000000) >> 32));
547 buffer_.push_back(static_cast<uint8_t>((data & 0x00000000ff000000) >> 24));
548 buffer_.push_back(static_cast<uint8_t>((data & 0x0000000000ff0000) >> 16));
549 buffer_.push_back(static_cast<uint8_t>((data & 0x000000000000ff00) >> 8));
550 buffer_.push_back(static_cast<uint8_t>(data & 0x00000000000000ff));
551 }
552
559 void writeData(const void* data, size_t len) {
560 if (len == 0) {
561 return;
562 }
563
564 const uint8_t* ptr = static_cast<const uint8_t*>(data);
565 buffer_.insert(buffer_.end(), ptr, ptr + len);
566 }
567
568 private:
570 std::vector<uint8_t> buffer_;
571};
572
574 typedef boost::shared_ptr<OutputBuffer> OutputBufferPtr;
575
576} // namespace util
577} // namespace isc
578
579#endif // BUFFER_H
isc::OutOfRange
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
Definition exceptions/exceptions.h:115
isc::util::InputBuffer::readVector
void readVector(std::vector< uint8_t > &data, size_t len)
Read specified number of bytes as a vector.
Definition buffer.h:262
isc::util::InputBuffer::peekUint8
uint8_t peekUint8()
Peek an unsigned 8-bit integer from the buffer and return it.
Definition buffer.h:125
isc::util::InputBuffer::peekUint16
uint16_t peekUint16()
Peek an unsigned 16-bit integer in network byte order from the buffer, and return it.
Definition buffer.h:149
isc::util::InputBuffer::InputBuffer
InputBuffer(const void *data, size_t len)
Constructor.
Definition buffer.h:90
isc::util::InputBuffer::readUint32
uint32_t readUint32()
Read an unsigned 32-bit integer in network byte order from the buffer, and return it.
Definition buffer.h:196
isc::util::InputBuffer::setPosition
void setPosition(size_t position)
Set the read position of the buffer to the given value.
Definition buffer.h:112
isc::util::InputBuffer::getPosition
size_t getPosition() const
Return the current read position.
Definition buffer.h:101
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::peekData
void peekData(void *data, size_t len)
Peek data of the specified length from the buffer and copy it to the caller supplied buffer.
Definition buffer.h:210
isc::util::InputBuffer::peekUint32
uint32_t peekUint32()
Read an unsigned 32-bit integer in network byte order from the buffer, and return it.
Definition buffer.h:177
isc::util::InputBuffer::getLength
size_t getLength() const
Return the length of the data stored in the buffer.
Definition buffer.h:96
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::InputBuffer::peekVector
void peekVector(std::vector< uint8_t > &data, size_t len)
Peek specified number of bytes as a vector.
Definition buffer.h:241
isc::util::InputBuffer::readUint16
uint16_t readUint16()
Read an unsigned 16-bit integer in network byte order from the buffer, and return it.
Definition buffer.h:166
isc::util::OutputBuffer::operator=
OutputBuffer & operator=(const OutputBuffer &other)
Assignment operator.
Definition buffer.h:373
isc::util::OutputBuffer::~OutputBuffer
~OutputBuffer()=default
Destructor.
isc::util::OutputBuffer::writeUint64
void writeUint64(uint64_t data)
Write an unsigned 64-bit integer in host byte order into the buffer in network byte order.
Definition buffer.h:542
isc::util::OutputBuffer::OutputBuffer
OutputBuffer(const OutputBuffer &other)
Copy constructor.
Definition buffer.h:360
isc::util::OutputBuffer::writeUint8
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
Definition buffer.h:476
isc::util::OutputBuffer::writeUint16
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:501
isc::util::OutputBuffer::getDataAsVoidPtr
const void * getDataAsVoidPtr() const
Return data as a pointer to void.
Definition buffer.h:407
isc::util::OutputBuffer::writeUint16At
void writeUint16At(uint16_t data, size_t position)
Write an unsigned 16-bit integer in host byte order at the specified position of the buffer in networ...
Definition buffer.h:517
isc::util::OutputBuffer::operator[]
uint8_t operator[](size_t position) const
Return the value of the buffer at the specified position.
Definition buffer.h:423
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::writeUint32
void writeUint32(uint32_t data)
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order.
Definition buffer.h:531
isc::util::OutputBuffer::trim
void trim(size_t len)
Trim the specified length of data from the end of the buffer.
Definition buffer.h:459
isc::util::OutputBuffer::OutputBuffer
OutputBuffer(size_t len)
Constructor.
Definition buffer.h:351
isc::util::OutputBuffer::skip
void skip(size_t len)
Insert a specified length of gap at the end of the buffer.
Definition buffer.h:448
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::util::OutputBuffer::clear
void clear()
Clear buffer content.
Definition buffer.h:469
isc::util::OutputBuffer::getCapacity
size_t getCapacity() const
Return the current capacity of the buffer.
Definition buffer.h:387
isc::util::OutputBuffer::writeUint8At
void writeUint8At(uint8_t data, size_t position)
Write an unsigned 8-bit integer into the buffer.
Definition buffer.h:488
isc::util::OutputBuffer::getVector
const std::vector< uint8_t > & getVector() const
Return the buffer.
Definition buffer.h:436
exceptions.h
isc_throw
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Definition exceptions/exceptions.h:210
isc::data
Definition base_stamped_element.cc:12
isc::util
Definition time_utils.cc:43
isc::util::InputBufferPtr
boost::shared_ptr< InputBuffer > InputBufferPtr
Type of pointers to input buffer.
Definition buffer.h:279
isc::util::OutputBufferPtr
boost::shared_ptr< OutputBuffer > OutputBufferPtr
Type of pointers to output buffers.
Definition buffer.h:574
isc
Defines the logger used by the top-level component of kea-lfc.
Definition agent_parser.cc:148