#include #include #include #include #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 = malloc(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; free(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 = realloc(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); }