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 ...@@ -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 */ /* Fill in the position indicator */
memset(&pd, 0, sizeof(pd));
pd.buffer = (const uint8_t *)buffer; pd.buffer = (const uint8_t *)buffer;
pd.nboff = skip_bits; pd.nboff = skip_bits;
pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */ pd.nbits = 8 * size - unused_bits; /* 8 is CHAR_BIT from <limits.h> */
......
...@@ -12,14 +12,33 @@ ...@@ -12,14 +12,33 @@
int32_t int32_t
per_get_few_bits(asn_per_data_t *pd, int nbits) { per_get_few_bits(asn_per_data_t *pd, int nbits) {
size_t off; /* Next after last bit offset */ size_t off; /* Next after last bit offset */
ssize_t nleft;
uint32_t accum; uint32_t accum;
const uint8_t *buf; const uint8_t *buf;
if(nbits < 0 || pd->nboff + nbits > pd->nbits) if(nbits < 0)
return -1; return -1;
ASN_DEBUG("[PER get %d bits from %p+%d bits]", nleft = pd->nbits - pd->nboff;
nbits, pd->buffer, 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. * Normalize position indicator.
...@@ -129,6 +148,29 @@ uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) { ...@@ -129,6 +148,29 @@ uper_get_length(asn_per_data_t *pd, int ebits, int *repeat) {
return (16384 * value); 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. * Get the normally small non-negative whole number.
* X.691, #10.6 * X.691, #10.6
......
...@@ -40,6 +40,8 @@ typedef struct asn_per_data_s { ...@@ -40,6 +40,8 @@ typedef struct asn_per_data_s {
const uint8_t *buffer; /* Pointer to the octet stream */ const uint8_t *buffer; /* Pointer to the octet stream */
size_t nboff; /* Bit offset to the meaningful bit */ size_t nboff; /* Bit offset to the meaningful bit */
size_t nbits; /* Number of bits in the stream */ size_t nbits; /* Number of bits in the stream */
int (*refill)(struct asn_per_data_s *);
void *refill_key;
} asn_per_data_t; } asn_per_data_t;
/* /*
...@@ -64,6 +66,11 @@ ssize_t uper_get_length(asn_per_data_t *pd, ...@@ -64,6 +66,11 @@ ssize_t uper_get_length(asn_per_data_t *pd,
int effective_bound_bits, int effective_bound_bits,
int *repeat); 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. * 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