StringBuilder
This commit is contained in:
parent
e7280038fb
commit
5ddc96e1b4
2
cbuild
2
cbuild
@ -1 +1 @@
|
||||
Subproject commit ef6a3f82c429ec232e1b910eecbdece76de933b3
|
||||
Subproject commit 60fa8c11c2673a10f8afbe37bcea13c9be3317b8
|
||||
@ -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)
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user