kerep/src/String/StringBuilder.c
2023-07-10 18:31:16 +06:00

127 lines
3.2 KiB
C

#include "StringBuilder.h"
kt_define(StringBuilder, (destruct_t)StringBuilder_destruct, NULL);
#define BL_C 32
#define BL_L 1024
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)
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);
}
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);
}
void StringBuilder_destruct(StringBuilder* b){
if(b->compl_bufs)
Autoarr_destruct(b->compl_bufs, true);
Autoarr_destruct(b->curr_buf, true);
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;
);
StringBuilder_destruct(b);
return str;
}
void StringBuilder_rmchar(StringBuilder* b){
if(b->curr_buf->chunk_length!=0)
Autoarr_pop(b->curr_buf)
else {
if(!b->compl_bufs) throw(ERR_NULLPTR);
string* lastcb=Autoarr_getPtr(b->compl_bufs, (Autoarr_length(b->compl_bufs)-1));
lastcb->length--;
}
}
void StringBuilder_append_char(StringBuilder* b, char c){
if(b->curr_buf->chunks_count==BL_C)
complete_buf(b);
Autoarr_add(b->curr_buf,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));
}
void StringBuilder_append_cptr(StringBuilder* b, char* 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);
}
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);
}
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)});
}