224 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "dstr.h"
 | |
| #include "aliases.h"
 | |
| #include "mem_allocator.h"
 | |
| #include "mem_libc.h"
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| 
 | |
| // Use this scalar to allocate extra memory in order to avoid having to
 | |
| // constantly reallocate
 | |
| #define CAPACITY_SCALAR 8
 | |
| 
 | |
| struct dstr {
 | |
|   Allocator allocator;
 | |
|   u64 capacity;
 | |
|   u64 size;
 | |
|   char buf[];
 | |
| };
 | |
| 
 | |
| String *wapp_dstr_with_capacity(u64 capacity, const Allocator *allocator) {
 | |
|   Allocator alloc;
 | |
|   if (allocator) {
 | |
|     alloc = *allocator;
 | |
|   } else {
 | |
|     alloc = wapp_mem_libc_allocator();
 | |
|   }
 | |
| 
 | |
|   String *out =
 | |
|       (String *)wapp_mem_allocator_alloc(&alloc, sizeof(String) + capacity + 1);
 | |
|   if (!out) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   out->allocator = alloc;
 | |
|   out->capacity = capacity;
 | |
|   out->size = 0;
 | |
| 
 | |
|   return out;
 | |
| }
 | |
| 
 | |
| String *wapp_dstr_from_string(const char *str, const Allocator *allocator) {
 | |
|   if (!str) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   u64 length = strlen(str);
 | |
| 
 | |
|   u64 capacity = length * CAPACITY_SCALAR;
 | |
| 
 | |
|   String *out = wapp_dstr_with_capacity(capacity, allocator);
 | |
|   if (!out) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   out->size = length;
 | |
|   strncpy(out->buf, str, length + 1);
 | |
| 
 | |
|   return out;
 | |
| }
 | |
| 
 | |
| void wapp_dstr_update(String **dst, const char *src) {
 | |
|   if (!dst || !(*dst)) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   u64 length = strlen(src);
 | |
| 
 | |
|   String *str = *dst;
 | |
| 
 | |
|   if (length < str->capacity) {
 | |
|     memset(str->buf, 0, str->capacity);
 | |
| 
 | |
|     str->size = length;
 | |
| 
 | |
|     strncpy(str->buf, src, length + 1);
 | |
|   } else {
 | |
|     u64 capacity = length * CAPACITY_SCALAR;
 | |
| 
 | |
|     String *tmp = (String *)wapp_mem_allocator_realloc(
 | |
|         &(str->allocator), *dst, sizeof(String) + capacity + 1);
 | |
|     if (!tmp) {
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     tmp->capacity = capacity;
 | |
|     tmp->size = length;
 | |
|     strncpy(tmp->buf, src, length + 1);
 | |
| 
 | |
|     *dst = tmp;
 | |
|   }
 | |
| }
 | |
| 
 | |
| void wapp_dstr_free(String **str) {
 | |
|   if (!str || !(*str)) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   String *str_ptr = *str;
 | |
|   wapp_mem_allocator_free(&(str_ptr->allocator), (void **)str);
 | |
| }
 | |
| 
 | |
| void wapp_dstr_concat(String **dst, const char *src) {
 | |
|   if (!dst || !(*dst)) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   u64 src_length = strlen(src);
 | |
|   if (src_length == 0) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   u64 new_length = (*dst)->size + src_length;
 | |
| 
 | |
|   char str[new_length + 1];
 | |
|   memset(str, 0, new_length + 1);
 | |
| 
 | |
|   strncpy(str, (*dst)->buf, (*dst)->size);
 | |
|   strncat(str, src, new_length + 1 - (*dst)->size);
 | |
| 
 | |
|   wapp_dstr_update(dst, str);
 | |
| }
 | |
| 
 | |
| void wapp_dstr_append(String **dst, char c) {
 | |
|   if (!dst || !(*dst)) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   u64 new_length = (*dst)->size + 1;
 | |
| 
 | |
|   char str[new_length + 1];
 | |
|   memset(str, 0, new_length + 1);
 | |
| 
 | |
|   strncpy(str, (*dst)->buf, (*dst)->size);
 | |
|   str[(*dst)->size] = c;
 | |
| 
 | |
|   wapp_dstr_update(dst, str);
 | |
| }
 | |
| 
 | |
| void wapp_dstr_resize(String **str) {
 | |
|   if (!str || !(*str)) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   String *str_ptr = *str;
 | |
|   u64 capacity = (*str)->size;
 | |
| 
 | |
|   String *tmp = (String *)wapp_mem_allocator_realloc(
 | |
|       &(str_ptr->allocator), *str, sizeof(String) + capacity + 1);
 | |
|   if (!tmp) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   tmp->capacity = capacity;
 | |
| 
 | |
|   *str = tmp;
 | |
| }
 | |
| 
 | |
| void wapp_dstr_clear(String *str) {
 | |
|   if (!str || str->size == 0) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   memset(str->buf, 0, str->capacity);
 | |
|   str->size = 0;
 | |
| }
 | |
| 
 | |
| void wapp_dstr_print(const String *str) {
 | |
|   if (!str) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   printf("%.*s\n", (i32)str->size, str->buf);
 | |
| }
 | |
| 
 | |
| i64 wapp_dstr_find(const String *str, const char *substr) {
 | |
|   if (!str || !substr) {
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   u64 substr_length = strlen(substr);
 | |
|   if (substr_length == 0 || substr_length > str->size) {
 | |
|     return -1;
 | |
|   }
 | |
| 
 | |
|   const char *s1;
 | |
|   for (u64 i = 0; i < str->size; ++i) {
 | |
|     if (i + substr_length > str->size) {
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     s1 = &(str->buf[i]);
 | |
| 
 | |
|     if (strncmp(s1, substr, substr_length) == 0) {
 | |
|       return i;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return -1;
 | |
| }
 | |
| 
 | |
| u64 wapp_dstr_length(const String *str) {
 | |
|   if (!str) {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   return str->size;
 | |
| }
 | |
| 
 | |
| u64 wapp_dstr_capacity(const String *str) {
 | |
|   if (!str) {
 | |
|     return 0;
 | |
|   }
 | |
| 
 | |
|   return str->capacity;
 | |
| }
 | |
| 
 | |
| const char *wapp_dstr_to_cstr(const String *str) {
 | |
|   if (!str) {
 | |
|     return "";
 | |
|   }
 | |
| 
 | |
|   return str->buf;
 | |
| }
 |