Kea 2.5.8
buffer.h
Go to the documentation of this file.
1// Copyright (C) 2009-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#ifndef BUFFER_H
8#define BUFFER_H
9
11
12#include <cstdint>
13#include <cstdlib>
14#include <cstring>
15#include <vector>
16
17#include <boost/shared_ptr.hpp>
18
19namespace isc {
20namespace util {
21
82public:
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_) {
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_) {
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_) {
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_) {
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_) {
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
240 void peekVector(std::vector<uint8_t>& data, size_t len) {
241 if (current_ + len > end_) {
243 "InputBuffer::peekVector read beyond end of buffer");
244 }
245
246 data.resize(len);
247 peekData(&data[0], len);
248 }
249
259 void readVector(std::vector<uint8_t>& data, size_t len) {
260 peekVector(data, len);
261 current_ += len;
262 }
263
264private:
266 const uint8_t* base_;
267
269 const uint8_t* current_;
270
272 const uint8_t* end_;
273};
274
276typedef boost::shared_ptr<InputBuffer> InputBufferPtr;
277
344public:
348 explicit OutputBuffer(size_t len) : buffer_() {
349 if (len != 0) {
350 buffer_.reserve(len);
351 }
352 }
353
357 OutputBuffer(const OutputBuffer& other) : buffer_(other.buffer_) {
358 size_t len = other.buffer_.capacity();
359 if (len != 0) {
360 buffer_.reserve(len);
361 }
362 }
363
365 ~OutputBuffer() = default;
366
371 if (this != &other) {
372 // Not self-assignment.
373 buffer_ = other.buffer_;
374 size_t len = other.buffer_.capacity();
375 if (len != 0) {
376 buffer_.reserve(len);
377 }
378 }
379
380 return (*this);
381 }
382
384 size_t getCapacity() const {
385 return (buffer_.capacity());
386 }
387
395 const uint8_t* getData() const {
396 if (!buffer_.empty()) {
397 return (&buffer_[0]);
398 } else {
399 return (0);
400 }
401 }
402
404 const void* getDataAsVoidPtr() const {
405 return (static_cast<const void*>(getData()));
406 }
407
409 size_t getLength() const {
410 return (buffer_.size());
411 }
412
420 uint8_t operator[](size_t position) const {
421 if (position >= buffer_.size()) {
423 "OutputBuffer::[]: pos (" << position
424 << ") >= size (" << buffer_.size() << ")");
425 }
426
427 return (buffer_[position]);
428 }
429
433 const std::vector<uint8_t>& getVector() const {
434 return (buffer_);
435 }
436
445 void skip(size_t len) {
446 buffer_.resize(buffer_.size() + len);
447 }
448
456 void trim(size_t len) {
457 if (len > buffer_.size()) {
459 "OutputBuffer::trim length too large from output buffer");
460 }
461
462 buffer_.resize(buffer_.size() - len);
463 }
464
466 void clear() {
467 buffer_.clear();
468 }
469
473 void writeUint8(uint8_t data) {
474 buffer_.push_back(data);
475 }
476
485 void writeUint8At(uint8_t data, size_t position) {
486 if (position + sizeof(data) > buffer_.size()) {
488 "OutputBuffer::writeUint8At write at invalid position");
489 }
490
491 buffer_[position] = data;
492 }
493
498 void writeUint16(uint16_t data) {
499 buffer_.push_back(static_cast<uint8_t>((data & 0xff00U) >> 8));
500 buffer_.push_back(static_cast<uint8_t>(data & 0x00ffU));
501 }
502
514 void writeUint16At(uint16_t data, size_t position) {
515 if (position + sizeof(data) > buffer_.size()) {
517 "OutputBuffer::writeUint16At write at invalid position");
518 }
519
520 buffer_[position] = static_cast<uint8_t>((data & 0xff00U) >> 8);
521 buffer_[position + 1] = static_cast<uint8_t>(data & 0x00ffU);
522 }
523
528 void writeUint32(uint32_t data) {
529 buffer_.push_back(static_cast<uint8_t>((data & 0xff000000) >> 24));
530 buffer_.push_back(static_cast<uint8_t>((data & 0x00ff0000) >> 16));
531 buffer_.push_back(static_cast<uint8_t>((data & 0x0000ff00) >> 8));
532 buffer_.push_back(static_cast<uint8_t>(data & 0x000000ff));
533 }
534
539 void writeUint64(uint64_t data) {
540 buffer_.push_back(static_cast<uint8_t>((data & 0xff00000000000000) >> 56));
541 buffer_.push_back(static_cast<uint8_t>((data & 0x00ff000000000000) >> 48));
542 buffer_.push_back(static_cast<uint8_t>((data & 0x0000ff0000000000) >> 40));
543 buffer_.push_back(static_cast<uint8_t>((data & 0x000000ff00000000) >> 32));
544 buffer_.push_back(static_cast<uint8_t>((data & 0x00000000ff000000) >> 24));
545 buffer_.push_back(static_cast<uint8_t>((data & 0x0000000000ff0000) >> 16));
546 buffer_.push_back(static_cast<uint8_t>((data & 0x000000000000ff00) >> 8));
547 buffer_.push_back(static_cast<uint8_t>(data & 0x00000000000000ff));
548 }
549
556 void writeData(const void* data, size_t len) {
557 if (len == 0) {
558 return;
559 }
560
561 const uint8_t* ptr = static_cast<const uint8_t*>(data);
562 buffer_.insert(buffer_.end(), ptr, ptr + len);
563 }
564
565private:
567 std::vector<uint8_t> buffer_;
568};
569
571typedef boost::shared_ptr<OutputBuffer> OutputBufferPtr;
572
573} // namespace util
574} // namespace isc
575
576#endif // BUFFER_H
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
The InputBuffer class is a buffer abstraction for manipulating read-only data.
Definition: buffer.h:81
void readVector(std::vector< uint8_t > &data, size_t len)
Read specified number of bytes as a vector.
Definition: buffer.h:259
uint8_t peekUint8()
Peek an unsigned 8-bit integer from the buffer and return it.
Definition: buffer.h:125
uint16_t peekUint16()
Peek an unsigned 16-bit integer in network byte order from the buffer, and return it.
Definition: buffer.h:149
InputBuffer(const void *data, size_t len)
Constructor.
Definition: buffer.h:90
uint32_t readUint32()
Read an unsigned 32-bit integer in network byte order from the buffer, and return it.
Definition: buffer.h:196
void setPosition(size_t position)
Set the read position of the buffer to the given value.
Definition: buffer.h:112
size_t getPosition() const
Return the current read position.
Definition: buffer.h:101
uint8_t readUint8()
Read an unsigned 8-bit integer from the buffer and return it.
Definition: buffer.h:138
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
uint32_t peekUint32()
Read an unsigned 32-bit integer in network byte order from the buffer, and return it.
Definition: buffer.h:177
size_t getLength() const
Return the length of the data stored in the buffer.
Definition: buffer.h:96
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
void peekVector(std::vector< uint8_t > &data, size_t len)
Peek specified number of bytes as a vector.
Definition: buffer.h:240
uint16_t readUint16()
Read an unsigned 16-bit integer in network byte order from the buffer, and return it.
Definition: buffer.h:166
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
Definition: buffer.h:343
OutputBuffer & operator=(const OutputBuffer &other)
Assignment operator.
Definition: buffer.h:370
~OutputBuffer()=default
Destructor.
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:539
OutputBuffer(const OutputBuffer &other)
Copy constructor.
Definition: buffer.h:357
void writeUint8(uint8_t data)
Write an unsigned 8-bit integer into the buffer.
Definition: buffer.h:473
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:498
const void * getDataAsVoidPtr() const
Return data as a pointer to void.
Definition: buffer.h:404
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:514
uint8_t operator[](size_t position) const
Return the value of the buffer at the specified position.
Definition: buffer.h:420
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
Definition: buffer.h:556
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:528
void trim(size_t len)
Trim the specified length of data from the end of the buffer.
Definition: buffer.h:456
OutputBuffer(size_t len)
Constructor.
Definition: buffer.h:348
void skip(size_t len)
Insert a specified length of gap at the end of the buffer.
Definition: buffer.h:445
const uint8_t * getData() const
Return a pointer to the head of the data stored in the buffer.
Definition: buffer.h:395
size_t getLength() const
Return the length of data written in the buffer.
Definition: buffer.h:409
void clear()
Clear buffer content.
Definition: buffer.h:466
size_t getCapacity() const
Return the current capacity of the buffer.
Definition: buffer.h:384
void writeUint8At(uint8_t data, size_t position)
Write an unsigned 8-bit integer into the buffer.
Definition: buffer.h:485
const std::vector< uint8_t > & getVector() const
Return the buffer.
Definition: buffer.h:433
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
boost::shared_ptr< InputBuffer > InputBufferPtr
Type of pointers to input buffer.
Definition: buffer.h:276
boost::shared_ptr< OutputBuffer > OutputBufferPtr
Type of pointers to output buffers.
Definition: buffer.h:571
Defines the logger used by the top-level component of kea-lfc.