diff options
Diffstat (limited to 'impl/stream.c')
-rw-r--r-- | impl/stream.c | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/impl/stream.c b/impl/stream.c index 3f109be..dd264cd 100644 --- a/impl/stream.c +++ b/impl/stream.c @@ -42,6 +42,8 @@ stream_err_t stream_init_file(stream_t *stream, char *name, FILE *pipe) stream->pipe.file = pipe; vec_init(&stream->pipe.cache, STREAM_DEFAULT_CHUNK); + // try to read an initial chunk + stream_chunk(stream); return STREAM_ERR_OK; } @@ -101,7 +103,8 @@ bool stream_eoc(stream_t *stream) case STREAM_TYPE_STRING: return stream->position >= stream->string.size; case STREAM_TYPE_FILE: - return stream->position >= stream->pipe.cache.size; + return feof(stream->pipe.file) && + stream->position >= stream->pipe.cache.size; default: FAIL("Unreachable"); return 0; @@ -121,8 +124,8 @@ bool stream_chunk(stream_t *stream) if (feof(stream->pipe.file)) return false; vec_ensure_free(&stream->pipe.cache, STREAM_DEFAULT_CHUNK); - int read = fread(vec_data(&stream->pipe.cache), 1, STREAM_DEFAULT_CHUNK, - stream->pipe.file); + int read = fread(vec_data(&stream->pipe.cache) + stream->pipe.cache.size, 1, + STREAM_DEFAULT_CHUNK, stream->pipe.file); stream->pipe.cache.size += read; return true; } @@ -142,7 +145,9 @@ char stream_next(stream_t *stream) char stream_peek(stream_t *stream) { - if (stream_eos(stream)) + // If we've reached end of stream, and end of content, there's really nothing + // to check here. + if (stream_eoc(stream)) return '\0'; switch (stream->type) @@ -186,18 +191,18 @@ bool stream_seek(stream_t *stream, i64 offset) bool stream_seek_forward(stream_t *stream, u64 offset) { - if (stream_eos(stream)) + if (stream_eoc(stream)) return false; + switch (stream->type) { case STREAM_TYPE_STRING: { - if (stream->position + offset < stream->string.size) - { - stream->position += offset; - return true; - } - return false; + if (stream->position + offset >= stream->string.size) + return false; + + stream->position += offset; + return true; } case STREAM_TYPE_FILE: { @@ -217,7 +222,7 @@ bool stream_seek_forward(stream_t *stream, u64 offset) read_chunk = stream_chunk(stream)) continue; - // Same principle as the stream_eos(stream) check. + // Same principle as the stream_eoc(stream) check. if (stream->position + offset >= stream->pipe.cache.size) return false; stream->position += offset; @@ -240,12 +245,15 @@ bool stream_seek_backward(stream_t *stream, u64 offset) sv_t stream_substr(stream_t *stream, u64 size) { - if (stream_eos(stream)) + if (stream_eoc(stream)) return SV(NULL, 0); + + // TODO: this is kinda disgusting, any better way of doing this u64 current_position = stream->position; bool successful = stream_seek_forward(stream, size); - // In case we did happen to move forward + // Reset the position in either situation stream->position = current_position; + if (!successful) return SV(NULL, 0); @@ -268,16 +276,15 @@ sv_t stream_substr(stream_t *stream, u64 size) sv_t stream_substr_abs(stream_t *stream, u64 index, u64 size) { - switch (stream->type) { case STREAM_TYPE_STRING: - if (index + size < stream_size(stream)) + if (index + size <= stream_size(stream)) return SV(stream->string.data + index, size); return SV(NULL, 0); case STREAM_TYPE_FILE: { - if (index + size < stream_size(stream)) + if (index + size <= stream_size(stream)) return SV(vec_data(&stream->pipe.cache) + index, size); // stream_size(stream) <= index + size => try reading chunks for (bool read_chunk = stream_chunk(stream); @@ -285,7 +292,7 @@ sv_t stream_substr_abs(stream_t *stream, u64 index, u64 size) read_chunk = stream_chunk(stream)) continue; - if (index + size >= stream_size(stream)) + if (index + size > stream_size(stream)) return SV(NULL, 0); return SV(vec_data(&stream->pipe.cache) + index, size); } |