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"
|
#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)
|
||||||
|
|||||||
@ -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);
|
||||||
|
if(lastcb->length != 0){
|
||||||
lastcb->length--;
|
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)});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user