gmio/tests/stream_buffer.c

154 lines
5.3 KiB
C
Raw Normal View History

2015-03-03 00:38:33 +08:00
/****************************************************************************
2016-07-05 18:46:22 +08:00
** Copyright (c) 2016, Fougue Ltd. <http://www.fougue.pro>
** All rights reserved.
2015-03-03 00:38:33 +08:00
**
2016-07-05 18:46:22 +08:00
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
2015-03-03 00:38:33 +08:00
**
2016-07-05 18:46:22 +08:00
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** 2. Redistributions in binary form must reproduce the above
** copyright notice, this list of conditions and the following
** disclaimer in the documentation and/or other materials provided
** with the distribution.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2015-03-03 00:38:33 +08:00
****************************************************************************/
2014-02-04 19:41:03 +08:00
#include "stream_buffer.h"
#include <string.h>
2016-01-27 00:03:58 +08:00
static bool gmio_stream_buffer_at_end(void* cookie)
2014-02-04 19:41:03 +08:00
{
const struct gmio_ro_buffer* buff = (const struct gmio_ro_buffer*)cookie;
2015-03-03 17:35:36 +08:00
return buff->pos >= buff->len;
2014-02-04 19:41:03 +08:00
}
static int gmio_stream_buffer_error(void* cookie)
2014-02-04 19:41:03 +08:00
{
const struct gmio_ro_buffer* buff = (const struct gmio_ro_buffer*)cookie;
2015-03-03 17:35:36 +08:00
return buff == NULL || buff->pos > buff->len;
2014-02-04 19:41:03 +08:00
}
static size_t gmio_stream_buffer_read(
void* cookie, void* ptr, size_t item_size, size_t item_count)
2014-02-04 19:41:03 +08:00
{
2015-03-03 17:35:36 +08:00
if (item_size > 0 && item_count > 0) {
struct gmio_ro_buffer* buff = (struct gmio_ro_buffer*)cookie;
const void* buff_ptr = buff->ptr;
2015-03-03 17:35:36 +08:00
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;
2015-03-03 17:35:36 +08:00
const size_t next_read_item_count = next_read_size / item_size;
2014-02-04 19:41:03 +08:00
memcpy(ptr,
(const char*)buff_ptr + buff->pos,
next_read_item_count * item_size);
2015-03-03 17:35:36 +08:00
buff->pos += next_read_item_count * item_size;
return next_read_item_count;
}
else {
return 0;
}
2014-02-04 19:41:03 +08:00
}
static size_t gmio_stream_buffer_write(
void* cookie, const void* ptr, size_t item_size, size_t item_count)
2014-02-04 19:41:03 +08:00
{
2015-03-03 17:35:36 +08:00
if (item_size > 0 && item_count > 0) {
struct gmio_rw_buffer* buff = (struct gmio_rw_buffer*)cookie;
2015-03-03 17:35:36 +08:00
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;
2015-03-03 17:35:36 +08:00
const size_t next_write_item_count = next_write_size / item_size;
2014-02-04 19:41:03 +08:00
memcpy((char*)buff->ptr + buff->pos,
ptr,
next_write_item_count * item_size);
2015-03-03 17:35:36 +08:00
buff->pos += next_write_item_count * item_size;
return next_write_item_count;
}
else {
return 0;
}
2014-02-04 19:41:03 +08:00
}
static gmio_streamsize_t gmio_stream_buffer_size(void* cookie)
{
const struct gmio_ro_buffer* buff = (const struct gmio_ro_buffer*)cookie;
return buff->len;
}
static int gmio_stream_buffer_get_pos(void* cookie, struct gmio_streampos* pos)
{
struct gmio_ro_buffer* buff = (struct gmio_ro_buffer*)cookie;
memcpy(&pos->cookie[0], &buff->pos, sizeof(size_t));
return 0;
}
static int gmio_stream_buffer_set_pos(
void* cookie, const struct gmio_streampos* pos)
{
struct gmio_ro_buffer* buff = (struct gmio_ro_buffer*)cookie;
memcpy(&buff->pos, &pos->cookie[0], sizeof(size_t));
return 0;
}
struct gmio_stream gmio_istream_buffer(struct gmio_ro_buffer* buff)
2014-02-04 19:41:03 +08:00
{
struct gmio_stream stream = {0};
stream.cookie = buff;
stream.func_at_end = gmio_stream_buffer_at_end;
stream.func_error = gmio_stream_buffer_error;
stream.func_read = gmio_stream_buffer_read;
stream.func_size = gmio_stream_buffer_size;
stream.func_get_pos = gmio_stream_buffer_get_pos;
stream.func_set_pos = gmio_stream_buffer_set_pos;
return stream;
}
struct gmio_stream gmio_stream_buffer(struct gmio_rw_buffer* buff)
{
struct gmio_stream stream =
gmio_istream_buffer((struct gmio_ro_buffer*)buff);
stream.func_write = gmio_stream_buffer_write;
return stream;
2014-02-04 19:41:03 +08:00
}
struct gmio_ro_buffer gmio_ro_buffer(const void *ptr, size_t len, size_t pos)
{
struct gmio_ro_buffer buff = {0};
buff.ptr = ptr;
buff.len = len;
buff.pos = pos;
return buff;
}
struct gmio_rw_buffer gmio_rw_buffer(void *ptr, size_t len, size_t pos)
{
struct gmio_rw_buffer buff = {0};
buff.ptr = ptr;
buff.len = len;
buff.pos = pos;
return buff;
}