summaryrefslogtreecommitdiff
path: root/source/kit/input_buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/kit/input_buffer.c')
-rw-r--r--source/kit/input_buffer.c447
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);
-}