aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2007-06-26 02:51:10 +0000
committerLev Walkin <vlm@lionet.info>2007-06-26 02:51:10 +0000
commitd00657f65254df98353505d5720a0b8cc9256170 (patch)
treeb17e43b28974673245321efee040ff410c341d17 /skeletons
parent054a7e842d900773eff181384b8e944870acceeb (diff)
per_get_undo()
Diffstat (limited to 'skeletons')
-rw-r--r--skeletons/constr_SEQUENCE.c8
-rw-r--r--skeletons/per_decoder.c1
-rw-r--r--skeletons/per_support.c23
-rw-r--r--skeletons/per_support.h14
4 files changed, 33 insertions, 13 deletions
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index ec04992f..4267d84e 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -1078,7 +1078,6 @@ uper_ugot_refill(asn_per_data_t *pd) {
oldpd->nbits -= consumed;
oldpd->buffer = pd->buffer;
oldpd->nboff = pd->nboff;
- oldpd->nboff = pd->nbits;
if(arg->unclaimed) {
/* Refill the container */
@@ -1091,6 +1090,7 @@ uper_ugot_refill(asn_per_data_t *pd) {
pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff - 1;
pd->nbits = oldpd->nbits;
+ pd->moved = oldpd->moved - 1;
ASN_DEBUG("====================");
return 0;
}
@@ -1110,12 +1110,12 @@ uper_ugot_refill(asn_per_data_t *pd) {
pd->buffer = oldpd->buffer;
pd->nboff = oldpd->nboff;
pd->nbits = oldpd->nbits;
+ pd->moved = oldpd->moved;
next_chunk_bits = next_chunk_bytes << 3;
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,
- next_chunk_bits);
- ASN_DEBUG("avail = %d", avail);
+ next_chunk_bits, avail);
if(avail >= next_chunk_bits) {
pd->nbits = pd->nboff + next_chunk_bits;
arg->unclaimed = 0;
diff --git a/skeletons/per_decoder.c b/skeletons/per_decoder.c
index 2e460da2..4e120a4b 100644
--- a/skeletons/per_decoder.c
+++ b/skeletons/per_decoder.c
@@ -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 */
rval.consumed = ((pd.buffer - (const uint8_t *)buffer) << 3)
+ pd.nboff - skip_bits;
+ assert(rval.consumed == pd.moved);
} else {
/* PER codec is not a restartable */
rval.consumed = 0;
diff --git a/skeletons/per_support.c b/skeletons/per_support.c
index 228fd111..f38422ad 100644
--- a/skeletons/per_support.c
+++ b/skeletons/per_support.c
@@ -6,13 +6,23 @@
#include <asn_internal.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.
*/
int32_t
per_get_few_bits(asn_per_data_t *pd, int nbits) {
size_t off; /* Next after last bit offset */
- ssize_t nleft;
+ ssize_t nleft; /* Number of bits left in this stream */
uint32_t accum;
const uint8_t *buf;
@@ -48,7 +58,9 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
pd->nbits -= (pd->nboff & ~0x07);
pd->nboff &= 0x07;
}
- off = (pd->nboff += nbits);
+ pd->moved += nbits;
+ pd->nboff += nbits;
+ off = pd->nboff;
buf = pd->buffer;
/*
@@ -66,11 +78,14 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
else if(nbits <= 31) {
asn_per_data_t tpd = *pd;
/* 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, 24);
} else {
- pd->nboff -= nbits; /* Oops, revert back */
+ per_get_undo(pd, nbits);
return -1;
}
diff --git a/skeletons/per_support.h b/skeletons/per_support.h
index c22bc726..bf06f056 100644
--- a/skeletons/per_support.h
+++ b/skeletons/per_support.h
@@ -37,11 +37,12 @@ typedef struct asn_per_constraints_s {
* This structure describes a position inside an incoming PER bit stream.
*/
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;
+ 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 */
+ size_t moved; /* Number of bits moved through this bit stream */
+ int (*refill)(struct asn_per_data_s *);
+ void *refill_key;
} asn_per_data_t;
/*
@@ -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);
+/* 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.
* This function returns -1 if the specified number of bits could not be