diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | include/parserutils/utils/buffer.h | 3 | ||||
-rw-r--r-- | src/charset/codecs/codec_utf8.c | 4 | ||||
-rw-r--r-- | src/utils/buffer.c | 119 | ||||
-rw-r--r-- | src/utils/endian.h | 4 | ||||
-rw-r--r-- | test/cscodec-utf16.c | 3 |
7 files changed, 114 insertions, 22 deletions
@@ -1,3 +1,4 @@ build-* Makefile.config.override +src/charset/aliases.inc @@ -6,7 +6,7 @@ # Component settings COMPONENT := parserutils -COMPONENT_VERSION := 0.2.2 +COMPONENT_VERSION := 0.2.5 # Default to a static library COMPONENT_TYPE ?= lib-static diff --git a/include/parserutils/utils/buffer.h b/include/parserutils/utils/buffer.h index 9425070..5b8b793 100644 --- a/include/parserutils/utils/buffer.h +++ b/include/parserutils/utils/buffer.h @@ -18,6 +18,7 @@ extern "C" struct parserutils_buffer { + uint8_t *alloc; uint8_t *data; size_t length; size_t allocated; @@ -29,6 +30,8 @@ parserutils_error parserutils_buffer_destroy(parserutils_buffer *buffer); parserutils_error parserutils_buffer_append(parserutils_buffer *buffer, const uint8_t *data, size_t len); +parserutils_error parserutils_buffer_appendv(parserutils_buffer *buffer, + size_t count, ...); parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer, size_t offset, const uint8_t *data, size_t len); parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer, diff --git a/src/charset/codecs/codec_utf8.c b/src/charset/codecs/codec_utf8.c index 6117fe6..39bdb28 100644 --- a/src/charset/codecs/codec_utf8.c +++ b/src/charset/codecs/codec_utf8.c @@ -409,8 +409,8 @@ parserutils_error charset_utf8_codec_read_char(charset_utf8_codec *c, const uint8_t **source, size_t *sourcelen, uint8_t **dest, size_t *destlen) { - uint32_t ucs4; - size_t sucs4; + uint32_t ucs4 = 0; + size_t sucs4 = 0; parserutils_error error; /* Convert a single character */ diff --git a/src/utils/buffer.c b/src/utils/buffer.c index 716e67c..4b68923 100644 --- a/src/utils/buffer.c +++ b/src/utils/buffer.c @@ -6,6 +6,7 @@ */ #include <string.h> +#include <stdarg.h> #include <parserutils/utils/buffer.h> @@ -30,12 +31,13 @@ parserutils_error parserutils_buffer_create(parserutils_buffer **buffer) if (b == NULL) return PARSERUTILS_NOMEM; - b->data = malloc(DEFAULT_SIZE); - if (b->data == NULL) { + b->alloc = malloc(DEFAULT_SIZE); + if (b->alloc == NULL) { free(b); return PARSERUTILS_NOMEM; } + b->data = b->alloc; b->length = 0; b->allocated = DEFAULT_SIZE; @@ -55,13 +57,59 @@ parserutils_error parserutils_buffer_destroy(parserutils_buffer *buffer) if (buffer == NULL) return PARSERUTILS_BADPARM; - free(buffer->data); + free(buffer->alloc); free(buffer); return PARSERUTILS_OK; } /** + * Get current data offset within buffer's allocation. + * + * \param[in] buffer The buffer object. + * \return data offset in bytes. + */ +static inline size_t get_offset(parserutils_buffer *buffer) +{ + return buffer->data - buffer->alloc; +} + +/** + * Try moving the data to the start of the allocation. + * + * \param[in] buffer The buffer object. + */ +static inline void try_rebase(parserutils_buffer *buffer) +{ + if (get_offset(buffer) >= buffer->length) { + memcpy(buffer->alloc, buffer->data, buffer->length); + buffer->data = buffer->alloc; + } +} + +/** + * Ensure that the buffer has enough space at the end to add len bytes. + * + * \param[in] buffer The buffer object. + * \param[in] len Number of bytes to ensure there is space for. + * \return PARSERUTILS_OK on success, appropriate error otherwise. + */ +static inline parserutils_error ensure_space( + parserutils_buffer *buffer, + size_t len) +{ + try_rebase(buffer); + + while (len >= buffer->allocated - buffer->length - get_offset(buffer)) { + parserutils_error error = parserutils_buffer_grow(buffer); + if (error != PARSERUTILS_OK) + return error; + } + + return PARSERUTILS_OK; +} + +/** * Append data to a memory buffer * * \param buffer The buffer to append to @@ -72,11 +120,9 @@ parserutils_error parserutils_buffer_destroy(parserutils_buffer *buffer) 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; - } + parserutils_error error = ensure_space(buffer, len); + if (error != PARSERUTILS_OK) + return error; memcpy(buffer->data + buffer->length, data, len); @@ -86,6 +132,38 @@ parserutils_error parserutils_buffer_append(parserutils_buffer *buffer, } /** + * Append multiple data blocks to a memory buffer. + * + * Each data block must be passed as a pair of const uint8_t* and size_t + * + * \param buffer The buffer to append to + * \param count The number of data blocks to append + * \param ... The pairs of pointer and size + * \return PARSERUTILS_OK on success, appropriate error otherwise. +*/ +parserutils_error parserutils_buffer_appendv(parserutils_buffer *buffer, + size_t count, ...) +{ + va_list ap; + parserutils_error error = PARSERUTILS_OK; + const uint8_t *data; + size_t len; + + va_start(ap, count); + while (count > 0) { + data = va_arg(ap, const uint8_t *); + len = va_arg(ap, size_t); + error = parserutils_buffer_append(buffer, data, len); + if (error != PARSERUTILS_OK) + break; + count--; + } + va_end(ap); + + return error; +} + +/** * Insert data into a memory buffer * * \param buffer The buffer to insert into @@ -97,17 +175,17 @@ parserutils_error parserutils_buffer_append(parserutils_buffer *buffer, parserutils_error parserutils_buffer_insert(parserutils_buffer *buffer, size_t offset, const uint8_t *data, size_t len) { + parserutils_error error; + 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; - } + error = ensure_space(buffer, len); + if (error != PARSERUTILS_OK) + return error; memmove(buffer->data + offset + len, buffer->data + offset, buffer->length - offset); @@ -133,6 +211,13 @@ parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer, if (offset >= buffer->length || offset + len > buffer->length) return PARSERUTILS_BADPARM; + if (offset == 0) { + buffer->data += len; + buffer->length -= len; + try_rebase(buffer); + return PARSERUTILS_OK; + } + memmove(buffer->data + offset, buffer->data + offset + len, buffer->length - (len + offset)); @@ -149,11 +234,13 @@ parserutils_error parserutils_buffer_discard(parserutils_buffer *buffer, */ parserutils_error parserutils_buffer_grow(parserutils_buffer *buffer) { - uint8_t *temp = realloc(buffer->data, buffer->allocated * 2); + size_t offset = get_offset(buffer); + uint8_t *temp = realloc(buffer->alloc, buffer->allocated * 2); if (temp == NULL) return PARSERUTILS_NOMEM; - buffer->data = temp; + buffer->alloc = temp; + buffer->data = buffer->alloc + offset; buffer->allocated *= 2; return PARSERUTILS_OK; @@ -180,7 +267,7 @@ parserutils_error parserutils_buffer_randomise(parserutils_buffer *buffer) /* Leak the buffer's current data, so we don't reuse it */ /* buffer->alloc(buffer->data, 0, buffer->pw); */ - buffer->data = temp; + buffer->alloc = buffer->data = temp; #endif diff --git a/src/utils/endian.h b/src/utils/endian.h index 8a4760b..3227c30 100644 --- a/src/utils/endian.h +++ b/src/utils/endian.h @@ -10,9 +10,9 @@ static inline bool endian_host_is_le(void) { - static uint32_t magic = 0x10000002; + const uint16_t test = 1; - return (((uint8_t *) &magic)[0] == 0x02); + return ((const uint8_t *) &test)[0]; } static inline uint32_t endian_swap(uint32_t val) diff --git a/test/cscodec-utf16.c b/test/cscodec-utf16.c index 835c65e..a49a710 100644 --- a/test/cscodec-utf16.c +++ b/test/cscodec-utf16.c @@ -87,6 +87,7 @@ int main(int argc, char **argv) run_test(&ctx); free(ctx.buf); + free(ctx.exp); parserutils_charset_codec_destroy(ctx.codec); @@ -117,7 +118,7 @@ bool handle_line(const char *data, size_t datalen, void *pw) if (ctx->buf[ctx->bufused - 1] == '\n') ctx->bufused -= 1; - if (ctx->exp[ctx->expused - 1] == '\n') + if (ctx->expused != 0 && ctx->exp[ctx->expused - 1] == '\n') ctx->expused -= 1; run_test(ctx); |