diff options
Diffstat (limited to 'source/kit/input_buffer.c')
-rw-r--r-- | source/kit/input_buffer.c | 447 |
1 files changed, 224 insertions, 223 deletions
diff --git a/source/kit/input_buffer.c b/source/kit/input_buffer.c index 3ee4959..db7e156 100644 --- a/source/kit/input_buffer.c +++ b/source/kit/input_buffer.c @@ -3,174 +3,178 @@ #include <assert.h> #include <string.h> -typedef struct { - i64 ref_count; - kit_is_handle_t upstream; - kit_allocator_t *alloc; - kit_str_builder_t data; -} internal_buffer_t; - -static internal_buffer_t *kit_buf_init_(kit_is_handle_t upstream, - kit_allocator_t *alloc) { - internal_buffer_t *buf = kit_alloc_dispatch(alloc, KIT_ALLOCATE, - sizeof *buf, 0, NULL); - - if (buf != NULL) { - memset(buf, 0, sizeof *buf); - buf->ref_count = 1; - buf->upstream = upstream; - buf->alloc = alloc; - DA_INIT(buf->data, 0, alloc); - } +enum { KIT_IB_CACHE_SIZE = 256 }; - return buf; -} +static s32 kit_buf_adjust_(kit_input_buffer_t *buf, i64 size) { + assert(buf != NULL); + assert(size >= 0); -static kit_allocator_t *kit_buf_alloc_(void *p) { - assert(p != NULL); + if (buf == NULL) + return KIT_ERROR_INTERNAL; - return ((internal_buffer_t *) p)->alloc; -} + i64 offset = buf->data.size; -static void kit_buf_acquire_(void *p) { - assert(p != NULL); + if (offset >= size) + return KIT_OK; - ((internal_buffer_t *) p)->ref_count++; -} + DA_RESIZE(buf->data, size); + if (buf->data.size != size) + return KIT_ERROR_BAD_ALLOC; -static void kit_buf_release_(void *p) { - if (p == NULL) - return; + str_t destination = { .size = size - offset, + .values = buf->data.values + offset }; + i64 n = IS_READ(buf->upstream, destination); - internal_buffer_t *buf = (internal_buffer_t *) p; + DA_RESIZE(buf->data, offset + n); + if (buf->data.size != offset + n) + return KIT_ERROR_BAD_ALLOC; - if (--buf->ref_count == 0) { - DA_DESTROY(buf->data); - kit_alloc_dispatch(buf->alloc, KIT_DEALLOCATE, 0, 0, buf); - } + return KIT_OK; } -static void kit_buf_adjust_(void *p, i64 size) { - assert(p != NULL); - assert(size >= 0); +kit_input_buffer_t kit_ib_wrap(is_handle_t upstream, + kit_allocator_t *alloc) { + kit_input_buffer_t buf; + memset(&buf, 0, sizeof buf); - internal_buffer_t *buf = (internal_buffer_t *) p; - i64 offset = buf->data.size; + buf.upstream = upstream; + DA_INIT(buf.data, 0, alloc); - if (offset < size) { - DA_RESIZE(buf->data, size); - kit_str_t destination = { .size = size - offset, - .values = buf->data.values + offset }; - i64 n = KIT_IS_READ(buf->upstream, destination); - DA_RESIZE(buf->data, offset + n); - } + return buf; } -static i64 kit_buf_read_(void *p, i64 offset, kit_str_t destination) { - internal_buffer_t *buf = (internal_buffer_t *) p; - i64 n = destination.size < buf->data.size - offset - ? destination.size - : buf->data.size - offset; - memcpy(destination.values, buf->data.values + offset, n); - return n; +void kit_ib_destroy(kit_input_buffer_t *buf) { + assert(buf != NULL); + if (buf == NULL) + return; + + DA_DESTROY(buf->data); + memset(buf, 0, sizeof *buf); } -kit_ib_t kit_ib_wrap(kit_is_handle_t upstream, - kit_allocator_t *alloc) { - kit_ib_t buf; - memset(&buf, 0, sizeof buf); - buf.status = KIT_OK; - DA_INIT(buf.data, 0, alloc); - buf.internal = kit_buf_init_(upstream, alloc); - if (buf.internal == NULL) - buf.status = KIT_ERROR_BAD_ALLOC; - return buf; +kit_ib_token_t kit_ib_token(kit_input_buffer_t *buf) { + return (kit_ib_token_t) { + .status = KIT_OK, .offset = 0, .size = 0, .buffer = buf + }; } -kit_ib_t kit_ib_copy(kit_ib_t buf) { - kit_ib_t next; - memset(&next, 0, sizeof next); +kit_str_t kit_ib_str(kit_ib_token_t tok) { + assert(tok.buffer != NULL); - if (buf.status != KIT_OK) { - next.status = buf.status; - return next; - } + if (tok.buffer == NULL || tok.buffer->data.values == NULL) + return (str_t) { .size = 0, .values = NULL }; - kit_buf_acquire_(buf.internal); + return (str_t) { .size = tok.size, + .values = tok.buffer->data.values + tok.offset }; +} - next.offset = buf.offset; - next.internal = buf.internal; +kit_ib_token_t kit_ib_read(kit_ib_token_t tok, i64 size) { + assert(tok.buffer != NULL); - return next; -} + kit_ib_token_t next = tok; -kit_ib_t kit_ib_read(kit_ib_t buf, i64 size) { - kit_ib_t next; - memset(&next, 0, sizeof next); + next.offset = tok.offset + tok.size; + next.size = 0; - if (buf.status != KIT_OK) { - next.status = buf.status; + if (tok.status != KIT_OK) + return next; + + if (tok.buffer == NULL) { + next.status = KIT_ERROR_INVALID_ARGUMENT; return next; } - kit_buf_acquire_(buf.internal); - kit_buf_adjust_(buf.internal, buf.offset + size); + s32 s = kit_buf_adjust_(tok.buffer, tok.offset + tok.size + size); + + if (s != KIT_OK) { + next.status = s; + return next; + } - DA_INIT(next.data, size, kit_buf_alloc_(buf.internal)); - if (next.data.size != size) - next.status = KIT_ERROR_BAD_ALLOC; + assert(tok.buffer->data.values != NULL); - kit_str_t destination = { .size = next.data.size, - .values = next.data.values }; - i64 n = kit_buf_read_(buf.internal, buf.offset, destination); - next.offset = buf.offset + n; - next.internal = buf.internal; + if (tok.buffer->data.values == NULL) { + next.status = KIT_ERROR_INTERNAL; + return next; + } - DA_RESIZE(next.data, n); - if (next.data.size != n) - next.status = KIT_ERROR_BAD_ALLOC; + next.size = size < tok.buffer->data.size - tok.offset - tok.size + ? size + : tok.buffer->data.size - tok.offset - tok.size; return next; } -kit_ib_t kit_ib_any(kit_ib_t buf, kit_str_t data) { - kit_ib_t next; - memset(&next, 0, sizeof next); +#define IB_CACHE_INIT_(res_) \ + str_builder_t cache_dynamic; \ + memset(&cache_dynamic, 0, sizeof cache_dynamic); \ + char cache_static[KIT_IB_CACHE_SIZE]; \ + \ + do { \ + if (data.size > 0) { \ + if (data.size < KIT_IB_CACHE_SIZE) { \ + memcpy(cache_static, data.values, data.size); \ + data.values = cache_static; \ + } else { \ + DA_INIT(cache_dynamic, data.size, tok.buffer->data.alloc); \ + if (cache_dynamic.size != data.size) { \ + (res_).status |= KIT_ERROR_BAD_ALLOC; \ + return (res_); \ + } \ + memcpy(cache_dynamic.values, data.values, data.size); \ + data.values = cache_dynamic.values; \ + } \ + } \ + } while (0) + +#define IB_CACHE_CLEANUP_() \ + do { \ + if (cache_dynamic.values != NULL) \ + DA_DESTROY(cache_dynamic); \ + } while (0) + +kit_ib_token_t kit_ib_any(kit_ib_token_t tok, str_t data) { + assert(tok.buffer != NULL); + + kit_ib_token_t next = tok; + + next.offset = tok.offset + tok.size; + next.size = 0; + + if (tok.status != KIT_OK) + return next; - if (buf.status != KIT_OK) { - next.status = buf.status; + if (tok.buffer == NULL) { + next.status = KIT_ERROR_INVALID_ARGUMENT; return next; } - kit_buf_acquire_(buf.internal); - - DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal)); + IB_CACHE_INIT_(next); - i64 size = 0; + for (;; ++next.size) { + s32 s = kit_buf_adjust_(tok.buffer, + tok.offset + tok.size + next.size + 1); - for (;; ++size) { - kit_buf_adjust_(buf.internal, buf.offset + size + 1); + if (s != KIT_OK) { + next.status = s; + return next; + } - DA_RESIZE(next.data, size + 1); + assert(tok.buffer->data.values != NULL); - assert(next.data.size == size + 1); - if (next.data.size != size + 1) { - next.status = KIT_ERROR_BAD_ALLOC; + if (tok.buffer->data.values == NULL) { + next.status = KIT_ERROR_INTERNAL; return next; } - kit_str_t destination = { .size = 1, - .values = next.data.values + size }; - i64 n = kit_buf_read_(buf.internal, buf.offset + size, - destination); - - if (n != 1) + if (tok.offset + tok.size + next.size >= tok.buffer->data.size) break; i8 found = 0; for (i64 i = 0; i < data.size; i++) - if (data.values[i] == destination.values[0]) { + if (data.values[i] == + tok.buffer->data.values[next.offset + next.size]) { found = 1; break; } @@ -179,54 +183,53 @@ kit_ib_t kit_ib_any(kit_ib_t buf, kit_str_t data) { break; } - next.offset = buf.offset + size; - next.internal = buf.internal; - - DA_RESIZE(next.data, size); - if (next.data.size != size) - next.status = KIT_ERROR_BAD_ALLOC; + IB_CACHE_CLEANUP_(); return next; } -kit_ib_t kit_ib_none(kit_ib_t buf, kit_str_t data) { - kit_ib_t next; - memset(&next, 0, sizeof next); +kit_ib_token_t kit_ib_none(kit_ib_token_t tok, str_t data) { + assert(tok.buffer != NULL); - if (buf.status != KIT_OK) { - next.status = buf.status; - return next; - } + kit_ib_token_t next = tok; - kit_buf_acquire_(buf.internal); + next.offset = tok.offset + tok.size; + next.size = 0; - DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal)); + if (tok.status != KIT_OK) + return next; - i64 size = 0; + if (tok.buffer == NULL) { + next.status = KIT_ERROR_INVALID_ARGUMENT; + return next; + } - for (;; ++size) { - kit_buf_adjust_(buf.internal, buf.offset + size + 1); + IB_CACHE_INIT_(next); - DA_RESIZE(next.data, size + 1); + for (;; ++next.size) { + s32 s = kit_buf_adjust_(tok.buffer, + tok.offset + tok.size + next.size + 1); - assert(next.data.size == size + 1); - if (next.data.size != size + 1) { - next.status = KIT_ERROR_BAD_ALLOC; + if (s != KIT_OK) { + next.status = s; return next; } - kit_str_t destination = { .size = 1, - .values = next.data.values + size }; - i64 n = kit_buf_read_(buf.internal, buf.offset + size, - destination); + assert(tok.buffer->data.values != NULL); - if (n != 1) + if (tok.buffer->data.values == NULL) { + next.status = KIT_ERROR_INTERNAL; + return next; + } + + if (tok.offset + tok.size + next.size >= tok.buffer->data.size) break; i8 found = 0; for (i64 i = 0; i < data.size; i++) - if (data.values[i] == destination.values[0]) { + if (data.values[i] == + tok.buffer->data.values[next.offset + next.size]) { found = 1; break; } @@ -235,125 +238,123 @@ kit_ib_t kit_ib_none(kit_ib_t buf, kit_str_t data) { break; } - next.offset = buf.offset + size; - next.internal = buf.internal; - - DA_RESIZE(next.data, size); - if (next.data.size != size) - next.status = KIT_ERROR_BAD_ALLOC; + IB_CACHE_CLEANUP_(); return next; } -kit_ib_t kit_ib_exact(kit_ib_t buf, kit_str_t data) { - kit_ib_t res = kit_ib_read(buf, data.size); - if (!AR_EQUAL(res.data, data)) - res.status = KIT_ERROR_INTERNAL; +kit_ib_token_t kit_ib_exact(kit_ib_token_t tok, str_t data) { + kit_ib_token_t res = tok; + + res.offset = tok.offset + tok.size; + res.size = 0; + + IB_CACHE_INIT_(res); + + res = kit_ib_read(tok, data.size); + if (!AR_EQUAL(kit_ib_str(res), data)) + res.status = KIT_PARSING_FAILED; + + IB_CACHE_CLEANUP_(); + return res; } -kit_ib_t kit_ib_until(kit_ib_t buf, kit_str_t data) { - kit_ib_t next; - memset(&next, 0, sizeof next); +kit_ib_token_t kit_ib_until(kit_ib_token_t tok, str_t data) { + assert(tok.buffer != NULL); - if (buf.status != KIT_OK) { - next.status = buf.status; - return next; - } + kit_ib_token_t next = tok; - kit_buf_acquire_(buf.internal); + next.offset = tok.offset + tok.size; + next.size = 0; - DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal)); + if (tok.status != KIT_OK) + return next; - i64 size = 0; + if (tok.buffer == NULL) { + next.status = KIT_ERROR_INVALID_ARGUMENT; + return next; + } - for (;; ++size) { - kit_buf_adjust_(buf.internal, buf.offset + size + 1); + IB_CACHE_INIT_(next); - DA_RESIZE(next.data, size + 1); + for (;; ++next.size) { + s32 s = kit_buf_adjust_(tok.buffer, + tok.offset + tok.size + next.size + 1); - assert(next.data.size == size + 1); - if (next.data.size != size + 1) { - next.status = KIT_ERROR_BAD_ALLOC; + if (s != KIT_OK) { + next.status = s; return next; } - kit_str_t destination = { .size = 1, - .values = next.data.values + size }; - i64 n = kit_buf_read_(buf.internal, buf.offset + size, - destination); + assert(tok.buffer->data.values != NULL); - if (n != 1) + if (tok.buffer->data.values == NULL) { + next.status = KIT_ERROR_INTERNAL; + return next; + } + + if (tok.offset + tok.size + next.size >= tok.buffer->data.size) break; - if (size + 1 >= data.size && - AR_EQUAL(kit_str(data.size, - next.data.values + (size + 1 - data.size)), + if (next.size + 1 >= data.size && + AR_EQUAL(kit_str(data.size, tok.buffer->data.values + + (next.offset + next.size + 1 - + data.size)), data)) { - size -= data.size - 1; + next.size -= data.size - 1; break; } } - next.offset = buf.offset + size; - next.internal = buf.internal; - - DA_RESIZE(next.data, size); - if (next.data.size != size) - next.status = KIT_ERROR_BAD_ALLOC; + IB_CACHE_CLEANUP_(); return next; } -kit_ib_t kit_ib_while(kit_ib_t buf, - kit_ib_read_condition_fn condition, - void *context) { - kit_ib_t next; - memset(&next, 0, sizeof next); +kit_ib_token_t kit_ib_while(kit_ib_token_t tok, + kit_ib_read_condition_fn condition, + void *context) { + assert(tok.buffer != NULL); - if (buf.status != KIT_OK) { - next.status = buf.status; - return next; - } + kit_ib_token_t next = tok; - kit_buf_acquire_(buf.internal); + next.offset = tok.offset + tok.size; + next.size = 0; + + if (tok.status != KIT_OK) + return next; - DA_INIT(next.data, 0, kit_buf_alloc_(buf.internal)); + if (tok.buffer == NULL) { + next.status = KIT_ERROR_INVALID_ARGUMENT; + return next; + } - i64 size = 0; + for (;; ++next.size) { + s32 s = kit_buf_adjust_(tok.buffer, + tok.offset + tok.size + next.size + 1); - for (;; ++size) { - kit_buf_adjust_(buf.internal, buf.offset + size + 1); + if (s != KIT_OK) { + next.status = s; + return next; + } - DA_RESIZE(next.data, size + 1); + assert(tok.buffer->data.values != NULL); - assert(next.data.size == size + 1); - if (next.data.size != size + 1) { - next.status = KIT_ERROR_BAD_ALLOC; + if (tok.buffer->data.values == NULL) { + next.status = KIT_ERROR_INTERNAL; return next; } - kit_str_t destination = { .size = 1, - .values = next.data.values + size }; - i64 n = kit_buf_read_(buf.internal, buf.offset + size, - destination); + if (tok.offset + tok.size + next.size >= tok.buffer->data.size) + break; - kit_str_t data = { .size = size + 1, .values = next.data.values }; - if (n != 1 || condition == NULL || condition(data, context) == 0) + if (condition == NULL || + !condition(kit_str(next.size + 1, + tok.buffer->data.values + next.offset), + context)) break; } - next.offset = buf.offset + size; - next.internal = buf.internal; - - DA_RESIZE(next.data, size); - if (next.data.size != size) - next.status = KIT_ERROR_BAD_ALLOC; - return next; } - -void kit_ib_destroy(kit_ib_t buf) { - kit_buf_release_(buf.internal); - DA_DESTROY(buf.data); -} |