JSON-XS-ByteString

 view release on metacpan or  search on metacpan

ByteString.xs  view on Meta::CPAN

            break;
        }
        case '"': case '\'': {
            unsigned char *value_buffer=0, *value_buffer_end, *value_end;
            str = decode_str_r(str, str_end, &value_buffer, &value_buffer_end, &value_end);
            if( !value_end )
                goto GIVEUP;
            *out = newSV(0);
            sv_upgrade(*out, SVt_PV);
            SvPOK_on(*out);
            SvPV_set(*out, (char*)value_buffer);
            SvCUR_set(*out, value_end - value_buffer);
            SvLEN_set(*out, value_buffer_end - value_buffer);
            return str;
        }
        default: {
            if( str_end-str==4 || (str_end-str>4 && !is_identity(str[4])) ){
                if( (str[0]=='T' || str[0]=='t') && (str[1]=='R' || str[1]=='r') && (str[2]=='U' || str[2]=='u') && (str[3]=='E' || str[3]=='e') ){
                    *out = newSViv(1);
                    return str+4;
                }
                if( (str[0]=='N' || str[0]=='n') && (str[1]=='U' || str[1]=='u') && (str[2]=='L' || str[2]=='l') && (str[3]=='L' || str[3]=='l') ){
                    *out = newSV(0);
                    return str+4;
                }
            }
            if( str_end-str==5 || (str_end-str>5 && !is_identity(str[5])) ){
                if( (str[0]=='F' || str[0]=='f') && (str[1]=='A' || str[1]=='a') && (str[2]=='L' || str[2]=='l') && (str[3]=='S' || str[3]=='s') && (str[4]=='E' || str[4]=='e') ){
                    *out = newSVpvn("", 0);
                    return str+5;
                }
            }

            unsigned char *value_buffer=0, *value_buffer_end, *value_end;
            str = decode_number_r(str, str_end, &value_buffer, &value_buffer_end, &value_end);
            if( value_end ){
                *out = newSV(0);
                sv_upgrade(*out, SVt_PV);
                SvPOK_on(*out);
                SvPV_set(*out, (char*)value_buffer);
                SvCUR_set(*out, value_end - value_buffer);
                SvLEN_set(*out, value_buffer_end - value_buffer);
                return str;
            }

            goto GIVEUP;
        }
    }

ROLLBACK:
    SvREFCNT_dec_NN(*out);
GIVEUP:
    *out = NULL;
    return str;
}

MODULE = JSON::XS::ByteString		PACKAGE = JSON::XS::ByteString		

void
encode_json(SV * data)
    PPCODE:
        visited_p = 0;
        STRLEN need_size = estimate_normal(data);
        SV * out_sv = sv_2mortal(newSV(need_size));
        SvPOK_only(out_sv);
        visited_p = 0;
        char * cur = (char*)encode_normal((unsigned char*)SvPVX(out_sv), data);
        SvCUR_set(out_sv, cur - SvPVX(out_sv));
        *SvEND(out_sv) = 0;
        PUSHs(out_sv);

void
encode_json_unblessed(SV * data)
    PPCODE:
        visited_p = 0;
        STRLEN need_size = estimate_unblessed(data);
        SV * out_sv = sv_2mortal(newSV(need_size));
        SvPOK_only(out_sv);
        visited_p = 0;
        char * cur = (char*)encode_unblessed((unsigned char*)SvPVX(out_sv), data);
        SvCUR_set(out_sv, cur - SvPVX(out_sv));
        *SvEND(out_sv) = 0;
        PUSHs(out_sv);

void
decode_json(SV * json)
    PPCODE:
        unsigned char *str, *str_end, *str_adv;
        STRLEN len;
        SV * out = NULL;
        str = (unsigned char*) SvPV(json, len);
        str_end = str + len;
        str_adv = skip_space(decode(skip_bom(str, str_end), str_end, &out), str_end);
        if( str_end != str_adv ){
            warn("decode_json: Unconsumed characters from offset %d", (int)(str_adv-str));
            SvREFCNT_dec(out);
            PUSHs(&PL_sv_undef);
        }
        else if( out==NULL )
            PUSHs(&PL_sv_undef);
        else
            PUSHs(sv_2mortal(out));

void
decode_json_safe(SV * json)
    PPCODE:
        unsigned char *str, *str_end, *str_adv;
        STRLEN len;
        SV * out = NULL;
        str = (unsigned char*) SvPV(json, len);
        str_end = str + len;
        str_adv = skip_space(decode(skip_bom(str, str_end), str_end, &out), str_end);
        if( str_end != str_adv ){
            SvREFCNT_dec(out);
            PUSHs(&PL_sv_undef);
        }
        else if( out==NULL )
            PUSHs(&PL_sv_undef);
        else
            PUSHs(sv_2mortal(out));

BOOT:
    visited_capacity = 32;
    Newx(visited, visited_capacity, SV*);



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