summaryrefslogtreecommitdiff
path: root/kernel/lib/sb.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lib/sb.c')
-rw-r--r--kernel/lib/sb.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/kernel/lib/sb.c b/kernel/lib/sb.c
new file mode 100644
index 0000000..3f99d95
--- /dev/null
+++ b/kernel/lib/sb.c
@@ -0,0 +1,124 @@
+#include <kmalloc.h>
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tb/sb.h>
+
+#define DEFAULT_CAPACITY 256
+
+void sb_init(struct sb *ctx) {
+ (void)sb_init_capacity(ctx, DEFAULT_CAPACITY);
+}
+
+int sb_init_capacity(struct sb *ctx, size_t starting_capacity) {
+ ctx->length = 0;
+ ctx->prebuffer = 0;
+ ctx->string = kmalloc(starting_capacity);
+ if (NULL == ctx->string) {
+ ctx->capacity = 0;
+ return 0;
+ }
+ ctx->capacity = starting_capacity;
+ return 1;
+}
+
+void sb_init_buffer(struct sb *ctx, char *buffer, size_t size) {
+ ctx->string = buffer;
+ ctx->capacity = size;
+ ctx->length = 0;
+ ctx->prebuffer = 1;
+}
+
+void sb_free(struct sb *ctx) {
+ if (ctx->prebuffer) {
+ ctx->length = 0;
+ return;
+ }
+ ctx->length = 0;
+ ctx->capacity = 0;
+ kfree(ctx->string);
+ ctx->string = NULL;
+}
+
+void sb_reset(struct sb *ctx) {
+ ctx->length = 0;
+}
+
+int sb_isempty(const struct sb *ctx) {
+ return (0 == ctx->length);
+}
+
+int sb_increase_buffer(struct sb *ctx, size_t min) {
+ if (ctx->prebuffer) {
+ return 0;
+ }
+ size_t new_capacity = ctx->capacity + max(32, min);
+ char *new_allocation = krealloc(ctx->string, new_capacity);
+ if (!new_allocation) {
+ return 0;
+ }
+
+ ctx->string = new_allocation;
+ ctx->capacity = new_capacity;
+ return 1;
+}
+
+int sb_append_char(struct sb *ctx, char c) {
+ if (1 > ctx->capacity - ctx->length) {
+ if (!sb_increase_buffer(ctx, 1)) {
+ return 0;
+ }
+ }
+ memcpy(ctx->string + ctx->length, &c, 1);
+ ctx->length++;
+ return 1;
+}
+
+int sb_delete_right(struct sb *ctx, size_t n) {
+ n = min(n, ctx->length);
+ ctx->length -= n;
+ return n;
+}
+
+int sb_append(struct sb *ctx, const char *s) {
+ size_t l = strlen(s);
+ if (l > ctx->capacity - ctx->length) {
+ if (!sb_increase_buffer(ctx, l)) {
+ return 0;
+ }
+ }
+ memcpy(ctx->string + ctx->length, s, l);
+ ctx->length += l;
+ return 1;
+}
+
+int sb_prepend_sv(struct sb *ctx, struct sv sv) {
+ return sb_prepend_buffer(ctx, sv.s, sv.length);
+}
+
+int sb_prepend_buffer(struct sb *ctx, const char *buffer, size_t length) {
+ if (length > ctx->capacity - ctx->length) {
+ if (!sb_increase_buffer(ctx, length)) {
+ return 0;
+ }
+ }
+ memmove(ctx->string + length, ctx->string, ctx->length);
+ memcpy(ctx->string, buffer, length);
+ ctx->length += length;
+ return 1;
+}
+
+int sb_append_buffer(struct sb *ctx, const char *buffer, size_t length) {
+ if (length > ctx->capacity - ctx->length) {
+ if (!sb_increase_buffer(ctx, length)) {
+ return 0;
+ }
+ }
+ memcpy(ctx->string + ctx->length, buffer, length);
+ ctx->length += length;
+ return 1;
+}
+
+int sb_append_sv(struct sb *ctx, struct sv sv) {
+ return sb_append_buffer(ctx, sv.s, sv.length);
+}