diff options
-rw-r--r-- | alisp.h | 1 | ||||
-rw-r--r-- | impl/stream.c | 43 | ||||
-rw-r--r-- | lorem.txt | 32 | ||||
-rw-r--r-- | main.c | 46 |
4 files changed, 96 insertions, 26 deletions
@@ -50,6 +50,7 @@ typedef struct #define SV(DATA, SIZE) ((sv_t){.data = (DATA), .size = (SIZE)}) #define SV_FMT(SV) (int)(SV).size, (SV).data #define PR_SV "%.*s" +#define PRD_SV "%d@%p" sv_t sv_copy(sv_t); 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); } diff --git a/lorem.txt b/lorem.txt new file mode 100644 index 0000000..4479dd0 --- /dev/null +++ b/lorem.txt @@ -0,0 +1,32 @@ +Pellentesque dapibus suscipit ligula. Donec posuere augue in quam. +Etiam vel tortor sodales tellus ultricies commodo. Suspendisse +potenti. Aenean in sem ac leo mollis blandit. Donec neque quam, +dignissim in, mollis nec, sagittis eu, wisi. Phasellus lacus. Etiam +laoreet quam sed arcu. Phasellus at dui in ligula mollis ultricies. +Integer placerat tristique nisl. Praesent augue. Fusce commodo. +Vestibulum convallis, lorem a tempus semper, dui dui euismod elit, +vitae placerat urna tortor vitae lacus. Nullam libero mauris, +consequat quis, varius et, dictum id, arcu. Mauris mollis tincidunt +felis. Aliquam feugiat tellus ut neque. Nulla facilisis, risus a +rhoncus fermentum, tellus tellus lacinia purus, et dictum nunc justo +sit amet elit. + +Nullam eu ante vel est convallis dignissim. Fusce suscipit, wisi nec +facilisis facilisis, est dui fermentum leo, quis tempor ligula erat +quis odio. Nunc porta vulputate tellus. Nunc rutrum turpis sed pede. +Sed bibendum. Aliquam posuere. Nunc aliquet, augue nec adipiscing +interdum, lacus tellus malesuada massa, quis varius mi purus non odio. +Pellentesque condimentum, magna ut suscipit hendrerit, ipsum augue +ornare nulla, non luctus diam neque sit amet urna. Curabitur +vulputate vestibulum lorem. Fusce sagittis, libero non molestie +mollis, magna orci ultrices dolor, at vulputate neque nulla lacinia +eros. Sed id ligula quis est convallis tempor. Curabitur lacinia +pulvinar nibh. Nam a sapien. + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Donec +hendrerit tempor tellus. Donec pretium posuere tellus. Proin quam +nisl, tincidunt et, mattis eget, convallis nec, purus. Cum sociis +natoque penatibus et magnis dis parturient montes, nascetur ridiculus +mus. Nulla posuere. Donec vitae dolor. Nullam tristique diam non +turpis. Cras placerat accumsan nulla. Nullam rutrum. Nam vestibulum +accumsan nisl. @@ -21,20 +21,50 @@ int main(void) { stream_t stream = {0}; - // const char data[] = "Hello, world!"; - // const sv_t sv = SV(data, ARRSIZE(data) - 1); - // stream_init_string(&stream, NULL, sv); + char _data[] = "Hello, world!"; + sv_t data = SV(_data, ARRSIZE(_data) - 1); + char filename[] = "lorem.txt"; - // stream_init_file(&stream, "test.txt"); + // stream_init_string(&stream, NULL, data); - stream_init_file(&stream, "stdin", stdin); - printf("[debug]: setup stream pipe\n"); - do + FILE *fp = fopen(filename, "rb"); + stream_init_file(&stream, filename, fp); + + // stream_init_file(&stream, "stdin", stdin); + + /// test 1 + while (!stream_eoc(&stream)) { printf("%s[%lu]: `%c`\n", stream.name, stream.position, stream_next(&stream)); - } while (!stream_eoc(&stream)); + } printf("%lu/%lu\n", stream.position, stream_size(&stream)); + + /// test 2 + stream.position = 0; + sv_t a = stream_substr(&stream, 100); + sv_t a_ = sv_copy(a); + stream_seek(&stream, 100); + sv_t b = stream_substr_abs(&stream, 0, 100); + sv_t b_ = sv_copy(b); + printf("a=b ? %s\na_=b_ ? %s\n", + memcmp(&a, &b, sizeof(a)) == 0 ? "yes" : "no", + a_.size == b_.size && strncmp(a_.data, b_.data, a_.size) == 0 ? "yes" + : "no"); + sv_t c = stream_substr(&stream, 100); + sv_t c_ = sv_copy(c); + stream_seek(&stream, 100); + sv_t d = stream_substr_abs(&stream, stream.position - 100, 100); + sv_t d_ = sv_copy(d); + printf("c=d ? %s\nc_=d_ ? %s\n", + memcmp(&c, &d, sizeof(a)) == 0 ? "yes" : "no", + c_.size == d_.size && strncmp(c_.data, d_.data, c_.size) == 0 ? "yes" + : "no"); + + printf("eos?=%s\n", stream_eos(&stream) ? "yes" : "no"); + printf("eoc?=%s\n", stream_eoc(&stream) ? "yes" : "no"); + stream_stop(&stream); + // fclose(fp); return 0; } |