2015-03-03 00:38:33 +08:00
|
|
|
/****************************************************************************
|
2015-05-28 15:40:24 +08:00
|
|
|
** gmio
|
2016-06-24 18:03:07 +08:00
|
|
|
** Copyright Fougue (24 Jun. 2016)
|
2015-07-13 17:42:03 +08:00
|
|
|
** contact@fougue.pro
|
2015-03-03 00:38:33 +08:00
|
|
|
**
|
|
|
|
** This software is a reusable library whose purpose is to provide complete
|
|
|
|
** I/O support for various CAD file formats (eg. STL)
|
|
|
|
**
|
|
|
|
** This software is governed by the CeCILL-B license under French law and
|
|
|
|
** abiding by the rules of distribution of free software. You can use,
|
|
|
|
** modify and/ or redistribute the software under the terms of the CeCILL-B
|
|
|
|
** license as circulated by CEA, CNRS and INRIA at the following URL
|
2015-03-30 15:05:25 +08:00
|
|
|
** "http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html".
|
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
|
|
|
{
|
2016-01-05 18:48:56 +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
|
|
|
}
|
|
|
|
|
2014-03-28 23:33:35 +08:00
|
|
|
static int gmio_stream_buffer_error(void* cookie)
|
2014-02-04 19:41:03 +08:00
|
|
|
{
|
2016-01-05 18:48:56 +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
|
|
|
}
|
|
|
|
|
2015-03-24 01:15:31 +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) {
|
2016-01-05 18:48:56 +08:00
|
|
|
struct gmio_ro_buffer* buff = (struct gmio_ro_buffer*)cookie;
|
2015-11-23 23:35:26 +08:00
|
|
|
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;
|
2015-03-03 23:44:14 +08:00
|
|
|
const size_t next_read_size =
|
2015-03-24 01:15:31 +08:00
|
|
|
wanted_read_size <= buff_remaining_size ?
|
2015-11-23 23:35:26 +08:00
|
|
|
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
|
|
|
|
2015-03-24 01:15:31 +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
|
|
|
}
|
|
|
|
|
2015-03-24 01:15:31 +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) {
|
2015-12-04 01:00:25 +08:00
|
|
|
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;
|
2015-03-24 01:15:31 +08:00
|
|
|
const size_t next_write_size =
|
|
|
|
wanted_write_size <= buff_remaining_size ?
|
2015-11-23 23:35:26 +08:00
|
|
|
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
|
|
|
|
2015-11-23 23:35:26 +08:00
|
|
|
memcpy((char*)buff->ptr + buff->pos,
|
2015-03-24 01:15:31 +08:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2015-11-06 20:43:03 +08:00
|
|
|
static gmio_streamsize_t gmio_stream_buffer_size(void* cookie)
|
2015-03-24 01:15:31 +08:00
|
|
|
{
|
2016-01-05 18:48:56 +08:00
|
|
|
const struct gmio_ro_buffer* buff = (const struct gmio_ro_buffer*)cookie;
|
2015-03-24 01:15:31 +08:00
|
|
|
return buff->len;
|
|
|
|
}
|
|
|
|
|
2015-12-04 01:03:46 +08:00
|
|
|
static int gmio_stream_buffer_get_pos(void* cookie, struct gmio_streampos* pos)
|
2015-09-21 21:44:55 +08:00
|
|
|
{
|
2016-01-05 18:48:56 +08:00
|
|
|
struct gmio_ro_buffer* buff = (struct gmio_ro_buffer*)cookie;
|
2015-09-21 21:44:55 +08:00
|
|
|
memcpy(&pos->cookie[0], &buff->pos, sizeof(size_t));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-01-05 18:48:56 +08:00
|
|
|
static int gmio_stream_buffer_set_pos(
|
|
|
|
void* cookie, const struct gmio_streampos* pos)
|
2015-09-21 21:44:55 +08:00
|
|
|
{
|
2016-01-05 18:48:56 +08:00
|
|
|
struct gmio_ro_buffer* buff = (struct gmio_ro_buffer*)cookie;
|
2015-09-21 21:44:55 +08:00
|
|
|
memcpy(&buff->pos, &pos->cookie[0], sizeof(size_t));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-01-05 18:48:56 +08:00
|
|
|
struct gmio_stream gmio_istream_buffer(struct gmio_ro_buffer* buff)
|
2014-02-04 19:41:03 +08:00
|
|
|
{
|
2015-12-04 01:00:25 +08:00
|
|
|
struct gmio_stream stream = {0};
|
2015-11-23 23:35:26 +08:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-12-04 01:00:25 +08:00
|
|
|
struct gmio_stream gmio_stream_buffer(struct gmio_rw_buffer* buff)
|
2015-11-23 23:35:26 +08:00
|
|
|
{
|
2016-01-05 18:48:56 +08:00
|
|
|
struct gmio_stream stream =
|
|
|
|
gmio_istream_buffer((struct gmio_ro_buffer*)buff);
|
2015-11-23 23:35:26 +08:00
|
|
|
stream.func_write = gmio_stream_buffer_write;
|
|
|
|
return stream;
|
2014-02-04 19:41:03 +08:00
|
|
|
}
|
2016-01-12 23:31:18 +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;
|
|
|
|
}
|