From cc9e0b2546da21e749f68eb4d148ecb58a90fc66 Mon Sep 17 00:00:00 2001 From: Hugues Delorme Date: Mon, 23 Mar 2015 18:15:31 +0100 Subject: [PATCH] gmio_core: add size_func and rewind_func function pointers to gmio_stream --- src/gmio_core/internal/helper_stream.h | 15 +++++++ src/gmio_core/stream.c | 17 ++++++++ src/gmio_core/stream.h | 7 ++++ src/gmio_support/qt_stream.cpp | 14 +++++++ tests/stream_buffer.c | 55 +++++++++++++++++--------- tests/stream_buffer.h | 6 +-- 6 files changed, 92 insertions(+), 22 deletions(-) diff --git a/src/gmio_core/internal/helper_stream.h b/src/gmio_core/internal/helper_stream.h index dd3543e..0d49dc8 100644 --- a/src/gmio_core/internal/helper_stream.h +++ b/src/gmio_core/internal/helper_stream.h @@ -54,3 +54,18 @@ GMIO_INLINE size_t gmio_stream_write( return stream->write_func(stream->cookie, ptr, size, count); return 0; } + +/*! Safe and convenient function for gmio_stream::size_func() */ +GMIO_INLINE size_t gmio_stream_size(gmio_stream_t* stream) +{ + if (stream != NULL && stream->size_func != NULL) + return stream->size_func(stream->cookie); + return 0; +} + +/*! Safe and convenient function for gmio_stream::rewind_func() */ +GMIO_INLINE void gmio_stream_rewind(gmio_stream_t* stream) +{ + if (stream != NULL && stream->rewind_func != NULL) + stream->rewind_func(stream->cookie); +} diff --git a/src/gmio_core/stream.c b/src/gmio_core/stream.c index 730414a..19e3c8d 100644 --- a/src/gmio_core/stream.c +++ b/src/gmio_core/stream.c @@ -19,6 +19,9 @@ #include #include +#include +#include + void gmio_stream_set_null(gmio_stream_t* stream) { memset(stream, 0, sizeof(gmio_stream_t)); @@ -52,6 +55,18 @@ static size_t gmio_stream_stdio_write( return fwrite(ptr, item_size, item_count, (FILE*) cookie); } +static size_t gmio_stream_stdio_size(void* cookie) +{ + struct stat stat_buf; + fstat(fileno((FILE*) cookie), &stat_buf); + return stat_buf.st_size; +} + +static void gmio_stream_stdio_rewind(void* cookie) +{ + rewind((FILE*) cookie); +} + void gmio_stream_set_stdio(gmio_stream_t* stream, FILE* file) { stream->cookie = file; @@ -59,6 +74,8 @@ void gmio_stream_set_stdio(gmio_stream_t* stream, FILE* file) stream->error_func = gmio_stream_stdio_error; stream->read_func = gmio_stream_stdio_read; stream->write_func = gmio_stream_stdio_write; + stream->size_func = gmio_stream_stdio_size; + stream->rewind_func = gmio_stream_stdio_rewind; } gmio_stream_t gmio_stream_stdio(FILE* file) diff --git a/src/gmio_core/stream.h b/src/gmio_core/stream.h index f3f8056..196ccba 100644 --- a/src/gmio_core/stream.h +++ b/src/gmio_core/stream.h @@ -87,6 +87,13 @@ struct gmio_stream * \returns The total number of elements successfully written */ size_t (*write_func)(void* cookie, const void* ptr, size_t size, size_t count); + + /*! Pointer on function that returns the size(in bytes) of the stream */ + size_t (*size_func)(void* cookie); + + /*! Pointer on function that moves the position indicator within the stream + * to the beginning */ + void (*rewind_func)(void* cookie); }; typedef struct gmio_stream gmio_stream_t; diff --git a/src/gmio_support/qt_stream.cpp b/src/gmio_support/qt_stream.cpp index 7f66dc2..1925469 100644 --- a/src/gmio_support/qt_stream.cpp +++ b/src/gmio_support/qt_stream.cpp @@ -56,6 +56,18 @@ static size_t gmio_stream_qiodevice_write( return c / item_size; } +static size_t gmio_stream_qiodevice_size(void* cookie) +{ + QIODevice* device = static_cast(cookie); + return device->size(); +} + +static size_t gmio_stream_qiodevice_rewind(void* cookie) +{ + QIODevice* device = static_cast(cookie); + device->seek(0); +} + void gmio_stream_set_qiodevice(gmio_stream_t* stream, QIODevice* device) { stream->cookie = device; @@ -63,6 +75,8 @@ void gmio_stream_set_qiodevice(gmio_stream_t* stream, QIODevice* device) stream->error_func = gmio_stream_qiodevice_error; stream->read_func = gmio_stream_qiodevice_read; stream->write_func = gmio_stream_qiodevice_write; + stream->size_func = gmio_stream_qiodevice_size; + stream->rewind_func = gmio_stream_qiodevice_rewind; } gmio_stream_t gmio_stream_qiodevice(QIODevice* device) diff --git a/tests/stream_buffer.c b/tests/stream_buffer.c index 0722110..6626df6 100644 --- a/tests/stream_buffer.c +++ b/tests/stream_buffer.c @@ -21,32 +21,34 @@ static gmio_bool_t gmio_stream_buffer_at_end(void* cookie) { - const gmio_buffer_t* buff = (const gmio_buffer_t*)cookie; + const gmio_stream_buffer_t* buff = (const gmio_stream_buffer_t*)cookie; return buff->pos >= buff->len; } static int gmio_stream_buffer_error(void* cookie) { - const gmio_buffer_t* buff = (const gmio_buffer_t*)cookie; + const gmio_stream_buffer_t* buff = (const gmio_stream_buffer_t*)cookie; return buff == NULL || buff->pos > buff->len; } -static size_t gmio_stream_buffer_read(void* cookie, - void* ptr, - size_t item_size, - size_t item_count) +static size_t gmio_stream_buffer_read( + void* cookie, void* ptr, size_t item_size, size_t item_count) { if (item_size > 0 && item_count > 0) { - gmio_buffer_t* buff = (gmio_buffer_t*)cookie; + gmio_stream_buffer_t* buff = (gmio_stream_buffer_t*)cookie; const void* buff_ptr = - buff->readonly_ptr != NULL ? buff->readonly_ptr : buff->readwrite_ptr; + buff->readonly_ptr != NULL ? + buff->readonly_ptr : buff->readwrite_ptr; const size_t buff_remaining_size = buff->len - buff->pos; const size_t wanted_read_size = item_size * item_count; const size_t next_read_size = - wanted_read_size <= buff_remaining_size ? wanted_read_size : buff_remaining_size; + wanted_read_size <= buff_remaining_size ? + wanted_read_size : buff_remaining_size; const size_t next_read_item_count = next_read_size / item_size; - memcpy(ptr, (const char*)buff_ptr + buff->pos, next_read_item_count * item_size); + memcpy(ptr, + (const char*)buff_ptr + buff->pos, + next_read_item_count * item_size); buff->pos += next_read_item_count * item_size; return next_read_item_count; } @@ -55,20 +57,21 @@ static size_t gmio_stream_buffer_read(void* cookie, } } -static size_t gmio_stream_buffer_write(void* cookie, - const void* ptr, - size_t item_size, - size_t item_count) +static size_t gmio_stream_buffer_write( + void* cookie, const void* ptr, size_t item_size, size_t item_count) { if (item_size > 0 && item_count > 0) { - gmio_buffer_t* buff = (gmio_buffer_t*)cookie; + gmio_stream_buffer_t* buff = (gmio_stream_buffer_t*)cookie; const size_t buff_remaining_size = buff->len - buff->pos; const size_t wanted_write_size = item_size * item_count; - const size_t next_write_size = wanted_write_size <= buff_remaining_size ? wanted_write_size : - buff_remaining_size; + const size_t next_write_size = + wanted_write_size <= buff_remaining_size ? + wanted_write_size : buff_remaining_size; const size_t next_write_item_count = next_write_size / item_size; - memcpy((char*)buff->readwrite_ptr + buff->pos, ptr, next_write_item_count * item_size); + memcpy((char*)buff->readwrite_ptr + buff->pos, + ptr, + next_write_item_count * item_size); buff->pos += next_write_item_count * item_size; return next_write_item_count; } @@ -77,11 +80,25 @@ static size_t gmio_stream_buffer_write(void* cookie, } } -void gmio_stream_set_buffer(gmio_stream_t *stream, gmio_buffer_t* buff) +static size_t gmio_stream_buffer_size(void* cookie) +{ + const gmio_stream_buffer_t* buff = (const gmio_stream_buffer_t*)cookie; + return buff->len; +} + +static void gmio_stream_buffer_rewind(void* cookie) +{ + gmio_stream_buffer_t* buff = (gmio_stream_buffer_t*)cookie; + buff->pos = 0; +} + +void gmio_stream_set_buffer(gmio_stream_t *stream, gmio_stream_buffer_t* buff) { stream->cookie = buff; stream->at_end_func = gmio_stream_buffer_at_end; stream->error_func = gmio_stream_buffer_error; stream->read_func = gmio_stream_buffer_read; stream->write_func = gmio_stream_buffer_write; + stream->size_func = gmio_stream_buffer_size; + stream->rewind_func = gmio_stream_buffer_rewind; } diff --git a/tests/stream_buffer.h b/tests/stream_buffer.h index bd95ecb..eda586c 100644 --- a/tests/stream_buffer.h +++ b/tests/stream_buffer.h @@ -20,15 +20,15 @@ #include "../src/gmio_core/stream.h" -struct gmio_buffer +struct gmio_stream_buffer { const void* readonly_ptr; void* readwrite_ptr; size_t len; size_t pos; }; -typedef struct gmio_buffer gmio_buffer_t; +typedef struct gmio_stream_buffer gmio_stream_buffer_t; -void gmio_stream_set_buffer(gmio_stream_t* stream, gmio_buffer_t* buff); +void gmio_stream_set_buffer(gmio_stream_t* stream, gmio_stream_buffer_t* buff); #endif /* GMIO_STREAM_BUFFER_H */