/* * This file is part of LibParserUtils. * Licensed under the MIT License, * http://www.opensource.org/licenses/mit-license.php * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org> */ #include <string.h> #include <parserutils/utils/buffer.h> #define DEFAULT_SIZE (4096) /** * Create a memory buffer * * \param alloc Memory (de)allocation function * \param pw Pointer to client-specific private data * \param buffer Pointer to location to receive memory buffer * \return PARSERUTILS_OK on success, * PARSERUTILS_BADPARM on bad parameters, * PARSERUTILS_NOMEM on memory exhausion */parserutils_error parserutils_buffer_create(parserutils_alloc alloc, void *pw, parserutils_buffer **buffer){ parserutils_buffer *b; if (alloc == NULL || buffer == NULL) return PARSERUTILS_BADPARM; b = alloc(NULL, sizeof(parserutils_buffer), pw); if (b == NULL) return PARSERUTILS_NOMEM; b->data = alloc(NULL, DEFAULT_SIZE, pw); if (b->data == NULL) { alloc(b, 0, pw); return PARSERUTILS_NOMEM; } b->length = 0; b->allocated = DEFAULT_SIZE; b->alloc = alloc; b->pw = pw; *buffer = b; return PARSERUTILS_OK;} /** * Destroy a memory buffer * * \param buffer The buffer to destroy * \return PARSERUTILS_OK on success, appropriate error otherwise */parserutils_error parserutils_buffer_destroy(parserutils_buffer *buffer){ if (buffer == NULL) return PARSERUTILS_BADPARM; buffer->alloc(buffer->data, 0, buffer->pw); buffer->alloc(buffer, 0, buffer->pw); return PARSERUTILS_OK;} /** * Append data to a memory buffer * * \param buffer The buffer to append to * \param data The data to append * \param len The length, in bytes, of the data to append * \return PARSERUTILS_OK on success, appropriate error otherwise. */parserutils_error parserutils_buffer_append(parserutils_buffer *buffer, const uint8_t *data, size_t len){ while (len >= buffer->allocated - buffer->length) { parserutils_error error = parserutils_buffer_grow(buffer); if (error != PARSERUTILS_OK) return error; } memcpy(buffer->data + buffer->length, data, len); buffer->length += len; return PARSERUTILS_OK;} /** * Insert data into a memory buffer * * \param buffer The buffer to insert into * \param offset The offset into the buffer to insert at * \param data The data to insert * \param len The length, in bytes, of the data to insert * \return PARSERUTILS_OK on success, appropriate error otherwise */parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer, size_t offset, const uint8_t *data, size_t len){ if (offset > buffer->length) return PARSERUTILS_BADPARM; if (offset == buffer->length) return parserutils_buffer_append(buffer, data, len); while (len >= buffer->allocated - buffer->length) { parserutils_error error = parserutils_buffer_grow(buffer); if (error != PARSERUTILS_OK) return error; } memmove(buffer->data + buffer->length + len, buffer->data + offset, buffer->length - offset); memcpy(buffer->data + offset, data, len); buffer->length += len; return PARSERUTILS_OK;} /** * Discard a section of a memory buffer * * \param buffer The buffer to discard data from * \param offset The offset into the buffer of the start of the section * \param len The number of bytes to discard * \return PARSERUTILS_OK on success, appropriate error otherwise. */parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer, size_t offset, size_t len){ if (offset >= buffer->length || offset + len > buffer->length) return PARSERUTILS_BADPARM; memmove(buffer->data + offset, buffer->data + offset + len, buffer->length - len); buffer->length -= len; return PARSERUTILS_OK;} /** * Extend the amount of space allocated for a memory buffer * * \param buffer The buffer to extend * \return PARSERUTILS_OK on success, appropriate error otherwise. */parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer){ uint8_t *temp = buffer->alloc(buffer->data, buffer->allocated * 2, buffer->pw); if (temp == NULL) return PARSERUTILS_NOMEM; buffer->data = temp; buffer->allocated *= 2; return PARSERUTILS_OK;} parserutils_error parserutils_buffer_randomise(parserutils_buffer *buffer){#ifndef NDEBUG uint8_t *temp;#endif if (buffer == NULL) return PARSERUTILS_BADPARM; #ifndef NDEBUG temp = buffer->alloc(NULL, buffer->allocated, buffer->pw); if (temp == NULL) return PARSERUTILS_NOMEM; memcpy(temp, buffer->data, buffer->length); memset(buffer->data, 0xff, buffer->length); /* Leak the buffer's current data, so we don't reuse it */ /* buffer->alloc(buffer->data, 0, buffer->pw); */ buffer->data = temp;#endif return PARSERUTILS_OK;}
/*
* This file is part of LibParserUtils.
* Licensed under the MIT License,
* http://www.opensource.org/licenses/mit-license.php
* Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org>
*/
#include <string.h>
#include <parserutils/utils/buffer.h>
#define DEFAULT_SIZE (4096)
/**
* Create a memory buffer
*
* \param alloc Memory (de)allocation function
* \param pw Pointer to client-specific private data
* \param buffer Pointer to location to receive memory buffer
* \return PARSERUTILS_OK on success,
* PARSERUTILS_BADPARM on bad parameters,
* PARSERUTILS_NOMEM on memory exhausion
*/
parserutils_error parserutils_buffer_create(parserutils_alloc alloc, void *pw,
parserutils_buffer **buffer)
{
parserutils_buffer *b;
if (alloc == NULL || buffer == NULL)
return PARSERUTILS_BADPARM;
b = alloc(NULL, sizeof(parserutils_buffer), pw);
if (b == NULL)
return PARSERUTILS_NOMEM;
b->data = alloc(NULL, DEFAULT_SIZE, pw);
if (b->data == NULL) {
alloc(b, 0, pw);
return PARSERUTILS_NOMEM;
}
b->length = 0;
b->allocated = DEFAULT_SIZE;
b->alloc = alloc;
b->pw = pw;
*buffer = b;
return PARSERUTILS_OK;
}
/**
* Destroy a memory buffer
*
* \param buffer The buffer to destroy
* \return PARSERUTILS_OK on success, appropriate error otherwise
*/
parserutils_error parserutils_buffer_destroy(parserutils_buffer *buffer)
{
if (buffer == NULL)
return PARSERUTILS_BADPARM;
buffer->alloc(buffer->data, 0, buffer->pw);
buffer->alloc(buffer, 0, buffer->pw);
return PARSERUTILS_OK;
}
/**
* Append data to a memory buffer
*
* \param buffer The buffer to append to
* \param data The data to append
* \param len The length, in bytes, of the data to append
* \return PARSERUTILS_OK on success, appropriate error otherwise.
*/
parserutils_error parserutils_buffer_append(parserutils_buffer *buffer,
const uint8_t *data, size_t len)
{
while (len >= buffer->allocated - buffer->length) {
parserutils_error error = parserutils_buffer_grow(buffer);
if (error != PARSERUTILS_OK)
return error;
}
memcpy(buffer->data + buffer->length, data, len);
buffer->length += len;
return PARSERUTILS_OK;
}
/**
* Insert data into a memory buffer
*
* \param buffer The buffer to insert into
* \param offset The offset into the buffer to insert at
* \param data The data to insert
* \param len The length, in bytes, of the data to insert
* \return PARSERUTILS_OK on success, appropriate error otherwise
*/
parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer,
size_t offset, const uint8_t *data, size_t len)
{
if (offset > buffer->length)
return PARSERUTILS_BADPARM;
if (offset == buffer->length)
return parserutils_buffer_append(buffer, data, len);
while (len >= buffer->allocated - buffer->length) {
parserutils_error error = parserutils_buffer_grow(buffer);
if (error != PARSERUTILS_OK)
return error;
}
memmove(buffer->data + buffer->length + len,
buffer->data + offset, buffer->length - offset);
memcpy(buffer->data + offset, data, len);
buffer->length += len;
return PARSERUTILS_OK;
}
/**
* Discard a section of a memory buffer
*
* \param buffer The buffer to discard data from
* \param offset The offset into the buffer of the start of the section
* \param len The number of bytes to discard
* \return PARSERUTILS_OK on success, appropriate error otherwise.
*/
parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer,
size_t offset, size_t len)
{
if (offset >= buffer->length || offset + len > buffer->length)
return PARSERUTILS_BADPARM;
memmove(buffer->data + offset, buffer->data + offset + len,
buffer->length - len);
buffer->length -= len;
return PARSERUTILS_OK;
}
/**
* Extend the amount of space allocated for a memory buffer
*
* \param buffer The buffer to extend
* \return PARSERUTILS_OK on success, appropriate error otherwise.
*/
parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer)
{
uint8_t *temp = buffer->alloc(buffer->data,
buffer->allocated * 2, buffer->pw);
if (temp == NULL)
return PARSERUTILS_NOMEM;
buffer->data = temp;
buffer->allocated *= 2;
return PARSERUTILS_OK;
}
parserutils_error parserutils_buffer_randomise(parserutils_buffer *buffer)
{
#ifndef NDEBUG
uint8_t *temp;
#endif
if (buffer == NULL)
return PARSERUTILS_BADPARM;
#ifndef NDEBUG
temp = buffer->alloc(NULL, buffer->allocated, buffer->pw);
if (temp == NULL)
return PARSERUTILS_NOMEM;
memcpy(temp, buffer->data, buffer->length);
memset(buffer->data, 0xff, buffer->length);
/* Leak the buffer's current data, so we don't reuse it */
/* buffer->alloc(buffer->data, 0, buffer->pw); */
buffer->data = temp;
#endif
return PARSERUTILS_OK;
}