Commit d00657f6 authored by Lev Walkin's avatar Lev Walkin

per_get_undo()

parent 054a7e84
...@@ -1078,7 +1078,6 @@ uper_ugot_refill(asn_per_data_t *pd) { ...@@ -1078,7 +1078,6 @@ uper_ugot_refill(asn_per_data_t *pd) {
oldpd->nbits -= consumed; oldpd->nbits -= consumed;
oldpd->buffer = pd->buffer; oldpd->buffer = pd->buffer;
oldpd->nboff = pd->nboff; oldpd->nboff = pd->nboff;
oldpd->nboff = pd->nbits;
if(arg->unclaimed) { if(arg->unclaimed) {
/* Refill the container */ /* Refill the container */
...@@ -1091,6 +1090,7 @@ uper_ugot_refill(asn_per_data_t *pd) { ...@@ -1091,6 +1090,7 @@ uper_ugot_refill(asn_per_data_t *pd) {
pd->buffer = oldpd->buffer; pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff - 1; pd->nboff = oldpd->nboff - 1;
pd->nbits = oldpd->nbits; pd->nbits = oldpd->nbits;
pd->moved = oldpd->moved - 1;
ASN_DEBUG("===================="); ASN_DEBUG("====================");
return 0; return 0;
} }
...@@ -1110,12 +1110,12 @@ uper_ugot_refill(asn_per_data_t *pd) { ...@@ -1110,12 +1110,12 @@ uper_ugot_refill(asn_per_data_t *pd) {
pd->buffer = oldpd->buffer; pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff; pd->nboff = oldpd->nboff;
pd->nbits = oldpd->nbits; pd->nbits = oldpd->nbits;
pd->moved = oldpd->moved;
next_chunk_bits = next_chunk_bytes << 3; next_chunk_bits = next_chunk_bytes << 3;
avail = pd->nbits - pd->nboff; avail = pd->nbits - pd->nboff;
ASN_DEBUG("now at %d bits, want %d", ASN_DEBUG("now at %d bits, want %d, avail %d",
((((int)pd->buffer ) & 0x7) << 3) + pd->nboff, ((((int)pd->buffer ) & 0x7) << 3) + pd->nboff,
next_chunk_bits); next_chunk_bits, avail);
ASN_DEBUG("avail = %d", avail);
if(avail >= next_chunk_bits) { if(avail >= next_chunk_bits) {
pd->nbits = pd->nboff + next_chunk_bits; pd->nbits = pd->nboff + next_chunk_bits;
arg->unclaimed = 0; arg->unclaimed = 0;
......
...@@ -47,6 +47,7 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp ...@@ -47,6 +47,7 @@ uper_decode(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td, void **sp
/* Return the number of consumed bits */ /* Return the number of consumed bits */
rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3) rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
+ pd.nboff - skip_bits; + pd.nboff - skip_bits;
assert(rval.consumed == pd.moved);
} else { } else {
/* PER codec is not a restartable */ /* PER codec is not a restartable */
rval.consumed = 0; rval.consumed = 0;
......
...@@ -6,13 +6,23 @@ ...@@ -6,13 +6,23 @@
#include <asn_internal.h> #include <asn_internal.h>
#include <per_support.h> #include <per_support.h>
void
per_get_undo(asn_per_data_t *pd, int nbits) {
if(pd->nboff < nbits) {
assert(pd->nboff < nbits);
} else {
pd->nboff -= nbits;
pd->moved -= nbits;
}
}
/* /*
* Extract a small number of bits (<= 31) from the specified PER data pointer. * Extract a small number of bits (<= 31) from the specified PER data pointer.
*/ */
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; ssize_t nleft; /* Number of bits left in this stream */
uint32_t accum; uint32_t accum;
const uint8_t *buf; const uint8_t *buf;
...@@ -48,7 +58,9 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) { ...@@ -48,7 +58,9 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
pd->nbits -= (pd->nboff & ~0x07); pd->nbits -= (pd->nboff & ~0x07);
pd->nboff &= 0x07; pd->nboff &= 0x07;
} }
off = (pd->nboff += nbits); pd->moved += nbits;
pd->nboff += nbits;
off = pd->nboff;
buf = pd->buffer; buf = pd->buffer;
/* /*
...@@ -66,11 +78,14 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) { ...@@ -66,11 +78,14 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
else if(nbits <= 31) { else if(nbits <= 31) {
asn_per_data_t tpd = *pd; asn_per_data_t tpd = *pd;
/* Here are we with our 31-bits limit plus 1..7 bits offset. */ /* Here are we with our 31-bits limit plus 1..7 bits offset. */
tpd.nboff -= nbits; per_get_undo(&tpd, nbits);
/* The number of available bits in the stream allow
* for the following operations to take place without
* invoking the ->refill() function */
accum = per_get_few_bits(&tpd, nbits - 24) << 24; accum = per_get_few_bits(&tpd, nbits - 24) << 24;
accum |= per_get_few_bits(&tpd, 24); accum |= per_get_few_bits(&tpd, 24);
} else { } else {
pd->nboff -= nbits; /* Oops, revert back */ per_get_undo(pd, nbits);
return -1; return -1;
} }
......
...@@ -40,6 +40,7 @@ typedef struct asn_per_data_s { ...@@ -40,6 +40,7 @@ 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 */
size_t moved; /* Number of bits moved through this bit stream */
int (*refill)(struct asn_per_data_s *); int (*refill)(struct asn_per_data_s *);
void *refill_key; void *refill_key;
} asn_per_data_t; } asn_per_data_t;
...@@ -51,6 +52,9 @@ typedef struct asn_per_data_s { ...@@ -51,6 +52,9 @@ typedef struct asn_per_data_s {
*/ */
int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits); int32_t per_get_few_bits(asn_per_data_t *per_data, int get_nbits);
/* Undo the immediately preceeding "get_few_bits" operation */
void per_get_undo(asn_per_data_t *per_data, int get_nbits);
/* /*
* Extract a large number of bits from the specified PER data pointer. * Extract a large number of bits from the specified PER data pointer.
* This function returns -1 if the specified number of bits could not be * This function returns -1 if the specified number of bits could not be
......
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