Commit 3e478edc authored by Lev Walkin's avatar Lev Walkin

removed special case

parent 302f9fd9
...@@ -169,24 +169,22 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -169,24 +169,22 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
* From the place where we've left it previously, * From the place where we've left it previously,
* try to decode the next member from the list of * try to decode the next member from the list of
* this structure's elements. * this structure's elements.
* (ctx->step) stores the member being processed * Note that elements in BER may arrive out of
* between invocations and the microphase {0,1} of parsing
* that member:
* step = (2 * <member_number> + <microphase>).
* Note, however, that the elements in BER may arrive out of
* order, yet DER mandates that they shall arive in the * order, yet DER mandates that they shall arive in the
* canonical order of their tags. So, there is a room * canonical order of their tags. So, there is a room
* for optimization. * for optimization.
*/ */
for(edx = (ctx->step >> 1); edx < td->elements_count; for(;; ctx->step = 0) {
ctx->step = (ctx->step & ~1) + 2, asn_TYPE_tag2member_t *t2m;
edx = (ctx->step >> 1)) { asn_TYPE_tag2member_t key;
void *memb_ptr; /* Pointer to the member */ void *memb_ptr; /* Pointer to the member */
void **memb_ptr2; /* Pointer to that pointer */ void **memb_ptr2; /* Pointer to that pointer */
ssize_t tag_len; /* Length of TLV's T */ ssize_t tag_len; /* Length of TLV's T */
if(ctx->step & 1) if(ctx->step & 1) {
edx = ctx->step >> 1;
goto microphase2; goto microphase2;
}
/* /*
* MICROPHASE 1: Synchronize decoding. * MICROPHASE 1: Synchronize decoding.
...@@ -226,59 +224,47 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -226,59 +224,47 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
} }
} }
if(BER_TAGS_EQUAL(tlv_tag, elements[edx].tag)) { key.el_tag = tlv_tag;
(void *)t2m = bsearch(&key,
specs->tag2el, specs->tag2el_count,
sizeof(specs->tag2el[0]), _t2e_cmp);
if(t2m) {
/* /*
* The elements seem to go in order. * Found the element corresponding to the tag.
* This is not particularly strange,
* but is not strongly anticipated either.
*/ */
edx = t2m->el_no;
ctx->step = (edx << 1) + 1;
ASN_DEBUG("Got tag %s (%s), edx %d",
ber_tlv_tag_string(tlv_tag), td->name, edx);
} else if(specs->extensible == 0) {
ASN_DEBUG("Unexpected tag %s "
"in non-extensible SET %s",
ber_tlv_tag_string(tlv_tag), td->name);
RETURN(RC_FAIL);
} else { } else {
asn_TYPE_tag2member_t *t2m; /* Skip this tag */
asn_TYPE_tag2member_t key; ssize_t skip;
key.el_tag = tlv_tag;
(void *)t2m = bsearch(&key,
specs->tag2el, specs->tag2el_count,
sizeof(specs->tag2el[0]), _t2e_cmp);
if(t2m) {
/*
* Found the element corresponding to the tag.
*/
edx = t2m->el_no;
ctx->step = 2 * edx;
} else if(specs->extensible == 0) {
ASN_DEBUG("Unexpected tag %s "
"in non-extensible SET %s",
ber_tlv_tag_string(tlv_tag), td->name);
RETURN(RC_FAIL);
} else {
/* Skip this tag */
ssize_t skip;
ASN_DEBUG("Skipping unknown tag %s",
ber_tlv_tag_string(tlv_tag));
skip = ber_skip_length(opt_codec_ctx, ASN_DEBUG("Skipping unknown tag %s",
BER_TLV_CONSTRUCTED(ptr), ber_tlv_tag_string(tlv_tag));
(char *)ptr + tag_len, LEFT - tag_len);
switch(skip) { skip = ber_skip_length(opt_codec_ctx,
case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE); BER_TLV_CONSTRUCTED(ptr),
/* Fall through */ (char *)ptr + tag_len, LEFT - tag_len);
case -1: RETURN(RC_FAIL);
}
ADVANCE(skip + tag_len); switch(skip) {
ctx->step -= 2; case 0: if(!SIZE_VIOLATION) RETURN(RC_WMORE);
edx--; /* Fall through */
continue; /* Try again with the next tag */ case -1: RETURN(RC_FAIL);
} }
ADVANCE(skip + tag_len);
continue; /* Try again with the next tag */
} }
/* /*
* MICROPHASE 2: Invoke the member-specific decoder. * MICROPHASE 2: Invoke the member-specific decoder.
*/ */
ctx->step |= 1; /* Confirm entering next microphase */
microphase2: microphase2:
/* /*
...@@ -375,8 +361,9 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, ...@@ -375,8 +361,9 @@ SET_decode_ber(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
if(specs->extensible == 0 || ctx->phase == 4) { if(specs->extensible == 0 || ctx->phase == 4) {
ASN_DEBUG("Unexpected continuation " ASN_DEBUG("Unexpected continuation "
"of a non-extensible type %s", "of a non-extensible type %s "
td->name); "(ptr=%02x)",
td->name, *(uint8_t *)ptr);
RETURN(RC_FAIL); RETURN(RC_FAIL);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment