Browse Source

Allow arbitrary page size to be passed for custom sources

zrythm_meson
David Robillard 6 years ago
parent
commit
52d36530ef
  1. 4
      NEWS
  2. 9
      serd/serd.h
  3. 21
      src/byte_source.c
  4. 14
      src/reader.c
  5. 4
      src/serd_internal.h
  6. 2
      wscript

4
NEWS

@ -1,8 +1,8 @@ @@ -1,8 +1,8 @@
serd (0.27.0) unstable;
serd (0.27.1) unstable;
* Add support for reading from a user provided callback
-- David Robillard <d@drobilla.net> Fri, 14 Apr 2017 20:30:51 +0200
-- David Robillard <d@drobilla.net> Mon, 24 Apr 2017 19:06:08 +0200
serd (0.26.0) stable;

9
serd/serd.h

@ -827,8 +827,8 @@ serd_reader_start_stream(SerdReader* me, @@ -827,8 +827,8 @@ serd_reader_start_stream(SerdReader* me,
/**
Start an incremental read from a user-specified source.
Iff `bulk` is true, `source` will be read a page at a time. Otherwise,
`source` is guaranteed to only be called for single bytes.
The `read_func` is guaranteed to only be called for `page_size` elements
with size 1 (i.e. `page_size` bytes).
*/
SERD_API
SerdStatus
@ -837,7 +837,7 @@ serd_reader_start_source_stream(SerdReader* me, @@ -837,7 +837,7 @@ serd_reader_start_source_stream(SerdReader* me,
SerdStreamErrorFunc error_func,
void* stream,
const uint8_t* name,
bool bulk);
size_t page_size);
/**
Read a single "chunk" of data during an incremental read.
@ -876,7 +876,8 @@ serd_reader_read_source(SerdReader* reader, @@ -876,7 +876,8 @@ serd_reader_read_source(SerdReader* reader,
SerdSource source,
SerdStreamErrorFunc error,
void* stream,
const uint8_t* name);
const uint8_t* name,
size_t page_size);
/**
Read `utf8`.

21
src/byte_source.c

@ -37,19 +37,19 @@ serd_byte_source_open_source(SerdByteSource* source, @@ -37,19 +37,19 @@ serd_byte_source_open_source(SerdByteSource* source,
SerdSource read_func,
SerdStreamErrorFunc error_func,
void* stream,
bool bulk)
size_t page_size)
{
memset(source, '\0', sizeof(*source));
source->stream = stream;
source->from_stream = true;
source->paging = bulk;
source->page_size = page_size;
source->error_func = error_func;
source->read_func = read_func;
if (bulk) {
source->file_buf = (uint8_t*)serd_bufalloc(SERD_PAGE_SIZE);
if (page_size > 1) {
source->file_buf = (uint8_t*)serd_bufalloc(page_size);
source->read_buf = source->file_buf;
memset(source->file_buf, '\0', SERD_PAGE_SIZE);
memset(source->file_buf, '\0', page_size);
} else {
source->read_buf = &source->read_byte;
}
@ -62,7 +62,7 @@ serd_byte_source_prepare(SerdByteSource* source) @@ -62,7 +62,7 @@ serd_byte_source_prepare(SerdByteSource* source)
{
if (!source->prepared) {
source->prepared = true;
if (source->paging) {
if (source->page_size > 1) {
return serd_byte_source_page(source);
} else if (source->from_stream) {
return serd_byte_source_advance(source);
@ -83,7 +83,7 @@ serd_byte_source_open_string(SerdByteSource* source, const uint8_t* utf8) @@ -83,7 +83,7 @@ serd_byte_source_open_string(SerdByteSource* source, const uint8_t* utf8)
SerdStatus
serd_byte_source_close(SerdByteSource* source)
{
if (source->paging) {
if (source->page_size > 1) {
free(source->file_buf);
}
memset(source, '\0', sizeof(*source));
@ -93,13 +93,14 @@ serd_byte_source_close(SerdByteSource* source) @@ -93,13 +93,14 @@ serd_byte_source_close(SerdByteSource* source)
SerdStatus
serd_byte_source_advance(SerdByteSource* source)
{
SerdStatus st = SERD_SUCCESS;
if (source->from_stream && !source->paging) {
const bool paging = source->page_size > 1;
SerdStatus st = SERD_SUCCESS;
if (source->from_stream && !paging) {
if (source->read_func(&source->read_byte, 1, 1, source->stream) == 0) {
return (source->error_func(source->stream)
? SERD_ERR_UNKNOWN : SERD_FAILURE);
}
} else if (++source->read_head == SERD_PAGE_SIZE && source->paging) {
} else if (++source->read_head == source->page_size && paging) {
st = serd_byte_source_page(source);
}

14
src/reader.c

@ -1834,7 +1834,7 @@ serd_reader_start_stream(SerdReader* me, @@ -1834,7 +1834,7 @@ serd_reader_start_stream(SerdReader* me,
(SerdStreamErrorFunc)ferror,
file,
name,
bulk);
bulk ? SERD_PAGE_SIZE : 1);
}
SERD_API
@ -1844,13 +1844,13 @@ serd_reader_start_source_stream(SerdReader* me, @@ -1844,13 +1844,13 @@ serd_reader_start_source_stream(SerdReader* me,
SerdStreamErrorFunc error_func,
void* stream,
const uint8_t* name,
bool bulk)
size_t page_size)
{
const Cursor cur = { name, 1, 1 };
me->cur = cur;
return serd_byte_source_open_source(
&me->source, read_func, error_func, stream, bulk);
&me->source, read_func, error_func, stream, page_size);
}
static SerdStatus
@ -1895,7 +1895,8 @@ SerdStatus @@ -1895,7 +1895,8 @@ SerdStatus
serd_reader_read_file_handle(SerdReader* me, FILE* file, const uint8_t* name)
{
return serd_reader_read_source(
me, (SerdSource)fread, (SerdStreamErrorFunc)ferror, file, name);
me, (SerdSource)fread, (SerdStreamErrorFunc)ferror,
file, name, SERD_PAGE_SIZE);
}
SERD_API
@ -1904,10 +1905,11 @@ serd_reader_read_source(SerdReader* me, @@ -1904,10 +1905,11 @@ serd_reader_read_source(SerdReader* me,
SerdSource source,
SerdStreamErrorFunc error,
void* stream,
const uint8_t* name)
const uint8_t* name,
size_t page_size)
{
SerdStatus st = serd_reader_start_source_stream(
me, source, error, stream, name, true);
me, source, error, stream, name, page_size);
if ((st = serd_reader_prepare(me))) {
serd_reader_end_stream(me);

4
src/serd_internal.h

@ -72,12 +72,12 @@ typedef struct { @@ -72,12 +72,12 @@ typedef struct {
SerdSource read_func; ///< Read function (e.g. fread)
SerdStreamErrorFunc error_func; ///< Error function (e.g. ferror)
void* stream; ///< Stream (e.g. FILE)
size_t page_size; ///< Number of bytes to read at a time
uint8_t* file_buf; ///< Buffer iff reading pages from a file
const uint8_t* read_buf; ///< Pointer to file_buf or read_byte
size_t read_head; ///< Offset into read_buf
uint8_t read_byte; ///< 1-byte 'buffer' used when not paging
bool from_stream; ///< True iff reading from `stream`
bool paging; ///< True iff reading a page at a time
bool prepared; ///< True iff prepared for reading
} SerdByteSource;
@ -94,7 +94,7 @@ serd_byte_source_open_source(SerdByteSource* source, @@ -94,7 +94,7 @@ serd_byte_source_open_source(SerdByteSource* source,
SerdSource read_func,
SerdStreamErrorFunc error_func,
void* stream,
bool bulk);
size_t page_size);
SerdStatus
serd_byte_source_close(SerdByteSource* source);

2
wscript

@ -11,7 +11,7 @@ import waflib.extras.autowaf as autowaf @@ -11,7 +11,7 @@ import waflib.extras.autowaf as autowaf
# major increment <=> incompatible changes
# minor increment <=> compatible changes (additions)
# micro increment <=> no interface changes
SERD_VERSION = '0.27.0'
SERD_VERSION = '0.27.1'
SERD_MAJOR_VERSION = '0'
# Mandatory waf variables

Loading…
Cancel
Save