Ejemplo n.º 1
0
int
uper_open_type_skip(asn_codec_ctx_t *ctx, asn_per_data_t *pd) {
	asn_TYPE_descriptor_t s_td;
	asn_dec_rval_t rv;

	s_td.name = "<unknown extension>";
	s_td.uper_decoder = uper_sot_suck;

	rv = uper_open_type_get(ctx, &s_td, 0, 0, pd);
	if(rv.code != RC_OK)
		return -1;
	else
		return 0;
}
Ejemplo n.º 2
0
asn_dec_rval_t
CHOICE_decode_uper(Allocator * allocator, asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
	asn_per_constraints_t *constraints, void **sptr, asn_per_data_t *pd) {
	asn_CHOICE_specifics_t *specs = (asn_CHOICE_specifics_t *)td->specifics;
	asn_dec_rval_t rv;
	asn_per_constraint_t *ct;
	asn_TYPE_member_t *elm;	/* CHOICE's element */
	void *memb_ptr;
	void **memb_ptr2;
	void *st = *sptr;
	int value;

	if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx))
		_ASN_DECODE_FAILED;

	/*
	 * Create the target structure if it is not present already.
	 */
	if(!st) {
		st = *sptr = CXX_ALLOC_WRAP CALLOC(1, specs->struct_size);
		if(!st) _ASN_DECODE_FAILED;
	}

	if(constraints) ct = &constraints->value;
	else if(td->per_constraints) ct = &td->per_constraints->value;
	else ct = 0;

	if(ct && ct->flags & asn_per_constraint_s::APC_EXTENSIBLE) {
		value = per_get_few_bits(pd, 1);
		if(value < 0) _ASN_DECODE_STARVED;
		if(value) ct = 0;	/* Not restricted */
	}

	if(ct && ct->range_bits >= 0) {
		value = per_get_few_bits(pd, ct->range_bits);
		if(value < 0) _ASN_DECODE_STARVED;
		ASN_DEBUG("CHOICE %s got index %d in range %d",
			td->name, value, ct->range_bits);
		if(value > ct->upper_bound)
			_ASN_DECODE_FAILED;
	} else {
		if(specs->ext_start == -1)
			_ASN_DECODE_FAILED;
		value = uper_get_nsnnwn(pd);
		if(value < 0) _ASN_DECODE_STARVED;
		value += specs->ext_start;
		if(value >= td->elements_count)
			_ASN_DECODE_FAILED;
	}

	/* Adjust if canonical order is different from natural order */
	if(specs->canonical_order)
		value = specs->canonical_order[value];

	/* Set presence to be able to free it later */
	_set_present_idx(st, specs->pres_offset, specs->pres_size, value + 1);

	elm = &td->elements[value];
	if(elm->flags & ATF_POINTER) {
		/* Member is a pointer to another structure */
		memb_ptr2 = (void **)((char *)st + elm->memb_offset);
	} else {
		memb_ptr = (char *)st + elm->memb_offset;
		memb_ptr2 = &memb_ptr;
	}
	ASN_DEBUG("Discovered CHOICE %s encodes %s", td->name, elm->name);

	if(ct && ct->range_bits >= 0) {
		rv = elm->type->uper_decoder(allocator, opt_codec_ctx, elm->type,
			elm->per_constraints, memb_ptr2, pd);
	} else {
		rv = uper_open_type_get(allocator, opt_codec_ctx, elm->type,
			elm->per_constraints, memb_ptr2, pd);
	}

	if(rv.code != RC_OK)
		ASN_DEBUG("Failed to decode %s in %s (CHOICE) %d",
			elm->name, td->name, rv.code);
	return rv;
}
Ejemplo n.º 3
0
asn_dec_rval_t
OPEN_TYPE_uper_get(asn_codec_ctx_t *opt_codec_ctx,
                   asn_TYPE_descriptor_t *td, void *sptr,
                   asn_TYPE_member_t *elm, asn_per_data_t *pd) {
    asn_type_selector_result_t selected;
    void *memb_ptr;   /* Pointer to the member */
    void **memb_ptr2; /* Pointer to that pointer */
    asn_dec_rval_t rv;

    if(!(elm->flags & ATF_OPEN_TYPE) || !elm->type_selector) {
        ASN__DECODE_FAILED;
    }

    selected = elm->type_selector(td, sptr);
    if(!selected.presence_index) {
        ASN__DECODE_FAILED;
    }

    /* Fetch the pointer to this member */
    assert(elm->flags == ATF_OPEN_TYPE);
    if(elm->flags & ATF_POINTER) {
        memb_ptr2 = (void **)((char *)sptr + elm->memb_offset);
    } else {
        memb_ptr = (char *)sptr + elm->memb_offset;
        memb_ptr2 = &memb_ptr;
    }
    if(*memb_ptr2 != NULL) {
        /* Make sure we reset the structure first before encoding */
        if(CHOICE_variant_set_presence(elm->type, *memb_ptr2, 0)
           != 0) {
            ASN__DECODE_FAILED;
        }
    }

    void *inner_value =
        (char *)*memb_ptr2
        + elm->type->elements[selected.presence_index - 1].memb_offset;

    rv = uper_open_type_get(opt_codec_ctx, selected.type_descriptor, NULL,
                            &inner_value, pd);
    switch(rv.code) {
    case RC_OK:
        if(CHOICE_variant_set_presence(elm->type, *memb_ptr2,
                                       selected.presence_index)
           == 0) {
            break;
        } else {
            rv.code = RC_FAIL;
        }
        /* Fall through */
    case RC_WMORE:
    case RC_FAIL:
        if(*memb_ptr2) {
            asn_CHOICE_specifics_t *specs = selected.type_descriptor->specifics;
            if(elm->flags & ATF_POINTER) {
                ASN_STRUCT_FREE(*selected.type_descriptor, inner_value);
                *memb_ptr2 = NULL;
            } else {
                ASN_STRUCT_FREE_CONTENTS_ONLY(*selected.type_descriptor,
                                              inner_value);
                memset(*memb_ptr2, 0, specs->struct_size);
            }
        }
    }
    return rv;
}