CBOR-Free
view release on metacpan or search on metacpan
cbor_free_decode.c view on Meta::CPAN
ret = cbf_decode_one( aTHX_ decstate );
_RETURN_IF_SET_INCOMPLETE(decstate, NULL);
if (tagnum == CBOR_TAG_INDIRECTION) {
ret = newRV_noinc(ret);
}
else if (tagnum == CBOR_TAG_SHAREABLE && decstate->reflist) {
++decstate->reflistlen;
Renew( decstate->reflist, decstate->reflistlen, void * );
decstate->reflist[ decstate->reflistlen - 1 ] = (SV *) ret;
}
else if (decstate->tag_handler) {
HV *my_tag_handler = decstate->tag_handler;
SV **handler_cr = hv_fetch( my_tag_handler, (char *) &tagnum, sizeof(UV), 0 );
if (handler_cr && *handler_cr && SvOK(*handler_cr)) {
ret = cbf_call_scalar_with_arguments( aTHX_ *handler_cr, 1, &ret );
}
else {
_warn_unhandled_tag( aTHX_ tagnum, value_major_type );
}
}
else {
_warn_unhandled_tag( aTHX_ tagnum, value_major_type );
}
}
break;
case CBOR_TYPE_OTHER:
switch (control_byte) {
case CBOR_FALSE:
ret = newSVsv( cbf_get_false() );
++decstate->curbyte;
break;
case CBOR_TRUE:
ret = newSVsv( cbf_get_true() );
++decstate->curbyte;
break;
case CBOR_NULL:
case CBOR_UNDEFINED:
ret = &PL_sv_undef;
++decstate->curbyte;
break;
case CBOR_HALF_FLOAT:
_RETURN_IF_INCOMPLETE( decstate, 3, NULL );
ret = newSVnv( decode_half_float( (uint8_t *) (1 + decstate->curbyte) ) );
decstate->curbyte += 3;
break;
case CBOR_FLOAT:
_RETURN_IF_INCOMPLETE( decstate, 5, NULL );
float decoded_flt;
#if IS_LITTLE_ENDIAN
decoded_flt = _decode_float_to_host( aTHX_ decstate, (uint8_t *) (1 + decstate->curbyte ) );
#else
decoded_flt = *( (float *) (1 + decstate->curbyte) );
#endif
ret = newSVnv( (NV) decoded_flt );
decstate->curbyte += 5;
break;
case CBOR_DOUBLE:
_RETURN_IF_INCOMPLETE( decstate, 9, NULL );
double decoded_dbl;
#if IS_LITTLE_ENDIAN
decoded_dbl = _decode_double_to_le( decstate, (uint8_t *) (1 + decstate->curbyte ) );
#else
decoded_dbl = *( (double *) (1 + decstate->curbyte) );
#endif
ret = newSVnv( (NV) decoded_dbl );
decstate->curbyte += 9;
break;
default:
_croak_invalid_control( aTHX_ decstate );
}
break;
default:
_croak("Unknown type!");
}
return ret;
}
/*
* Possible states:
*
* 1) Weâre initializing.
* 2) We just concatâed two SVPVs (same as initializing).
* 3) We just shortened from the beginning.
*/
void renew_decode_state_buffer( pTHX_ decode_ctx *decode_state, SV *cbor ) {
STRLEN cborlen = SvCUR(cbor);
char *cborstr = SvPVX(cbor);
STRLEN offset;
if (decode_state->curbyte == NULL) {
offset = 0;
}
else {
offset = decode_state->curbyte - decode_state->start;
}
decode_state->start = cborstr;
decode_state->size = cborlen;
decode_state->curbyte = cborstr + offset;
decode_state->end = cborstr + cborlen;
}
void advance_decode_state_buffer( pTHX_ decode_ctx *decode_state ) {
STRLEN diff = decode_state->curbyte - decode_state->start;
decode_state->start = decode_state->curbyte;
decode_state->size -= diff;
}
decode_ctx* create_decode_state( pTHX_ SV *cbor, HV *tag_handler, UV flags ) {
decode_ctx *decode_state;
Newx( decode_state, 1, decode_ctx );
decode_state->curbyte = NULL;
if (cbor) {
renew_decode_state_buffer( aTHX_ decode_state, cbor );
}
( run in 0.506 second using v1.01-cache-2.11-cpan-39bf76dae61 )