Cpanel-JSON-XS
view release on metacpan or search on metacpan
PROTOTYPES: DISABLE
#_if PERL_IMPLICIT_CONTEXT for embedding, but no ithreads, then CLONE is never
# called
#ifdef USE_ITHREADS
void CLONE (...)
PPCODE:
MY_CXT_CLONE; /* possible declaration */
init_MY_CXT(aTHX_ &MY_CXT);
/* skip implicit PUTBACK, returning @_ to caller, more efficient*/
return;
#endif
void END(...)
PREINIT:
dMY_CXT;
SV * sv;
PPCODE:
sv = MY_CXT.sv_json;
MY_CXT.sv_json = NULL;
if (sv && SvOK (sv))
SvREFCNT_dec_NN (sv);
/* skip implicit PUTBACK, returning @_ to caller, more efficient*/
return;
void new (char *klass)
PREINIT:
HV *stash;
PPCODE:
dMY_CXT;
SV *pv = NEWSV (0, sizeof (JSON));
SvPOK_only (pv);
json_init ((JSON *)SvPVX (pv));
if (SvROK (ST(0))) {
/* called as $obj->new â extract real class name from the object */
stash = SvSTASH (SvRV (ST(0)));
if (!stash)
croak ("Cannot create a %s object from an unblessed reference", klass);
} else {
allow_barekey = F_ALLOW_BAREKEY
allow_singlequote = F_ALLOW_SQUOTE
allow_bignum = F_ALLOW_BIGNUM
escape_slash = F_ESCAPE_SLASH
allow_stringify = F_ALLOW_STRINGIFY
unblessed_bool = F_UNBLESSED_BOOL
allow_dupkeys = F_ALLOW_DUPKEYS
require_types = F_REQUIRE_TYPES
type_all_string = F_TYPE_ALL_STRING
dupkeys_as_arrayref = F_DUPKEYS_AS_AREF
PPCODE:
if (enable)
self->flags |= ix;
else
self->flags &= ~ix;
# Turning on DUPKEYS_AS_AREF also turns on ALLOW_DUPKEYS
# But turning off DUPKEYS_AS_AREF does not
if (ix == F_DUPKEYS_AS_AREF && enable != 0)
self->flags |= F_ALLOW_DUPKEYS;
XPUSHs (ST (0));
get_allow_barekey = F_ALLOW_BAREKEY
get_allow_singlequote = F_ALLOW_SQUOTE
get_allow_bignum = F_ALLOW_BIGNUM
get_escape_slash = F_ESCAPE_SLASH
get_allow_stringify = F_ALLOW_STRINGIFY
get_unblessed_bool = F_UNBLESSED_BOOL
get_allow_dupkeys = F_ALLOW_DUPKEYS
get_require_types = F_REQUIRE_TYPES
get_type_all_string = F_TYPE_ALL_STRING
get_dupkeys_as_arrayref = F_DUPKEYS_AS_AREF
PPCODE:
XPUSHs (boolSV (self->flags & ix));
void indent_length (JSON *self, int val = INDENT_STEP)
PPCODE:
if (0 <= val && val <= 15) {
self->indent_length = val;
} else {
warn("The acceptable range of indent_length() is 0 to 15.");
}
XPUSHs (ST (0));
U32 get_indent_length (JSON *self)
CODE:
RETVAL = self->indent_length;
OUTPUT:
RETVAL
void max_depth (JSON *self, U32 max_depth = 0x80000000UL)
PPCODE:
self->max_depth = max_depth;
XPUSHs (ST (0));
U32 get_max_depth (JSON *self)
CODE:
RETVAL = self->max_depth;
OUTPUT:
RETVAL
void max_size (JSON *self, U32 max_size = 0)
PPCODE:
self->max_size = max_size;
XPUSHs (ST (0));
int get_max_size (JSON *self)
CODE:
RETVAL = self->max_size;
OUTPUT:
RETVAL
void stringify_infnan (JSON *self, IV infnan_mode = 1)
PPCODE:
if (infnan_mode > 3 || infnan_mode < 0) {
croak ("invalid stringify_infnan mode %d. Must be 0, 1, 2 or 3", (int)infnan_mode);
}
self->infnan_mode = (unsigned char)infnan_mode;
XPUSHs (ST (0));
int get_stringify_infnan (JSON *self)
CODE:
RETVAL = (int)self->infnan_mode;
OUTPUT:
RETVAL
void sort_by (JSON *self, SV* cb = &PL_sv_yes)
PPCODE:
{
SvREFCNT_dec (self->cb_sort_by);
self->cb_sort_by = SvOK (cb) ? newSVsv (cb) : 0;
if (self->cb_sort_by)
self->flags |= F_CANONICAL;
XPUSHs (ST (0));
}
void filter_json_object (JSON *self, SV *cb = &PL_sv_undef)
PPCODE:
{
SvREFCNT_dec (self->cb_object);
self->cb_object = SvOK (cb) ? newSVsv (cb) : 0;
XPUSHs (ST (0));
}
void filter_json_single_key_object (JSON *self, SV *key, SV *cb = &PL_sv_undef)
PPCODE:
{
if (!self->cb_sk_object)
self->cb_sk_object = newHV ();
if (SvOK (cb))
(void)hv_store_ent (self->cb_sk_object, key, newSVsv (cb), 0);
else
{
(void)hv_delete_ent (self->cb_sk_object, key, G_DISCARD, 0);
{
SvREFCNT_dec (self->cb_sk_object);
self->cb_sk_object = 0;
}
}
XPUSHs (ST (0));
}
void encode (JSON *self, SV *scalar, SV *typesv = &PL_sv_undef)
PPCODE:
PUTBACK; scalar = encode_json (aTHX_ scalar, self, typesv); SPAGAIN;
XPUSHs (scalar);
void decode (JSON *self, SV *jsonstr, SV *typesv = NULL)
PPCODE:
PUTBACK; jsonstr = decode_json (aTHX_ jsonstr, self, 0, typesv); SPAGAIN;
XPUSHs (jsonstr);
void decode_prefix (JSON *self, SV *jsonstr, SV *typesv = NULL)
PPCODE:
{
SV *sv;
STRLEN offset;
PUTBACK; sv = decode_json (aTHX_ jsonstr, self, &offset, typesv); SPAGAIN;
EXTEND (SP, 2);
PUSHs (sv);
PUSHs (sv_2mortal (newSVuv (ptr_to_index (aTHX_ jsonstr, offset))));
}
void incr_parse (JSON *self, SV *jsonstr = 0)
PPCODE:
{
if (!self->incr_text)
self->incr_text = newSVpvn ("", 0);
/* if utf8-ness doesn't match the decoder, need to upgrade/downgrade */
if (!DECODE_WANTS_OCTETS (self) == !SvUTF8 (self->incr_text)) {
if (DECODE_WANTS_OCTETS (self))
{
if (self->incr_pos)
self->incr_pos = utf8_length ((U8 *)SvPVX (self->incr_text),
sv_chop (self->incr_text, (char*)endp);
#endif
}
while (GIMME_V == G_ARRAY);
}
#if PERL_VERSION > 6
SV *incr_text (JSON *self)
ATTRS: lvalue
PPCODE:
{
PERL_UNUSED_VAR(RETVAL);
if (UNLIKELY(self->incr_pos))
{
/* We might want to return a copy of the rest.
But incr_parse already chops the start at the end, so this can
only happen on concurrent accesses to incr_parse */
croak ("incr_text can not be called when the incremental parser already started parsing");
}
ST(0) = self->incr_text ? self->incr_text : &PL_sv_undef;
XSRETURN(1);
}
#else
SV *incr_text (JSON *self)
PPCODE:
{
if (UNLIKELY(self->incr_pos))
croak ("incr_text can not be called when the incremental parser already started parsing");
ST(0) = self->incr_text ? self->incr_text : &PL_sv_undef;
XSRETURN(1);
}
#endif
SvREFCNT_dec (self->cb_sort_by);
if (self->incr_text)
SvREFCNT_dec (self->incr_text);
PROTOTYPES: ENABLE
void encode_json (SV *scalar, SV *typesv = &PL_sv_undef)
ALIAS:
_to_json = 0
encode_json = F_UTF8
PPCODE:
{
JSON json;
json_init (&json);
json.flags |= ix;
PUTBACK; scalar = encode_json (aTHX_ scalar, &json, typesv); SPAGAIN;
XPUSHs (scalar);
}
void decode_json (SV *jsonstr, SV *allow_nonref = NULL, SV *typesv = NULL)
ALIAS:
_from_json = 0
decode_json = F_UTF8
PPCODE:
{
JSON json;
json_init (&json);
json.flags |= ix;
if (items > 1) {
/* allow_nonref arg explicitly given: override the default */
if (!SvTRUE (allow_nonref))
json.flags &= ~F_ALLOW_NONREF;
}
PUTBACK; jsonstr = decode_json (aTHX_ jsonstr, &json, 0, typesv); SPAGAIN;
( run in 0.538 second using v1.01-cache-2.11-cpan-71847e10f99 )