stredit - auto growing str/bin buffer. fast.
typedef struct stredit_tag {
char* p;
int ofst;
int sz;
int msz;
// ..and inner_data
} se_t;
se_t*
se_new(void);
se_t*
se_free(se_t*
obj); //macro: >> (se_freeXX(obj), obj=NULL)
int se_ins(se_t*
obj,
int cur,
const char*
bin [,
int binsz]
);
int se_insf(se_t*
obj,
int
cur,
const char*
fmt, ...
);
int se_del(se_t*
obj,
int cur,
int dcnt);
char*
se_ptr(obj); // get str/data
head ptr. obj->p.
int se_sz(obj); // data sz.
obj->sz.
int se_clear(se_t*
obj); //rtn
some int val
- obj
- mainstruct. holds malloc()ed ptr, memsz etc
- cur
- edit cursor pos
- bin
- str/bin you want to add
- binsz
- addsize >= -2. -1:strlen(bin), -2:strlen(bin)+1.
- fmt
- printf() fmt
- dcnt
- del byte size. dcnt<0 / 0<dcnt == bs-key/del-key
#include <stdio.h>
#include "stredit.h"
int main() {
se_t* obj = se_new(); // ""
int rc= se_ins(obj, -1, "foo"); // "foo", rc=3(strsz), -1 == end
char* p = se_ptr(obj); // get headptr
puts(p); // >> 'foo'
int sz = se_sz(obj); // >> 3
se_ins(obj, 1, "ZZZ"); // f|oo + ZZZ, "fZZZoo", 1 == inspos
rc = se_ins(obj, 0, "baz"); // "bazfZZZoo", rc=3
se_ins(obj, -1, "\0abc"); // "bazfZZZoo", read as str if ag4 isnt
se_ins(obj, 0, "\0abc", 2); // "(\0)abazfZZZoo", rc==2
sz = se_sz(obj); // 11, sz is holding bin size
se_clear(obj); // "", rc = 0
se_insf(obj, 0, "%#x",17); // "0x11", printf() fmt
se_insf(obj, -1, "\0"); // "0x11", rc=0
se_insf(obj, -1, "%c", 0); // "0x11(\0)", rc=1
se_del(obj, 1, 2); // "01(\0)" , cur==1, del 2byte. rc=2
se_del(obj, -1, -2); // "0" , rc=2. -1==tail, -2 == bs 2byte. rc=2
puts(obj->p); // "01"
se_ins(obj, 0, obj->p); // >> "0101", allow to use inner ptr
se_insf(obj, 1, "%s", obj->p); // >> "0_01011,
se_free(obj); // (free_XX(obj), obj=NULL);
return 0;
}
// ~$ gcc src.c stredit.c
se_ins/se_insf/se_del: edit byte int size
se_clear: some int val
se_new/se_free: new/freed se_t* ptr
stredit is string buffer for general purpose, add/del/ins/clear chars. buffsz is
automatically realloc()ed. see samples for detail usage.
input data/str is always terminated with '\0'. this last byte is out of se_sz()
cnt.
- puts(se_ptr(obj)) never causes SEGV err.
se_ins(obj, 0, "foo"); // sz=3 puts(se_ptr(obj) ) >> "foo"
se_ins(obj, 0, "\0ab",4); // sz=7 puts(se_ptr(obj) ) >> "foo"
se_clear(obj); // sz=0 puts(se_ptr(obj) ) >> ""
se_ins(obj, 0, "bar"); // sz=3 puts(se_ptr(obj) ) >> "bar"
- str editting funcs rtns added sz as printf()
se_t* obj = se_new();
char* s = "hw";
int p1 = se_ins(obj, s, strlen(s)+1 ); //+1=='\0', p1==3
s = "gw";
int p2 = se_ins(obj, s, -2 ); //-2==slen(s)+1, p2==3, "hw(\0)gw(\0)"
puts( se_ptr(strpool)+p1 ); //>>gw
puts( strpool->p ); //>>hw
- se_clear() doesnt shrink heap
- sloppy benchmark:
FAST: strdup/se_ins(1) > se_insf(5) >>> asprintf(300) >>> libapr(1000) :SLOW
code: while(i-- >0){ se_ins(obj, "123"); }, loop(1*1000*1000) etc
100.466 ms: msg:se_ins(abc) lp: 1*1000*1000
517.152 ms: msg:se_insf(abc) lp: 1*1000*1000
118.990 ms: msg:strdup(abc) loop1*1000*1000
(too slow + causes memclash)
244.710 ms : msg:gnu asprintf(), x10 == 2.4s (lp: 10*1000)
978.828 ms : msg:apr_psprintf(), x10 == 9.7s (lp: 10*1000)
-
posix-2001+
2022-07-10 v1.0.2 (2021-06-25 v1.0.0)