Cpanel-JSON-XS

 view release on metacpan or  search on metacpan

XS.xs  view on Meta::CPAN


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 {

XS.xs  view on Meta::CPAN

        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));

XS.xs  view on Meta::CPAN

        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);

XS.xs  view on Meta::CPAN

              {
                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),

XS.xs  view on Meta::CPAN

              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

XS.xs  view on Meta::CPAN

            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 )