Add initial JSON formatter
It works and can format all "plain" Perl data, but has a few known bugs and limitations that still need to be worked out. It's about 8x smaller than JSON::XS's encoder and *much* smaller than Cpanel::JSON::XS, but this is just a first attempt, it'll grow.
This commit is contained in:
parent
9c80f2465a
commit
c16a9fa493
10 changed files with 421 additions and 0 deletions
43
c/common.c
Normal file
43
c/common.c
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/* Custom string builder, comparable to functionality provided by SV*
|
||||
* functions, but with less magic and better inlineable. */
|
||||
|
||||
typedef struct {
|
||||
size_t len;
|
||||
size_t size;
|
||||
char *buf;
|
||||
} fustr;
|
||||
|
||||
/* No need to call this, an empty fustr is already usable.
|
||||
* This allows setting a custom initial size. */
|
||||
static void fustr_init(fustr *s, size_t prealloc) {
|
||||
s->len = 0;
|
||||
s->size = prealloc;
|
||||
s->buf = safemalloc(prealloc);
|
||||
}
|
||||
|
||||
static void fustr_grow(fustr *s, size_t add) {
|
||||
if (s->size == 0) s->size = 512;
|
||||
while (s->size < s->len + add)
|
||||
s->size *= 2;
|
||||
s->buf = saferealloc(s->buf, s->size);
|
||||
}
|
||||
|
||||
#define fustr_reserve(s, n) do {\
|
||||
if (UNLIKELY((s)->size < (s)->len + (n))) fustr_grow(s, n);\
|
||||
} while(0)
|
||||
|
||||
#define fustr_write(s, str, n) do {\
|
||||
fustr_reserve(s, n);\
|
||||
memcpy((s)->buf+(s)->len, str, (n));\
|
||||
(s)->len += (n);\
|
||||
} while(0)
|
||||
|
||||
/* Move the string buffer into a new SV; fustr should be considered invalid after this call.
|
||||
* Does not set the UTF8 flag. */
|
||||
static SV *fustr_sv(fustr *s) {
|
||||
SV *r = newSV(0);
|
||||
fustr_write(s, "", 1); // trailing nul
|
||||
sv_usepvn_flags(r, s->buf, s->len-1, SV_HAS_TRAILING_NUL);
|
||||
// TODO: SvPV_shrink_to_cur?
|
||||
return r;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue