JSON-SL

 view release on metacpan or  search on metacpan

SL.xs  view on Meta::CPAN

        die("eh? (RETURN_RESULTS)"); \
        result_count = 0; \
        break; \
    }




MODULE = JSON::SL PACKAGE = JSON::SL PREFIX = PLJSONSL_

PROTOTYPES: DISABLED

BOOT:
{
    MY_CXT_INIT;
    POPULATE_CXT;
    PLJSONSL_ESCTBL_INIT(ESCTBL);
}

SV *
PLJSONSL_new(SV *pkg, ...)
    PREINIT:
    PLJSONSL *pjsn;
    SV *ptriv, *retrv;
    int levels;
    dMY_CXT;
    CODE:
    (void)pkg;
    if (items > 1) {
        if (!SvIOK(ST(1))) {
            die("Second argument (if provided) must be numeric");
        }
        levels = SvIV(ST(1));
        if (levels < 2) {
            die ("Levels must be at least 2");
        }
    } else {
        levels = PLJSONSL_MAX_DEFAULT;
    }

    Newxz(pjsn, 1, PLJSONSL);
    pljsonsl_common_initialize(&MY_CXT, pjsn, levels);
    ptriv = newSViv(PTR2IV(pjsn));
    retrv = newRV_noinc(ptriv);
    sv_bless(retrv, MY_CXT.stash_obj);
    pjsn->buf = newSVpvn("", 0);

    jsonsl_enable_all_callbacks(pjsn->jsn);
    pjsn->jsn->action_callback = initial_callback;
    pjsn->jsn->error_callback = error_callback;

    pjsn->results = newAV();
    PLJSONSL_INIT_KSV(pjsn);
    RETVAL = retrv;

    OUTPUT: RETVAL


void
PLJSONSL_set_jsonpointer(PLJSONSL *pjsn, AV *paths)
    PPCODE:
    pljsonsl_set_jsonpointer(pjsn, paths);

SV *
PLJSONSL_root(PLJSONSL *pjsn)
    CODE:
    if (pjsn->root) {
        RETVAL = newRV_inc(pjsn->root);
    } else {
        RETVAL = &PL_sv_undef;
    }
    OUTPUT: RETVAL

void
PLJSONSL__modify_readonly(PLJSONSL *pjsn, SV *ref)
    ALIAS:
    make_referrent_writeable = 1
    make_referrent_readonly = 2
    CODE:
    if (!SvROK(ref)) {
        die("Variable is not a reference!");
    }
    if (ix == 0) {
        PLJSONSL_CROAK_USAGE("use make_referrent_writeable or make_referrent_readonly");
    } else if (ix == 1) {
        SvREADONLY_off(SvRV(ref));
    } else if (ix == 2) {
        SvREADONLY_on(SvRV(ref));
    }

int
PLJSONSL_referrent_is_writeable(PLJSONSL *pjsn, SV *ref)
    CODE:
    if (!SvROK(ref)) {
        die("Variable is not a reference!");
    }
    RETVAL = SvREADONLY(SvRV(ref)) == 0;
    OUTPUT: RETVAL


void
PLJSONSL_feed(PLJSONSL *pjsn, SV *input)
    ALIAS:
    incr_parse =1

    PPCODE:
    {
    dRESULT_VARS;
    pljsonsl_feed_incr(pjsn, input);
    RETURN_RESULTS(pjsn);
    }

void
PLJSONSL_fetch(PLJSONSL *pjsn)
    PPCODE:
    {
    dRESULT_VARS;
    RETURN_RESULTS(pjsn);
    }

int
PLJSONSL__escape_table_chr(PLJSONSL *pjsn, U8 chrc, ...)
    CODE:
    if (chrc > 0x7f) {
        warn("Attempted to set non-ASCII escape preference");
        RETVAL = -1;
    } else {
        RETVAL = pjsn->escape_table[chrc];
        if (items == 3) {
            pjsn->escape_table[chrc] = SvIV(ST(2));
        }
    }
    OUTPUT: RETVAL

void
PLJSONSL_reset(PLJSONSL *pjsn)
    CODE:
    REFDEC_FIELD(pjsn, root);

    if (pjsn->results) {
        av_clear(pjsn->results);
    }
    if (pjsn->buf) {
        SvCUR_set(pjsn->buf, 0);
    }

    jsonsl_reset(pjsn->jsn);
    pjsn->pos_min_valid = 0;
    pjsn->keep_pos = 0;
    pjsn->curhk = NULL;
    pjsn->jsn->action_callback_PUSH = initial_callback;

SV*
PLJSONSL_root_callback(PLJSONSL *pjsn, SV *callback)
    CODE:
    RETVAL = pjsn->options.root_callback;
    if (RETVAL) {
        SvREFCNT_inc(RETVAL);
    } else {
        RETVAL = &PL_sv_undef;
    }

    if (SvTYPE(callback) == SVt_NULL) {
        if (pjsn->options.root_callback) {
            SvREFCNT_dec(pjsn->options.root_callback);
            pjsn->options.root_callback = NULL;
        }
    } else {
        if (SvTYPE(callback) != SVt_RV ||
                SvTYPE(SvRV(callback)) != SVt_PVCV) {
            die("Second argument must be undef or a CODE ref");
        }
        if (pjsn->options.root_callback) {
            SvREFCNT_dec(pjsn->options.root_callback);
        }
        pjsn->options.root_callback = newRV_inc(SvRV(callback));
    }

    OUTPUT: RETVAL

void
PLJSONSL_DESTROY(PLJSONSL *pjsn)
    PREINIT:
    int ii;

    CODE:
    if (pjsn->priv_global.is_global == 0) {
        REFDEC_FIELD(pjsn, root);
        REFDEC_FIELD(pjsn, results);
        REFDEC_FIELD(pjsn, buf);
        REFDEC_FIELD(pjsn, options.root_callback);
    } /* else, it's a mortal and shouldn't be freed */
    jsonsl_jpr_match_state_cleanup(pjsn->jsn);
    if (pjsn->jprs) {
        for ( ii = 0; ii < pjsn->njprs; ii++) {
            if (pjsn->jprs[ii] == NULL) {
                break;
            }
            jsonsl_jpr_destroy(pjsn->jprs[ii]);
        }
        Safefree(pjsn->jprs);
        pjsn->jprs = NULL;
    }
    if (pjsn->jsn) {
        jsonsl_destroy(pjsn->jsn);
        pjsn->jsn = NULL;
    }
    PLJSONSL_DESTROY_KSV(pjsn);
    Safefree(pjsn);

void
PLJSONSL_decode_json(SV *input)
    PREINIT:
    PLJSONSL* pjsn;
    dRESULT_VARS;

    PPCODE:
    pjsn = pljsonsl_get_and_initialize_global(aTHX);
    pljsonsl_feed_oneshot(pjsn, input);

    pjsn->curhk = NULL;
    pjsn->keep_pos = 0;
    pjsn->pos_min_valid = 0;
    pjsn->jsn->action_callback_PUSH = initial_callback;

    RETURN_RESULTS(pjsn);
    if (result_count == 0 && av_len(pjsn->results) == -1) {
        die("Incomplete JSON string?");
    }

SV *
PLJSONSL_unescape_json_string(SV *input)
    PREINIT:
    size_t origlen, newlen;
    SV *retsv = NULL;
    char *errpos;
    jsonsl_error_t err;
    jsonsl_special_t flags;

    CODE:
    if (!SvPOK(input)) {
        die("Input is not a valid string");
    }
    origlen = SvCUR(input);
    if (origlen) {
        retsv = newSV(origlen);
        newlen = jsonsl_util_unescape_ex(SvPVX_const(input), SvPVX(retsv),
                                    SvCUR(input), ESCTBL, &flags,
                                    &err, (const char**)&errpos);
        if (newlen == 0) {
            SvREFCNT_dec(retsv);
            die("Could not unescape: %s at pos %lu ('%c'..)",
                jsonsl_strerror(err),
                errpos - SvPVX_const(input),
                *errpos
            );
        }

        SvCUR_set(retsv, newlen);
        SvPOK_only(retsv);
        if (SvUTF8(input) || (flags & JSONSL_SPECIALf_NONASCII)) {
            SvUTF8_on(retsv);
        }
    } else {
        retsv = &PL_sv_undef;
    }
    RETVAL = retsv;
    OUTPUT: RETVAL



void
PLJSONSL_CLONE(PLJSONSL *pjsn)
    CODE:
    {
    MY_CXT_CLONE;
    POPULATE_CXT;



( run in 0.524 second using v1.01-cache-2.11-cpan-5511b514fd6 )