diff options
author | Lev Walkin <vlm@lionet.info> | 2007-06-26 02:51:10 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2007-06-26 02:51:10 +0000 |
commit | d00657f65254df98353505d5720a0b8cc9256170 (patch) | |
tree | b17e43b28974673245321efee040ff410c341d17 /skeletons | |
parent | 054a7e842d900773eff181384b8e944870acceeb (diff) |
per_get_undo()
Diffstat (limited to 'skeletons')
-rw-r--r-- | skeletons/constr_SEQUENCE.c | 8 | ||||
-rw-r--r-- | skeletons/per_decoder.c | 1 | ||||
-rw-r--r-- | skeletons/per_support.c | 23 | ||||
-rw-r--r-- | skeletons/per_support.h | 14 |
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 |