The OutputBuffer
class is a buffer abstraction for manipulating mutable data.
More...
Public Member Functions | |
Constructors and Destructor | |
OutputBuffer (size_t len) | |
Constructor from the initial size of the buffer. | |
Getter Methods | |
size_t | getCapacity () const |
Return the current capacity of the buffer. | |
const void * | getData () const |
Return a pointer to the head of the data stored in the buffer. | |
size_t | getLength () const |
Return the length of data written in the buffer. | |
uint8_t | operator[] (size_t pos) const |
Return the value of the buffer at the specified position. | |
Methods for writing data into the buffer. | |
void | skip (size_t len) |
Insert a specified length of gap at the end of the buffer. | |
void | clear () |
Clear buffer content. | |
void | writeUint8 (uint8_t data) |
Write an unsigned 8-bit integer into the buffer. | |
void | writeUint16 (uint16_t data) |
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order. | |
void | writeUint16At (uint16_t data, size_t pos) |
Write an unsigned 16-bit integer in host byte order at the specified position of the buffer in network byte order. | |
void | writeUint32 (uint32_t data) |
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order. | |
void | writeData (const void *data, size_t len) |
Copy an arbitrary length of data into the buffer. |
The OutputBuffer
class is a buffer abstraction for manipulating mutable data.
The main purpose of this class is to provide a safe workplace for constructing wire-format data to be sent out to a network. Here, safe means that it automatically allocates necessary memory and avoid buffer overrun.
Like for the InputBuffer
class, applications normally use this class only in a limited situation. One common usage of this class for an application would be something like this:
OutputBuffer buffer(4096); // give a sufficiently large initial size // pass the buffer to a DNS message object to construct a wire-format // DNS message. struct sockaddr to; sendto(s, buffer.getData(), buffer.getLength(), 0, &to, sizeof(to));
where the getData()
method gives a reference to the internal memory region stored in the buffer
object. This is a suboptimal design in that it exposes an encapsulated "handle" of an object to its user. Unfortunately, there is no easy way to avoid this without involving expensive data copy if we want to use this object with a legacy API such as a BSD socket interface. And, indeed, this is one major purpose for this object. Applications should use this method only under such a special circumstance.
An OutputBuffer
class object automatically extends its memory region when data is written beyond the end of the current buffer. However, it will involve performance overhead such as reallocating more memory and copying data. It is therefore recommended to construct the buffer object with a sufficiently large initial size. The getCapacity()
method provides the current maximum size of data (including the portion already written) that can be written into the buffer without causing memory reallocation.
Methods for writing data into the buffer generally work like an output stream: it begins with the head of the buffer, and once some length of data is written into the buffer, the next write operation will take place from the end of the buffer. Other methods to emulate "random access" are also provided (e.g., writeUint16At()
). The normal write operations are normally exception-free as this class automatically extends the buffer when necessary. However, in extreme cases such as an attempt of writing multi-GB data, a separate exception (e.g., std::bad_alloc
) may be thrown by the system. This also applies to the constructor with a very large initial size.
isc::dns::OutputBuffer::OutputBuffer | ( | size_t | len | ) |
Constructor from the initial size of the buffer.
len | The initial length of the buffer in bytes. |
void isc::dns::OutputBuffer::clear | ( | ) |
Clear buffer content.
This method can be used to re-initialize and reuse the buffer without constructing a new one.
Referenced by isc::dns::MessageRenderer::writeName().
size_t isc::dns::OutputBuffer::getCapacity | ( | ) | const |
Return the current capacity of the buffer.
const void* isc::dns::OutputBuffer::getData | ( | ) | const |
Return a pointer to the head of the data stored in the buffer.
The caller can assume that the subsequent getLength()
bytes are identical to the stored data of the buffer.
Note: The pointer returned by this method may be invalidated after a subsequent write operation.
Referenced by isc::dns::MessageRenderer::writeName().
size_t isc::dns::OutputBuffer::getLength | ( | ) | const |
Return the length of data written in the buffer.
Referenced by isc::dns::MessageRenderer::writeName().
uint8_t isc::dns::OutputBuffer::operator[] | ( | size_t | pos | ) | const |
Return the value of the buffer at the specified position.
pos
must specify the valid position of the buffer; otherwise an exception class of InvalidBufferPosition
will be thrown.
pos | The position in the buffer to be returned. |
References dns_throw.
void isc::dns::OutputBuffer::skip | ( | size_t | len | ) |
Insert a specified length of gap at the end of the buffer.
The caller should not assume any particular value to be inserted. This method is provided as a shortcut to make a hole in the buffer that is to be filled in later, e.g, by writeUint16At().
len | The length of the gap to be inserted in bytes. |
void isc::dns::OutputBuffer::writeData | ( | const void * | data, | |
size_t | len | |||
) |
Copy an arbitrary length of data into the buffer.
No conversion on the copied data is performed.
data | A pointer to the data to be copied into the buffer. | |
len | The length of the data in bytes. |
Referenced by isc::dns::Name::toWire(), and isc::dns::MessageRenderer::writeName().
void isc::dns::OutputBuffer::writeUint16 | ( | uint16_t | data | ) |
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
data | The 16-bit integer to be written into the buffer. |
Referenced by isc::dns::MessageRenderer::writeName().
void isc::dns::OutputBuffer::writeUint16At | ( | uint16_t | data, | |
size_t | pos | |||
) |
Write an unsigned 16-bit integer in host byte order at the specified position of the buffer in network byte order.
The buffer must have a sufficient room to store the given data at the given position, that is, pos + 2 < getLength()
; otherwise an exception of class isc::dns::InvalidBufferPosition
will be thrown. Note also that this method never extends the buffer.
data | The 16-bit integer to be written into the buffer. | |
pos | The beginning position in the buffer to write the data. |
References dns_throw.
void isc::dns::OutputBuffer::writeUint32 | ( | uint32_t | data | ) |
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order.
data | The 32-bit integer to be written into the buffer. |
void isc::dns::OutputBuffer::writeUint8 | ( | uint8_t | data | ) |
Write an unsigned 8-bit integer into the buffer.
data | The 8-bit integer to be written into the buffer. |