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 )