diff options
author | Lev Walkin <vlm@lionet.info> | 2006-09-05 16:18:34 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2006-09-05 16:18:34 +0000 |
commit | adf863fc8fb984e1d7e6bbe1a9744fab3fbb7050 (patch) | |
tree | c53d6b1253d4414883a671178bbdac4b1d466460 /skeletons/constr_SET.c | |
parent | 3cf7c3a1e7f8fa127ea26c782808aaff2c3c0d3f (diff) |
support parsing realnumber tokens in constraints
Diffstat (limited to 'skeletons/constr_SET.c')
-rw-r--r-- | skeletons/constr_SET.c | 145 |
1 files changed, 143 insertions, 2 deletions
diff --git a/skeletons/constr_SET.c b/skeletons/constr_SET.c index 6d2d6c15..b43f0a87 100644 --- a/skeletons/constr_SET.c +++ b/skeletons/constr_SET.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2003, 2004, 2005 Lev Walkin <vlm@lionet.info>. + * Copyright (c) 2003, 2004, 2005, 2006 Lev Walkin <vlm@lionet.info>. * All rights reserved. * Redistribution and modifications are permitted subject to BSD license. */ @@ -121,7 +121,10 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, int edx; /* SET element's index */ ASN_DEBUG("Decoding %s as SET", td->name); - + + if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) + _ASN_DECODE_FAILED; + /* * Create the target structure if it is not present already. */ @@ -862,6 +865,144 @@ cb_failed: _ASN_ENCODE_FAILED; } +asn_dec_rval_t +SET_decode_uper(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_SET_specifics_t *specs = (asn_SET_specifics_t *)td->specifics; + void *st = *sptr; /* Target structure. */ + int extpresent = 0; /* Extension additions are present */ + uint8_t *opres; /* Presence of optional root members */ + asn_per_data_t opmd; + asn_dec_rval_t rv; + int edx; + + (void)constraints; + + ASN_DEBUG("Decoding %s as SET", td->name); + + if(_ASN_STACK_OVERFLOW_CHECK(opt_codec_ctx)) + _ASN_DECODE_FAILED; + + if(!st) { + st = *sptr = CALLOC(1, specs->struct_size); + if(!st) _ASN_DECODE_FAILED; + } + + ASN_DEBUG("Decoding %s as SEQUENCE (UPER)", td->name); + + /* Handle extensions */ + if(specs->ext_before >= 0) { + extpresent = per_get_few_bits(pd, 1); + if(extpresent < 0) _ASN_DECODE_FAILED; + } + + /* Prepare a place and read-in the presence bitmap */ + if(specs->roms_count) { + opres = (uint8_t *)MALLOC(((specs->roms_count + 7) >> 3) + 1); + if(!opres) _ASN_DECODE_FAILED; + /* Get the presence map */ + if(per_get_many_bits(pd, opres, 0, specs->roms_count)) { + FREEMEM(opres); + _ASN_DECODE_FAILED; + } + opmd.buffer = opres; + opmd.nboff = 0; + opmd.nbits = specs->roms_count; + ASN_DEBUG("Read in presence bitmap for %s of %d bits (%x..)", + td->name, specs->roms_count, *opres); + } else { + opres = 0; + memset(&opmd, 0, sizeof opmd); + } + + /* + * Get the sequence ROOT elements. + */ + for(edx = 0; edx < ((specs->ext_before < 0) + ? td->elements_count : specs->ext_before + 1); edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + /* Deal with optionality */ + if(elm->optional) { + int present = per_get_few_bits(&opmd, 1); + ASN_DEBUG("Member %s->%s is optional, p=%d (%d->%d)", + td->name, elm->name, present, + (int)opmd.nboff, (int)opmd.nbits); + if(present == 0) { + /* This element is not present */ + if(elm->default_value) { + /* Fill-in DEFAULT */ + if(elm->default_value(1, memb_ptr2)) { + FREEMEM(opres); + _ASN_DECODE_FAILED; + } + } + /* The member is just not present */ + continue; + } + /* Fall through */ + } + + /* Fetch the member from the stream */ + ASN_DEBUG("Decoding member %s in %s", elm->name, td->name); + rv = elm->type->uper_decoder(opt_codec_ctx, elm->type, + elm->per_constraints, memb_ptr2, pd); + if(rv.code != RC_OK) { + ASN_DEBUG("Failed decode %s in %s", + elm->name, td->name); + FREEMEM(opres); + return rv; + } + } + + /* + * Deal with extensions. + */ + if(extpresent) { + ASN_DEBUG("Extensibility for %s: NOT IMPLEMENTED", td->name); + _ASN_DECODE_FAILED; + } else { + for(edx = specs->roms_count; edx < specs->roms_count + + specs->aoms_count; edx++) { + asn_TYPE_member_t *elm = &td->elements[edx]; + void *memb_ptr; /* Pointer to the member */ + void **memb_ptr2; /* Pointer to that pointer */ + + if(!elm->default_value) continue; + + /* Fetch the pointer to this member */ + if(elm->flags & ATF_POINTER) { + memb_ptr2 = (void **)((char *)st + + elm->memb_offset); + } else { + memb_ptr = (char *)st + elm->memb_offset; + memb_ptr2 = &memb_ptr; + } + + /* Set default value */ + if(elm->default_value(1, memb_ptr2)) { + FREEMEM(opres); + _ASN_DECODE_FAILED; + } + } + } + + rv.consumed = 0; + rv.code = RC_OK; + FREEMEM(opres); + return rv; +} + int SET_print(asn_TYPE_descriptor_t *td, const void *sptr, int ilevel, asn_app_consume_bytes_f *cb, void *app_key) { |