You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.0 KiB
107 lines
3.0 KiB
/* |
|
Copyright 2011-2017 David Robillard <http://drobilla.net> |
|
|
|
Permission to use, copy, modify, and/or distribute this software for any |
|
purpose with or without fee is hereby granted, provided that the above |
|
copyright notice and this permission notice appear in all copies. |
|
|
|
THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
|
*/ |
|
|
|
#include "serd_internal.h" |
|
|
|
static inline SerdStatus |
|
serd_byte_source_page(SerdByteSource* source) |
|
{ |
|
source->read_head = 0; |
|
size_t n_read = source->read_func( |
|
source->file_buf, 1, SERD_PAGE_SIZE, source->stream); |
|
if (n_read == 0) { |
|
source->file_buf[0] = '\0'; |
|
return (source->error_func(source->stream) |
|
? SERD_ERR_UNKNOWN : SERD_FAILURE); |
|
} else if (n_read < SERD_PAGE_SIZE) { |
|
source->file_buf[n_read] = '\0'; |
|
} |
|
return SERD_SUCCESS; |
|
} |
|
|
|
SerdStatus |
|
serd_byte_source_open_source(SerdByteSource* source, |
|
SerdSource read_func, |
|
SerdStreamErrorFunc error_func, |
|
void* stream, |
|
bool bulk) |
|
{ |
|
memset(source, '\0', sizeof(*source)); |
|
source->stream = stream; |
|
source->from_stream = true; |
|
source->paging = bulk; |
|
source->error_func = error_func; |
|
source->read_func = read_func; |
|
|
|
if (bulk) { |
|
source->file_buf = (uint8_t*)serd_bufalloc(SERD_PAGE_SIZE); |
|
source->read_buf = source->file_buf; |
|
memset(source->file_buf, '\0', SERD_PAGE_SIZE); |
|
} else { |
|
source->read_buf = &source->read_byte; |
|
} |
|
|
|
return SERD_SUCCESS; |
|
} |
|
|
|
SerdStatus |
|
serd_byte_source_prepare(SerdByteSource* source) |
|
{ |
|
if (!source->prepared) { |
|
source->prepared = true; |
|
if (source->paging) { |
|
return serd_byte_source_page(source); |
|
} else if (source->from_stream) { |
|
return serd_byte_source_advance(source); |
|
} |
|
} |
|
return SERD_SUCCESS; |
|
} |
|
|
|
SerdStatus |
|
serd_byte_source_open_string(SerdByteSource* source, const uint8_t* utf8) |
|
{ |
|
memset(source, '\0', sizeof(*source)); |
|
source->read_buf = utf8; |
|
source->prepared = true; |
|
return SERD_SUCCESS; |
|
} |
|
|
|
SerdStatus |
|
serd_byte_source_close(SerdByteSource* source) |
|
{ |
|
if (source->paging) { |
|
free(source->file_buf); |
|
} |
|
memset(source, '\0', sizeof(*source)); |
|
return SERD_SUCCESS; |
|
} |
|
|
|
SerdStatus |
|
serd_byte_source_advance(SerdByteSource* source) |
|
{ |
|
SerdStatus st = SERD_SUCCESS; |
|
if (source->from_stream && !source->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) { |
|
st = serd_byte_source_page(source); |
|
} |
|
|
|
return st; |
|
}
|
|
|