Commit 5b78e1cb authored by Lev Walkin's avatar Lev Walkin

uper extensions decoding

parent f55a6dde
This diff is collapsed.
......@@ -30,6 +30,7 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
}
/* Fill in the position indicator */
memset(&pd, 0, sizeof(pd));
pd.buffer = (const uint8_t *)buffer;
pd.nboff = skip_bits;
pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
......
......@@ -12,14 +12,33 @@
int32_t
per_get_few_bits(asn_per_data_t *pd, int nbits) {
size_t off; /* Next after last bit offset */
ssize_t nleft;
uint32_t accum;
const uint8_t *buf;
if(nbits < 0 || pd->nboff + nbits > pd->nbits)
if(nbits < 0)
return -1;
ASN_DEBUG("[PER get %d bits from %p+%d bits]",
nbits, pd->buffer, pd->nboff);
nleft = pd->nbits - pd->nboff;
if(nbits > nleft) {
int32_t tailv, vhead;
if(!pd->refill || nbits > 31) return -1;
/* Accumulate unused bytes before refill */
ASN_DEBUG("Obtain the rest %d bits", nleft);
tailv = per_get_few_bits(pd, nleft);
if(tailv < 0) return -1;
/* Refill (replace pd contents with new data) */
if(pd->refill(pd))
return -1;
nbits -= nleft;
vhead = per_get_few_bits(pd, nbits);
/* Combine the rest of previous pd with the head of new one */
tailv = (tailv << nbits) | vhead; /* Could == -1 */
return tailv;
}
ASN_DEBUG("[PER get %d bits from %p+%d bits, %d available]",
nbits, pd->buffer, pd->nboff, nleft);
/*
* Normalize position indicator.
......@@ -129,6 +148,29 @@ uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
return (16384 * value);
}
/*
* Get the normally small length "n".
* This procedure used to decode length of extensions bit-maps
* for SET and SEQUENCE types.
*/
ssize_t
uper_get_nslength(asn_per_data_t *pd) {
ssize_t length;
if(per_get_few_bits(pd, 1) == 0) {
ASN_DEBUG("l=?");
length = per_get_few_bits(pd, 6);
ASN_DEBUG("l=%d", length);
if(length < 0) return -1;
return length + 1;
} else {
int repeat;
length = uper_get_length(pd, -1, &repeat);
if(length >= 0 && !repeat) return length;
return -1; /* Error, or do not support >16K extensions */
}
}
/*
* Get the normally small non-negative whole number.
* X.691, #10.6
......
......@@ -40,6 +40,8 @@ typedef struct asn_per_data_s {
const uint8_t *buffer; /* Pointer to the octet stream */
size_t nboff; /* Bit offset to the meaningful bit */
size_t nbits; /* Number of bits in the stream */
int (*refill)(struct asn_per_data_s *);
void *refill_key;
} asn_per_data_t;
/*
......@@ -64,6 +66,11 @@ ssize_t uper_get_length(asn_per_data_t *pd,
int effective_bound_bits,
int *repeat);
/*
* Get the normally small length "n".
*/
ssize_t uper_get_nslength(asn_per_data_t *pd);
/*
* Get the normally small non-negative whole number.
*/
......
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