StringBuilder rewrote

This commit is contained in:
Timerix22 2022-04-20 19:25:19 +03:00
parent 2434a126da
commit 0309f0a3d0
9 changed files with 138 additions and 76 deletions

View File

@ -3,8 +3,6 @@
#define ARR_BC 64 #define ARR_BC 64
#define ARR_BL 1024 #define ARR_BL 1024
#define STRB_BC 64
#define STRB_BL 1024
typedef struct DeserializeSharedData{ typedef struct DeserializeSharedData{
@ -105,7 +103,7 @@ Maybe __ReadName(DeserializeSharedData* shared){
safethrow_wrongchar(c,;); safethrow_wrongchar(c,;);
return SUCCESS(UniPtr(CharPtr,NULL)); return SUCCESS(UniPtr(CharPtr,NULL));
case ':': case ':':
return SUCCESS(UniPtr(CharPtr,string_cpToCptr(nameStr))); return SUCCESS(UniPtr(CharPtr,string_extract(nameStr)));
case '$': case '$':
if(nameStr.length!=0) if(nameStr.length!=0)
safethrow_wrongchar(c,;); safethrow_wrongchar(c,;);
@ -130,19 +128,18 @@ Maybe __ReadValue(DeserializeSharedData* shared);
Maybe __ReadString(DeserializeSharedData* shared){ Maybe __ReadString(DeserializeSharedData* shared){
char c; char c;
bool prevIsBackslash=false; bool prevIsBackslash=false;
StringBuilder* b=StringBuilder_create(STRB_BC,STRB_BL); StringBuilder* b=StringBuilder_create();
while ((c=*++text)){ while ((c=*++text)){
if(c=='"') { if(c=='"') {
if(prevIsBackslash) { if(prevIsBackslash) {
// replacing <\"> with <"> // replacing <\"> with <">
StringBuilder_pop(b); StringBuilder_rmchar(b);
StringBuilder_append_char(b,c); StringBuilder_append_char(b,c);
prevIsBackslash=false; prevIsBackslash=false;
} }
else { else {
char* str=StringBuilder_build(b); char* str=StringBuilder_build(b).ptr;
StringBuilder_free(b);
return SUCCESS(UniPtr(CharPtr,str)); return SUCCESS(UniPtr(CharPtr,str));
} }
} }
@ -188,7 +185,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
break; break;
// Float64 // Float64
case 'f': { case 'f': {
char* _c=string_cpToCptr(str); char* _c=string_extract(str);
Unitype rez=Uni(Float64,strtod(_c,NULL)); Unitype rez=Uni(Float64,strtod(_c,NULL));
free(_c); free(_c);
return SUCCESS(rez); return SUCCESS(rez);
@ -196,7 +193,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
// UInt64 // UInt64
case 'u': { case 'u': {
uint64 lu=0; uint64 lu=0;
char* _c=string_cpToCptr(str); char* _c=string_extract(str);
if(sscanf(_c,"%lu",&lu)!=1){ if(sscanf(_c,"%lu",&lu)!=1){
char err[64]; char err[64];
IFWIN( IFWIN(
@ -212,7 +209,7 @@ Maybe __ParseValue(DeserializeSharedData* shared, string str){
case '0': case '1': case '2': case '3': case '4': case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': { case '5': case '6': case '7': case '8': case '9': {
int64 li=0; int64 li=0;
char* _c=string_cpToCptr(str); char* _c=string_extract(str);
if(sscanf(_c,"%li",&li)!=1){ if(sscanf(_c,"%li",&li)!=1){
char err[64]; char err[64];
IFWIN( IFWIN(

View File

@ -1,9 +1,6 @@
#include "DtsodV24.h" #include "DtsodV24.h"
#include "../String/StringBuilder.h" #include "../String/StringBuilder.h"
// 65536 max length!
#define STRB_BC 64
#define STRB_BL 1024
typedef struct SerializeSharedData{ typedef struct SerializeSharedData{
StringBuilder* sh_builder; StringBuilder* sh_builder;
@ -35,7 +32,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
addc('u'); addc('u');
break; break;
case Float64: case Float64:
StringBuilder_append_double(b,u.Float64); StringBuilder_append_float64(b,u.Float64);
addc('f'); addc('f');
break; break;
case CharPtr: case CharPtr:
@ -64,7 +61,7 @@ Maybe __AppendValue(SerializeSharedData* shared, Unitype u){
try(AppendValue(e),__,;); try(AppendValue(e),__,;);
addc(','); addc(',');
})); }));
StringBuilder_pop(b); StringBuilder_rmchar(b);
addc('\n'); addc('\n');
tabs--; tabs--;
AppendTabs(); AppendTabs();
@ -106,9 +103,8 @@ Maybe __serialize(StringBuilder* _b, uint8 _tabs, Hashtable* dtsod){
} }
Maybe DtsodV24_serialize(Hashtable* dtsod){ Maybe DtsodV24_serialize(Hashtable* dtsod){
StringBuilder* sb=StringBuilder_create(STRB_BC,STRB_BL); StringBuilder* sb=StringBuilder_create();
try(__serialize(sb,0,dtsod),__, StringBuilder_free((sb))); try(__serialize(sb,0,dtsod),__, StringBuilder_free(sb));
char* str=StringBuilder_build(sb); char* str=StringBuilder_build(sb).ptr;
StringBuilder_free((sb));
return SUCCESS(UniPtr(CharPtr, str)); return SUCCESS(UniPtr(CharPtr, str));
} }

View File

@ -1,42 +1,109 @@
#include "StringBuilder.h" #include "StringBuilder.h"
StringBuilder* StringBuilder_create(uint16 max_blocks_count, uint16 max_block_length){ define_Autoarr(string)
return Autoarr_create(int8,max_blocks_count,max_block_length);
#define MAXLENGTH 32768
#define BL_C 32
#define BL_L 1024
void complete_buf(StringBuilder* b){
if(!b->compl_bufs)
b->compl_bufs=Autoarr_create(string,BL_C,BL_L);
uint32 len=Autoarr_length(b->curr_buf);
if(!len) return;
string str={.length=len, .ptr=malloc(len)};
uint32 i=0;
Autoarr_foreach(b->curr_buf, c, ({
str.ptr[i++]=c;
}));
Autoarr_add(b->compl_bufs,str);
Autoarr_free(b->curr_buf);
b->curr_buf=Autoarr_create(int8,BL_C,BL_L);
}
void try_complete_buf(StringBuilder* b){
if(b->curr_buf->blocks_count==BL_C)
complete_buf(b);
}
StringBuilder* StringBuilder_create(){
StringBuilder* b=malloc(sizeof(StringBuilder));
b->compl_bufs=NULL;
b->curr_buf=Autoarr_create(int8,BL_C,BL_L);
return b;
} }
void StringBuilder_free(StringBuilder* b){ void StringBuilder_free(StringBuilder* b){
Autoarr_free(b); if(b->compl_bufs) Autoarr_free(b->compl_bufs);
Autoarr_free(b->curr_buf);
free(b);
} }
void StringBuilder_pop(StringBuilder* b){ string StringBuilder_build(StringBuilder* b){
Autoarr_pop(b); complete_buf(b);
uint32 len=0;
Autoarr_foreach(b->compl_bufs, cs, ({
len+=cs.length;
}));
string str= { .length=len, .ptr=malloc(len+1) };
str.ptr[len]='\0';
uint32 i=0;
Autoarr_foreach(b->compl_bufs, cs, ({
for(uint32 n=0;n<cs.length;n++)
str.ptr[i++]=cs.ptr[n];
free(cs.ptr);
}));
StringBuilder_free(b);
return str;
} }
void StringBuilder_rmchar(StringBuilder* b){
if(b->curr_buf->block_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){ void StringBuilder_append_char(StringBuilder* b, char c){
Autoarr_add(b,c); try_complete_buf(b);
Autoarr_add(b->curr_buf,c);
}
void StringBuilder_append_string(StringBuilder* b, string s){
complete_buf(b);
Autoarr_add(b->compl_bufs, string_copy(s));
} }
void StringBuilder_append_cptr(StringBuilder* b, char* s){ void StringBuilder_append_cptr(StringBuilder* b, char* s){
char c; string str={
while((c=*s++)) .ptr=s,
Autoarr_add(b,c); .length=cptr_length(s)
};
StringBuilder_append_string(b,str);
} }
void StringBuilder_append_string(StringBuilder* b, string s){ void curr_buf_add_string(StringBuilder* b, string s){
while(s.length>0){ for(uint32 i=0; i<s.length; i++)
Autoarr_add(b,*s.ptr++); Autoarr_add(b->curr_buf,s.ptr[i]);
s.length--;
}
} }
void StringBuilder_append_int64(StringBuilder* b, int64 a){ void StringBuilder_append_int64(StringBuilder* b, int64 a){
try_complete_buf(b);
uint8 i=0; uint8 i=0;
if(a==0){ if(a==0){
Autoarr_add(b,'0'); Autoarr_add(b->curr_buf,'0');
return; return;
} }
else if(a<0){ else if(a<0){
Autoarr_add(b,'-'); Autoarr_add(b->curr_buf,'-');
a=-a; a=-a;
} }
char buf[24]; char buf[24];
@ -45,14 +112,15 @@ void StringBuilder_append_int64(StringBuilder* b, int64 a){
a/=10; a/=10;
} }
string rev=string_reverse((string){buf,i}); string rev=string_reverse((string){buf,i});
StringBuilder_append_string(b,rev); curr_buf_add_string(b,rev);
free(rev.ptr); free(rev.ptr);
} }
void StringBuilder_append_uint64(StringBuilder* b, uint64 a){ void StringBuilder_append_uint64(StringBuilder* b, uint64 a){
try_complete_buf(b);
uint8 i=0; uint8 i=0;
if(a==0){ if(a==0){
Autoarr_add(b,'0'); Autoarr_add(b->curr_buf,'0');
return; return;
} }
char buf[24]; char buf[24];
@ -61,24 +129,17 @@ void StringBuilder_append_uint64(StringBuilder* b, uint64 a){
a/=10; a/=10;
} }
string rev=string_reverse((string){buf,i}); string rev=string_reverse((string){buf,i});
StringBuilder_append_string(b,rev); curr_buf_add_string(b,rev);
free(rev.ptr); free(rev.ptr);
} }
void StringBuilder_append_double(StringBuilder* b, double a){ void StringBuilder_append_float64(StringBuilder* b, double a){
try_complete_buf(b);
char buf[32]; char buf[32];
IFWIN( IFWIN(
sprintf_s(buf,32,"%lf",a), sprintf_s(buf,32,"%lf",a),
sprintf(buf,"%lf",a) sprintf(buf,"%lf",a)
); );
StringBuilder_append_cptr(b,buf); StringBuilder_append_cptr(b,buf);
} curr_buf_add_string(b, (string){.ptr=buf, .length=cptr_length(buf)});
char* StringBuilder_build(StringBuilder* b){
uint32 len=Autoarr_length(b);
char* str=malloc(len+1);
str[len]=0;
for(uint32 i=0;i<len;i++)
str[i]=Autoarr_get(b,i);
return str;
} }

View File

@ -7,18 +7,28 @@ extern "C" {
#include "../Autoarr/Autoarr.h" #include "../Autoarr/Autoarr.h"
#include "../String/string.h" #include "../String/string.h"
typedef Autoarr(int8) StringBuilder; declare_Autoarr(string)
StringBuilder* StringBuilder_create(uint16 max_blocks_count, uint16 max_block_length); typedef struct StringBuilder{
Autoarr(string)* compl_bufs;
Autoarr(int8)* curr_buf;
} StringBuilder;
StringBuilder* StringBuilder_create(void);
void StringBuilder_free(StringBuilder* b); void StringBuilder_free(StringBuilder* b);
void StringBuilder_pop(StringBuilder* b); // Joins all strings from compl_bufs.
// Returns zero-terminated string.
// No need to call string_extract()!
// Frees StringBuilder.
string StringBuilder_build(StringBuilder* b);
// removes last char
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);
void StringBuilder_append_int64(StringBuilder* b, int64 a); void StringBuilder_append_int64(StringBuilder* b, int64 a);
void StringBuilder_append_uint64(StringBuilder* b, uint64 a); void StringBuilder_append_uint64(StringBuilder* b, uint64 a);
void StringBuilder_append_double(StringBuilder* b, double a); void StringBuilder_append_float64(StringBuilder* b, double a);
char* StringBuilder_build(StringBuilder* b);
#if __cplusplus #if __cplusplus
} }

View File

@ -1,7 +1,7 @@
#include "../String/string.h" #include "../String/string.h"
// copies str content to new char pointer value (adding '\0' at the end) // copies str content to new char pointer value (adding '\0' at the end)
char* string_cpToCptr(string str){ char* string_extract(string str){
if(str.length==0) return NULL; if(str.length==0) return NULL;
char* cptr=malloc(str.length*sizeof(char)+1); char* cptr=malloc(str.length*sizeof(char)+1);
cptr[str.length]=0; cptr[str.length]=0;
@ -10,15 +10,15 @@ char* string_cpToCptr(string str){
return cptr; return cptr;
} }
// copies cptr content (excluding '\0' at the end) to new string // copies src.ptr content to new string
string string_cpFromCharPtr(char* cptr){ string string_copy(string src){
if(!cptr) return stringNull; if(!src.ptr) return src;
string str; string nstr;
str.length=cptr_length(cptr)-1; nstr.length=src.length;
str.ptr=malloc(str.length); nstr.ptr=malloc(nstr.length);
for(uint32 i=0;i<str.length;i++) for(uint32 i=0;i<nstr.length;i++)
str.ptr[i]=cptr[i]; nstr.ptr[i]=src.ptr[i];
return str; return nstr;
} }
// compares two strings, NullPtr-friendly // compares two strings, NullPtr-friendly

View File

@ -16,10 +16,10 @@ typedef struct string{
static const string stringNull={NULL,0}; static const string stringNull={NULL,0};
// copies str content to new char pointer value (adding '\0' at the end) // copies str content to new char pointer value (adding '\0' at the end)
char* string_cpToCptr(string str); char* string_extract(string str);
// copies cptr content (excluding '\0' at the end) to new string // copies src.ptr content to new string
string string_cpFromCharPtr(char* cptr); string string_copy(string src);
// compares two strings, NullPtr-friendly // compares two strings, NullPtr-friendly
bool string_compare(string str0, string str1); bool string_compare(string str0, string str1);

View File

@ -1,16 +1,16 @@
#include "base.h" #include "base.h"
// returns length of string (including \0) // returns length of char buffer (without \0)
uint32 cptr_length(char* str){ uint32 cptr_length(char* str){
uint32 len=0; uint32 len=0;
while(*(str++)) len++; while(*(str++)) len++;
return ++len; return len;
} }
// allocates new char[] and copies src there // allocates new char[] and copies src there
char* cptr_copy(char* src){ char* cptr_copy(char* src){
uint32 len=cptr_length(src); uint32 len=cptr_length(src);
char* dst=malloc(len*sizeof(char)); char* dst=malloc(len+1);
while(len-->0) while(len-->0)
dst[len]=src[len]; dst[len]=src[len];
return dst; return dst;

View File

@ -6,7 +6,7 @@ extern "C" {
#include "types.h" #include "types.h"
// returns length of string (including \0) // returns length of char buffer (without \0)
uint32 cptr_length(char* str); uint32 cptr_length(char* str);
// allocates new char[] and copies src there // allocates new char[] and copies src there

View File

@ -5,12 +5,10 @@ void test_string(){
optime(__func__,1,({ optime(__func__,1,({
printf("\e[96m-------------[test_string]-------------\n"); printf("\e[96m-------------[test_string]-------------\n");
char c[]="0123456789abcdef"; char c[]="0123456789abcdef";
string s=string_cpFromCharPtr(c); string s={.ptr=c, .length=cptr_length(c)};
printf("\e[92m\"%s\" \e[94m-> string_cpFromCharPtr()\n",c); if(s.length!=sizeof(c)-1) throw("string created with incorrect length");
if(s.length!=16) throw("string created with incorrect length"); char* p=string_extract(s);
char* p=string_cpToCptr(s); printf("\e[94mstring_extract() -> \e[92m\"%s\"\n",p);
printf("\e[94mstring_cpToCptr() -> \e[92m\"%s\"\n",p);
free(p); free(p);
free(s.ptr);
})); }));
} }