JSON-SIMD
view release on metacpan or search on metacpan
encode_str (enc, str, len, SvUTF8 (sv));
}
else
encode_str (enc, HeKEY (he), HeKLEN (he), HeKUTF8 (he));
encode_ch (enc, '"');
if (enc->json.flags & F_SPACE_BEFORE) encode_space (enc);
encode_ch (enc, ':');
if (enc->json.flags & F_SPACE_AFTER ) encode_space (enc);
}
// compare hash entries, used when all keys are bytestrings
static int
he_cmp_fast (const void *a_, const void *b_)
{
int cmp;
HE *a = *(HE **)a_;
HE *b = *(HE **)b_;
STRLEN la = HeKLEN (a);
STRLEN lb = HeKLEN (b);
if (!(cmp = memcmp (HeKEY (b), HeKEY (a), lb < la ? lb : la)))
cmp = lb - la;
return cmp;
}
// compare hash entries, used when some keys are sv's or utf-x
static int
he_cmp_slow (const void *a, const void *b)
{
return sv_cmp (HeSVKEY_force (*(HE **)b), HeSVKEY_force (*(HE **)a));
}
static void
encode_hv (enc_t *enc, HV *hv)
{
HE *he;
if (enc->indent >= enc->json.max_depth)
croak (ERR_NESTING_EXCEEDED);
encode_ch (enc, '{');
// for canonical output we have to sort by keys first
// actually, this is mostly due to the stupid so-called
// security workaround added somewhere in 5.8.x
// that randomises hash orderings
if (enc->json.flags & F_CANONICAL && !SvRMAGICAL (hv))
{
int count = hv_iterinit (hv);
if (SvMAGICAL (hv))
{
// need to count by iterating. could improve by dynamically building the vector below
// but I don't care for the speed of this special case.
// note also that we will run into undefined behaviour when the two iterations
// do not result in the same count, something I might care for in some later release.
count = 0;
while (hv_iternext (hv))
++count;
hv_iterinit (hv);
}
if (count)
{
int i, fast = 1;
HE *hes_stack [STACK_HES];
HE **hes = hes_stack;
// allocate larger arrays on the heap
if (count > STACK_HES)
{
SV *sv = sv_2mortal (NEWSV (0, count * sizeof (*hes)));
hes = (HE **)SvPVX (sv);
}
i = 0;
while ((he = hv_iternext (hv)))
{
hes [i++] = he;
if (HeKLEN (he) < 0 || HeKUTF8 (he))
fast = 0;
}
assert (i == count);
if (fast)
qsort (hes, count, sizeof (HE *), he_cmp_fast);
else
{
// hack to forcefully disable "use bytes"
COP cop = *PL_curcop;
cop.op_private = 0;
ENTER;
SAVETMPS;
SAVEVPTR (PL_curcop);
PL_curcop = &cop;
qsort (hes, count, sizeof (HE *), he_cmp_slow);
FREETMPS;
LEAVE;
}
encode_nl (enc); ++enc->indent;
while (count--)
{
encode_indent (enc);
he = hes [count];
encode_hk (enc, he);
encode_sv (enc, expect_false (SvMAGICAL (hv)) ? hv_iterval (hv, he) : HeVAL (he));
( run in 1.759 second using v1.01-cache-2.11-cpan-71847e10f99 )