struct Buffer

#include "buffer.h"

Overview

The Buffer class provides a simple, file like mechanism that operates in memory. It is intended to provide a bridge between the wide variety of file and file like mechanisms commonly found in C and C++ libraries. The class itself provides an in memory buffer for read and write operations, and tracks the read and write position separately. A write past of the end of currently allocated memory results in the available buffer size being doubled. A selection of utility functions allows for reading and writing of buffers to sources such as system sockets, C files, C++ streams, and CURL handles. In most instances, client code will interact with buffers through the utility routines, rather than through member functions.

If the member variable own_data is set to false, then the buffer can not be grown, and the underlying storage space will not be cleaned up when the Buffer is deleted. This allows Buffer to be used to wrap storage space that is managed elsewhere, or that comes from other similar classes in other libraries. It is also useful when Buffer is wrapped around a static string.

Member Variables

VariablePurpose
char* dataData held in the buffer
size_t sizeAllocated size of data member
size_t rposPosition of the read head
size_t wposPosition of the write head
size_t lengthNumber of bytes the buffer contains
bool own_dataWhether or not this buffer objects owns the underlying data.

Constructor

Buffer(size_t sz = 32k)

Creates a new, empty, Buffer class, with an initial internal buffer size of sz. Defaults to 32k.

Buffer(char* str)

Buffer(std::string& str)

Creates a buffer, using the given string as the storage space. The write position is set to the end of the string, and the length is set to strlen(str). The resulting buffer can not be grown, and when it is deleted the string remains.

Buffer(void* d, size_t len)

Creates a buffer, using the given array of bytes as the storage space. The write position is set to len, as is the length of the buffer. The resulting buffer can not be grown, and when it is deleted the string remains.

Methods

bool put_data(const char* data, int length)

Copy length bytes from data into the buffer. Updates the read position accordingly, and expands the internal memory buffer as required. Returns true on success and false on failure.

bool put_string(const std::string& s)

Copy string s into the buffer, with the null terminator. Updates the read position accordingly, and expands the internal memory buffer as required. Returns true on success and false on failure.

char* fetch_data(size_t len)

If there are not at least len bytes from the current read position to the end of buffer this method returns NULL. Otherwise, the read pointer is advanced by len bytes and a pointer to the previous read position is returned. Note that the pointer returned by this routine is the same block the object instance uses to store data, and it is owned by the Buffer instance.

bool ensure_space(size_t len)

Ensures that the underlying internal buffer has at least len unused bytes. If len bytes are already available, nothing more is done. If len is not available, the buffer is doubled until len bytes are available. Mostly used by the provided write methods, client code will rarely need this method. Returns true on success and false on failure.

size_t copy_out(char* dest, size_t len)

This method copies up to len bytes from the current read position to dest. A null-terminator is not written. The number of bytes actually copied is returned.

char* get_line(void)

Reads from the buffer until the end of the buffer or a newline character is found. A null-terminated string is returned. Unlike fetch_data, this returned string is owned by the client and should be deleted (not freed) when the client is finished with it.

bool end(void) const

Returns true is the read pointer has reached the end of the buffer, false otherwise.

void rewind(void)

Rewinds both the read and write positions to the beginning of the buffer. The buffer contents are not affected.

void clear(void)

Clears the buffer, reseting read and write positions, and buffer contents.

bool seek(size_t pos)

Sets both the read and write position to pos.

bool put(char datum)

bool put(unsigned char datum)

bool put(int datum)

bool put(long datum)

bool put(bool datum)

bool put(double datum)

This group of methods writes the given value to the buffer. If necessary the internal buffer is expanded. Returns true on success and false on failure.

bool fetch(char&retval)

bool fetch(unsigned char& retval)

bool fetch(int& retval)

bool fetch(long& retval)

bool fetch(bool& retval)

bool fetch(double& retval)

This group of methods reads a value out of the buffer and into the provided variable. Returns true on success and false on failure.

int compare(Buffer* buffer)

Compare the buffer with another buffer, and return true if they are the same length and their contents match. Properties such as own_data, allocated size, and the position of the read and write heads are not compared.

Non-member Utility Functions

bool write_from_buffer(Buffer*, ostream& stream)

bool write_from_buffer(Buffer*, FILE* file)

bool write_from_buffer(Buffer*, int socket)

bool write_from_buffer(Buffer*, const char* filename)

These routines send the entire contents of the buffer to the given destination. Note that the version that takes an int works on any file descriptor, not just sockets.

Buffer* read_to_buffer(istream& stream)

Buffer* read_to_buffer(FILE* file)

Buffer* read_to_buffer(int socket)

Buffer* read_to_buffer(const char* filename)

These routines read from the given source and place the entire contents, up till end of file, in the buffer. Note that the version that takes an int works on any file descriptor, not just sockets.

Buffer* base64_encode(Buffer* src, Buffer* dest = NULL)

Encodes buffer src into base64 format, and returns a buffer containing the result. If the optional parameter dest is specified, this buffer is used as the destionation for the encoded data and will be returned on success. If dest is NULL a new Buffer object will be created to return the result. Returns NULL on failure.

Buffer* base64_decode(Buffer* src, Buffer* dest = NULL)

Decodes a buffer src in base64 data, returning a buffer with the unencoded data. If the optional parameter dest is specified, this buffer is used as the destionation for the decoded data and will be returned on success. If dest is NULL a new Buffer object will be created to return the result. Returns NULL on failure.

This method requires that LibUC be built with libcurl support.

Buffer* http_post_buffer(const char* url, Buffer* send, string& mime_type_returned, const char* mime_type_sent = NULL, const int timeout = -1)

This function does an HTTP POST request of the buffer send to given url. The mime_type of the resulting response is stored in mime_type_returned. If mime_type_sent is not provided, or is NULL, the HTTP POST request will be made with mime type "application/x-www-form-urlencoded", which is the type used when sending forms from a browser to a web server. Otherwise, the post request will be made using the given mime type. This can be useful when working with RESTful services. The buffer containing the servers response is returned. If timeout is allowed to default, the default timeout provided by the underlying CURL library will be used. Otherwise, timeout provides the timeout for the operation in seconds.

Buffer* http_get_buffer(const char* url, string& mime_type, const int timeout = -1)

This method requires that LibUC be built with libcurl support.

This function sends an HTTP GET to the specified URL, and returns the results in a buffer. The string mime_type is set to the mime_type of the data retrieved. If timeout is allowed to default, the default timeout provided by the underlying CURL library will be used. Otherwise, timeout provides the timeout for the operation in seconds.


Class BufferAdapter

#include "buffer_adapter.h"

Overview

The BufferAdapter class allows for Buffer objects to be stored in a UniversalContainer. See Extending UniversalContainer for a discussion of adapter classes in general. In practice, the buffer adapter class has been written such that as long as it is linked into your program you can use the two functions below to store and retrieve a buffer a into and out of a UniversalContainer. Attempting to serialize a container that holds a Buffer will result in an exception.

Methods

static UniversalContainer BufferAdapter::assign(Buffer* ptr)

Stores the given Buffer* to a new UniversalContainer and returns that container.

static Buffer* BufferAdapter::cast(UniversalContainer const& uc)

If passed a container holding a Buffer* this method will return the held Buffer*. If the container holds something else, an exception is thrown.