From 5ddc96e1b442403c2fa2049f64580d5c0d443fa0 Mon Sep 17 00:00:00 2001 From: timerix Date: Fri, 27 Oct 2023 13:37:18 +0600 Subject: [PATCH] StringBuilder --- cbuild | 2 +- src/Autoarr/Autoarr.c | 26 ++++----- src/String/StringBuilder.c | 108 +++++++++++++------------------------ src/String/StringBuilder.h | 9 ++-- src/base/memory/memory.h | 10 ++-- 5 files changed, 61 insertions(+), 94 deletions(-) diff --git a/cbuild b/cbuild index ef6a3f8..60fa8c1 160000 --- a/cbuild +++ b/cbuild @@ -1 +1 @@ -Subproject commit ef6a3f82c429ec232e1b910eecbdece76de933b3 +Subproject commit 60fa8c11c2673a10f8afbe37bcea13c9be3317b8 diff --git a/src/Autoarr/Autoarr.c b/src/Autoarr/Autoarr.c index 2cbb0a0..f2159c8 100644 --- a/src/Autoarr/Autoarr.c +++ b/src/Autoarr/Autoarr.c @@ -1,17 +1,17 @@ #include "Autoarr.h" -// Autoarr_define(Pointer, true) +Autoarr_define(Pointer, true) Autoarr_define(char, false) -// Autoarr_define(bool, false) -// Autoarr_define(f32, false) -// Autoarr_define(f64, false) -// Autoarr_define(u8, false) -// Autoarr_define(i8, false) -// Autoarr_define(u16, false) -// Autoarr_define(i16, false) -// Autoarr_define(u32, false) -// Autoarr_define(i32, false) -// Autoarr_define(u64, false) -// Autoarr_define(i64, false) +Autoarr_define(bool, false) +Autoarr_define(f32, false) +Autoarr_define(f64, false) +Autoarr_define(u8, false) +Autoarr_define(i8, false) +Autoarr_define(u16, false) +Autoarr_define(i16, false) +Autoarr_define(u32, false) +Autoarr_define(i32, false) +Autoarr_define(u64, false) +Autoarr_define(i64, false) -// Autoarr_define(Unitype, false) +Autoarr_define(Unitype, false) diff --git a/src/String/StringBuilder.c b/src/String/StringBuilder.c index d633376..e7bb66a 100644 --- a/src/String/StringBuilder.c +++ b/src/String/StringBuilder.c @@ -5,122 +5,86 @@ kt_define(StringBuilder, (destruct_t)StringBuilder_destruct, NULL); #define BL_C 32 #define BL_L 1024 +#define createBuffer() (MemoryChunk){.data = allocator_alloc(InternalAllocator_getPtr(b), 512), .size=512, .occupied_size=0} + void complete_buf(StringBuilder* b){ - if(!b->compl_bufs) - b->compl_bufs=Autoarr_construct(string,BL_C,BL_L); - u32 len=Autoarr_length(b->curr_buf); - if(len==0) + if(b->curr_buf.occupied_size == 0) return; - string str={.length=len, .ptr=malloc(len)}; - u32 i=0; - Autoarr_foreach(b->curr_buf, c, - str.ptr[i++]=c; - ); - Autoarr_add(b->compl_bufs,str); - Autoarr_destruct(b->curr_buf, true); - b->curr_buf=Autoarr_construct(i8,BL_C,BL_L); + string str={ .length=b->curr_buf.occupied_size, .ptr= b->curr_buf.data }; + Autoarr_add(&b->compl_bufs,str); + b->curr_buf = createBuffer(); } void StringBuilder_construct(StringBuilder* b, allocator_ptr external_al){ InternalAllocator_setExternalOrConstruct(b, external_al, LinearAllocator, 1024); - b->compl_bufs=NULL; - b->curr_buf=Autoarr_construct(i8,BL_C,BL_L); + Autoarr_construct(&b->compl_bufs, string, 0, InternalAllocator_getPtr(b)); + b->curr_buf = createBuffer(); + b->total_length = 0; } void StringBuilder_destruct(StringBuilder* b){ - if(b->compl_bufs) - Autoarr_destruct(b->compl_bufs, true); - Autoarr_destruct(b->curr_buf, true); + Autoarr_destruct(&b->compl_bufs); + allocator_free(InternalAllocator_getPtr(b), b->curr_buf.data); InternalAllocator_destructIfInternal(LinearAllocator, b); } string StringBuilder_build(StringBuilder* b){ complete_buf(b); - u32 len=0; - Autoarr_foreach(b->compl_bufs, cs, - len+=cs.length; - ); - string str= { .length=len, .ptr=malloc(len+1) }; - str.ptr[len]='\0'; - u32 l=0; - Autoarr_foreach(b->compl_bufs, cs, - memcpy(str.ptr+l, cs.ptr, cs.length); - l+=cs.length; + string str= { + .length = b->total_length, + .ptr = allocator_alloc(InternalAllocator_getPtr(b), b->total_length+1) + }; + str.ptr[b->total_length]='\0'; + char* free_space_ptr = str.ptr; + Autoarr_foreach(&b->compl_bufs, buf, + memcpy(free_space_ptr, buf.ptr, buf.length); + free_space_ptr += buf.length; ); StringBuilder_destruct(b); return str; } - void StringBuilder_rmchar(StringBuilder* b){ - if(b->curr_buf->chunk_length!=0) - Autoarr_pop(b->curr_buf) + if(b->curr_buf.occupied_size != 0) + b->curr_buf.occupied_size--; else { - if(!b->compl_bufs) throw(ERR_NULLPTR); - string* lastcb=Autoarr_getPtr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1)); - lastcb->length--; + for(u32 buf_i = Autoarr_length(&b->compl_bufs) - 1; buf_i != (u32)-1; buf_i--){ + string* lastcb = Autoarr_getPtr(&b->compl_bufs, buf_i); + if(lastcb->length != 0){ + lastcb->length--; + break; + } + } } } void StringBuilder_append_char(StringBuilder* b, char c){ - if(b->curr_buf->chunks_count==BL_C) + if(b->curr_buf.occupied_size==b->curr_buf.size) complete_buf(b); - Autoarr_add(b->curr_buf,c); + ((char*)b->curr_buf.data)[b->curr_buf.occupied_size] = c; } void StringBuilder_append_string(StringBuilder* b, string s){ complete_buf(b); - // TODO remove copying - Autoarr_add(b->compl_bufs, string_copy(InternalAllocator_getPtr(b), s)); + Autoarr_add(&b->compl_bufs, s); } void StringBuilder_append_cptr(StringBuilder* b, char* s){ - string str={ - .ptr=s, - .length=cptr_length(s) - }; + string str={ .ptr=s, .length=cptr_length(s) }; StringBuilder_append_string(b, str); } void StringBuilder_append_i64(StringBuilder* b, i64 a){ - u8 i=0; - if(a==0){ - Autoarr_add(b->curr_buf,'0'); - return; - } - else if(a<0){ - Autoarr_add(b->curr_buf,'-'); - a=-a; - } - char buf[24]; - while(a!=0){ - buf[i++]='0'+a%10; - a/=10; - } - string rev=string_reverse(InternalAllocator_getPtr(b), (string){buf,i}); - StringBuilder_append_string(b, rev); + StringBuilder_append_cptr(b, toString_i64(InternalAllocator_getPtr(b), a)); } void StringBuilder_append_u64(StringBuilder* b, u64 a){ - u8 i=0; - if(a==0){ - Autoarr_add(b->curr_buf,'0'); - return; - } - char buf[24]; - while(a!=0){ - buf[i++]='0'+a%10; - a/=10; - } - string rev=string_reverse(InternalAllocator_getPtr(b), (string){buf,i}); - StringBuilder_append_string(b, rev); + StringBuilder_append_cptr(b, toString_u64(InternalAllocator_getPtr(b), a, 0, 0)); } void StringBuilder_append_f64(StringBuilder* b, f64 a){ - char buf[32]; - sprintf_s(buf, sizeof(buf), "%lf", a); - StringBuilder_append_string(b, (string){.ptr=buf, .length=cptr_length(buf)}); + StringBuilder_append_cptr(b, toString_f64(InternalAllocator_getPtr(b), a, toString_f64_max_precision, 0, 0)); } diff --git a/src/String/StringBuilder.h b/src/String/StringBuilder.h index 9aa4c32..28b2e83 100644 --- a/src/String/StringBuilder.h +++ b/src/String/StringBuilder.h @@ -9,8 +9,9 @@ extern "C" { STRUCT(StringBuilder, InternalAllocator_declare(LinearAllocator); - Autoarr(string)* compl_bufs; - Autoarr(i8)* curr_buf; + Autoarr(string) compl_bufs; + MemoryChunk curr_buf; + u64 total_length; ) ///@param external_al if null, creates internal allocator @@ -22,8 +23,10 @@ void StringBuilder_destruct(StringBuilder* b); // No need to call string_extract! // Destructs StringBuilder. string StringBuilder_build(StringBuilder* b); -// removes last char + +/// OBSOLETE! Will be removed later void StringBuilder_rmchar(StringBuilder* b); + void StringBuilder_append_char(StringBuilder* b, char c); void StringBuilder_append_cptr(StringBuilder* b, char* s); void StringBuilder_append_string(StringBuilder* b, string s); diff --git a/src/base/memory/memory.h b/src/base/memory/memory.h index 390dd5b..d6a2261 100644 --- a/src/base/memory/memory.h +++ b/src/base/memory/memory.h @@ -19,18 +19,18 @@ allocator_ptr _internal_al_ptr; /// get pointer to allocator -#define InternalAllocator_getPtr(STRUCT_PTR) (STRUCT_PTR->_internal_al_ptr) +#define InternalAllocator_getPtr(STRUCT_PTR) ((STRUCT_PTR)->_internal_al_ptr) /// true if allocator is stored inside the struct, otherwise false -#define InternalAllocator_isInternal(STRUCT_PTR) (bool)(STRUCT_PTR->_internal_al_ptr == (allocator_ptr)&STRUCT_PTR->_internal_al) +#define InternalAllocator_isInternal(STRUCT_PTR) (bool)((STRUCT_PTR)->_internal_al_ptr == (allocator_ptr)&(STRUCT_PTR)->_internal_al) /// set ptr to external allocator -#define InternalAllocator_setExternal(STRUCT_PTR, EXT_AL_PTR) (STRUCT_PTR->_internal_al_ptr = EXT_AL_PTR); +#define InternalAllocator_setExternal(STRUCT_PTR, EXT_AL_PTR) ((STRUCT_PTR)->_internal_al_ptr = EXT_AL_PTR); /// create internal allocator and set ptr to it #define InternalAllocator_construct(STRUCT_PTR, TYPE, CTOR_ARGS...) { \ - TYPE##_construct(&STRUCT_PTR->_internal_al, CTOR_ARGS); \ - STRUCT_PTR->_internal_al_ptr = (allocator_ptr)&STRUCT_PTR->_internal_al; \ + TYPE##_construct(&(STRUCT_PTR)->_internal_al, CTOR_ARGS); \ + (STRUCT_PTR)->_internal_al_ptr = (allocator_ptr)&(STRUCT_PTR)->_internal_al; \ } /// if EXT_AL_PTR isn't null, set external allocator, otherwise create new