StringBuilder

This commit is contained in:
timerix 2023-10-27 13:37:18 +06:00
parent e7280038fb
commit 5ddc96e1b4
5 changed files with 61 additions and 94 deletions

2
cbuild

@ -1 +1 @@
Subproject commit ef6a3f82c429ec232e1b910eecbdece76de933b3 Subproject commit 60fa8c11c2673a10f8afbe37bcea13c9be3317b8

View File

@ -1,17 +1,17 @@
#include "Autoarr.h" #include "Autoarr.h"
// Autoarr_define(Pointer, true) Autoarr_define(Pointer, true)
Autoarr_define(char, false) Autoarr_define(char, false)
// Autoarr_define(bool, false) Autoarr_define(bool, false)
// Autoarr_define(f32, false) Autoarr_define(f32, false)
// Autoarr_define(f64, false) Autoarr_define(f64, false)
// Autoarr_define(u8, false) Autoarr_define(u8, false)
// Autoarr_define(i8, false) Autoarr_define(i8, false)
// Autoarr_define(u16, false) Autoarr_define(u16, false)
// Autoarr_define(i16, false) Autoarr_define(i16, false)
// Autoarr_define(u32, false) Autoarr_define(u32, false)
// Autoarr_define(i32, false) Autoarr_define(i32, false)
// Autoarr_define(u64, false) Autoarr_define(u64, false)
// Autoarr_define(i64, false) Autoarr_define(i64, false)
// Autoarr_define(Unitype, false) Autoarr_define(Unitype, false)

View File

@ -5,122 +5,86 @@ kt_define(StringBuilder, (destruct_t)StringBuilder_destruct, NULL);
#define BL_C 32 #define BL_C 32
#define BL_L 1024 #define BL_L 1024
#define createBuffer() (MemoryChunk){.data = allocator_alloc(InternalAllocator_getPtr(b), 512), .size=512, .occupied_size=0}
void complete_buf(StringBuilder* b){ void complete_buf(StringBuilder* b){
if(!b->compl_bufs) if(b->curr_buf.occupied_size == 0)
b->compl_bufs=Autoarr_construct(string,BL_C,BL_L);
u32 len=Autoarr_length(b->curr_buf);
if(len==0)
return; return;
string str={.length=len, .ptr=malloc(len)}; string str={ .length=b->curr_buf.occupied_size, .ptr= b->curr_buf.data };
u32 i=0; Autoarr_add(&b->compl_bufs,str);
Autoarr_foreach(b->curr_buf, c, b->curr_buf = createBuffer();
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);
} }
void StringBuilder_construct(StringBuilder* b, allocator_ptr external_al){ void StringBuilder_construct(StringBuilder* b, allocator_ptr external_al){
InternalAllocator_setExternalOrConstruct(b, external_al, LinearAllocator, 1024); InternalAllocator_setExternalOrConstruct(b, external_al, LinearAllocator, 1024);
b->compl_bufs=NULL; Autoarr_construct(&b->compl_bufs, string, 0, InternalAllocator_getPtr(b));
b->curr_buf=Autoarr_construct(i8,BL_C,BL_L); b->curr_buf = createBuffer();
b->total_length = 0;
} }
void StringBuilder_destruct(StringBuilder* b){ void StringBuilder_destruct(StringBuilder* b){
if(b->compl_bufs) Autoarr_destruct(&b->compl_bufs);
Autoarr_destruct(b->compl_bufs, true); allocator_free(InternalAllocator_getPtr(b), b->curr_buf.data);
Autoarr_destruct(b->curr_buf, true);
InternalAllocator_destructIfInternal(LinearAllocator, b); InternalAllocator_destructIfInternal(LinearAllocator, b);
} }
string StringBuilder_build(StringBuilder* b){ string StringBuilder_build(StringBuilder* b){
complete_buf(b); complete_buf(b);
u32 len=0; string str= {
Autoarr_foreach(b->compl_bufs, cs, .length = b->total_length,
len+=cs.length; .ptr = allocator_alloc(InternalAllocator_getPtr(b), b->total_length+1)
); };
string str= { .length=len, .ptr=malloc(len+1) }; str.ptr[b->total_length]='\0';
str.ptr[len]='\0'; char* free_space_ptr = str.ptr;
u32 l=0; Autoarr_foreach(&b->compl_bufs, buf,
Autoarr_foreach(b->compl_bufs, cs, memcpy(free_space_ptr, buf.ptr, buf.length);
memcpy(str.ptr+l, cs.ptr, cs.length); free_space_ptr += buf.length;
l+=cs.length;
); );
StringBuilder_destruct(b); StringBuilder_destruct(b);
return str; return str;
} }
void StringBuilder_rmchar(StringBuilder* b){ void StringBuilder_rmchar(StringBuilder* b){
if(b->curr_buf->chunk_length!=0) if(b->curr_buf.occupied_size != 0)
Autoarr_pop(b->curr_buf) b->curr_buf.occupied_size--;
else { else {
if(!b->compl_bufs) throw(ERR_NULLPTR); for(u32 buf_i = Autoarr_length(&b->compl_bufs) - 1; buf_i != (u32)-1; buf_i--){
string* lastcb=Autoarr_getPtr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1)); string* lastcb = Autoarr_getPtr(&b->compl_bufs, buf_i);
lastcb->length--; if(lastcb->length != 0){
lastcb->length--;
break;
}
}
} }
} }
void StringBuilder_append_char(StringBuilder* b, char c){ 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); 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){ void StringBuilder_append_string(StringBuilder* b, string s){
complete_buf(b); complete_buf(b);
// TODO remove copying Autoarr_add(&b->compl_bufs, s);
Autoarr_add(b->compl_bufs, string_copy(InternalAllocator_getPtr(b), s));
} }
void StringBuilder_append_cptr(StringBuilder* b, char* s){ void StringBuilder_append_cptr(StringBuilder* b, char* s){
string str={ string str={ .ptr=s, .length=cptr_length(s) };
.ptr=s,
.length=cptr_length(s)
};
StringBuilder_append_string(b, str); StringBuilder_append_string(b, str);
} }
void StringBuilder_append_i64(StringBuilder* b, i64 a){ void StringBuilder_append_i64(StringBuilder* b, i64 a){
u8 i=0; StringBuilder_append_cptr(b, toString_i64(InternalAllocator_getPtr(b), a));
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);
} }
void StringBuilder_append_u64(StringBuilder* b, u64 a){ void StringBuilder_append_u64(StringBuilder* b, u64 a){
u8 i=0; StringBuilder_append_cptr(b, toString_u64(InternalAllocator_getPtr(b), a, 0, 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);
} }
void StringBuilder_append_f64(StringBuilder* b, f64 a){ void StringBuilder_append_f64(StringBuilder* b, f64 a){
char buf[32]; StringBuilder_append_cptr(b, toString_f64(InternalAllocator_getPtr(b), a, toString_f64_max_precision, 0, 0));
sprintf_s(buf, sizeof(buf), "%lf", a);
StringBuilder_append_string(b, (string){.ptr=buf, .length=cptr_length(buf)});
} }

View File

@ -9,8 +9,9 @@ extern "C" {
STRUCT(StringBuilder, STRUCT(StringBuilder,
InternalAllocator_declare(LinearAllocator); InternalAllocator_declare(LinearAllocator);
Autoarr(string)* compl_bufs; Autoarr(string) compl_bufs;
Autoarr(i8)* curr_buf; MemoryChunk curr_buf;
u64 total_length;
) )
///@param external_al if null, creates internal allocator ///@param external_al if null, creates internal allocator
@ -22,8 +23,10 @@ void StringBuilder_destruct(StringBuilder* b);
// No need to call string_extract! // No need to call string_extract!
// Destructs StringBuilder. // Destructs StringBuilder.
string StringBuilder_build(StringBuilder* b); string StringBuilder_build(StringBuilder* b);
// removes last char
/// OBSOLETE! Will be removed later
void StringBuilder_rmchar(StringBuilder* b); void StringBuilder_rmchar(StringBuilder* b);
void StringBuilder_append_char(StringBuilder* b, char c); void StringBuilder_append_char(StringBuilder* b, char c);
void StringBuilder_append_cptr(StringBuilder* b, char* s); void StringBuilder_append_cptr(StringBuilder* b, char* s);
void StringBuilder_append_string(StringBuilder* b, string s); void StringBuilder_append_string(StringBuilder* b, string s);

View File

@ -19,18 +19,18 @@
allocator_ptr _internal_al_ptr; allocator_ptr _internal_al_ptr;
/// get pointer to allocator /// 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 /// 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 /// 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 /// create internal allocator and set ptr to it
#define InternalAllocator_construct(STRUCT_PTR, TYPE, CTOR_ARGS...) { \ #define InternalAllocator_construct(STRUCT_PTR, TYPE, CTOR_ARGS...) { \
TYPE##_construct(&STRUCT_PTR->_internal_al, CTOR_ARGS); \ TYPE##_construct(&(STRUCT_PTR)->_internal_al, CTOR_ARGS); \
STRUCT_PTR->_internal_al_ptr = (allocator_ptr)&STRUCT_PTR->_internal_al; \ (STRUCT_PTR)->_internal_al_ptr = (allocator_ptr)&(STRUCT_PTR)->_internal_al; \
} }
/// if EXT_AL_PTR isn't null, set external allocator, otherwise create new /// if EXT_AL_PTR isn't null, set external allocator, otherwise create new