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"
// 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)

View File

@ -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));
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));
}

View File

@ -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);

View File

@ -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