aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2005-11-28 06:58:11 +0000
committerLev Walkin <vlm@lionet.info>2005-11-28 06:58:11 +0000
commit6036488576624c21d7e7035dd488cb36502b6986 (patch)
tree8ee9177fa72bcf03b31132faf5f8f9682ed16967 /skeletons
parentd500a967a593f300fb697a9d51590ff0d4e0d906 (diff)
expanding range: <= 31 bits now
Diffstat (limited to 'skeletons')
-rw-r--r--skeletons/per_support.c16
-rw-r--r--skeletons/per_support.h2
-rw-r--r--skeletons/tests/check-PER.c19
3 files changed, 30 insertions, 7 deletions
diff --git a/skeletons/per_support.c b/skeletons/per_support.c
index 506ca780..9b048f0f 100644
--- a/skeletons/per_support.c
+++ b/skeletons/per_support.c
@@ -6,7 +6,7 @@
#include <per_support.h>
/*
- * Extract a small number of bits (<= 24) from the specified PER data pointer.
+ * 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) {
@@ -16,8 +16,6 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
if(nbits < 0 || pd->nboff + nbits > pd->nbits)
return -1;
- if(nbits == 0)
- return 0;
/*
* Normalize position indicator.
@@ -34,7 +32,7 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
* Extract specified number of bits.
*/
if(off <= 8)
- accum = (buf[0]) >> (8 - off);
+ accum = nbits ? (buf[0]) >> (8 - off) : 0;
else if(off <= 16)
accum = ((buf[0] << 8) + buf[1]) >> (16 - off);
else if(off <= 24)
@@ -42,12 +40,18 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
else if(off <= 31)
accum = ((buf[0] << 24) + (buf[1] << 16)
+ (buf[2] << 8) + (buf[3])) >> (32 - off);
- else {
+ 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;
+ accum = per_get_few_bits(&tpd, nbits - 24) << 24;
+ accum |= per_get_few_bits(&tpd, 24);
+ } else {
pd->nboff -= nbits; /* Oops, revert back */
return -1;
}
- return (accum & ((1 << nbits) - 1));
+ return (accum & (((uint32_t)1 << nbits) - 1));
}
/*
diff --git a/skeletons/per_support.h b/skeletons/per_support.h
index 25c92566..a8f15fbe 100644
--- a/skeletons/per_support.h
+++ b/skeletons/per_support.h
@@ -21,7 +21,7 @@ typedef struct asn_per_data_s {
} asn_per_data_t;
/*
- * Extract a small number of bits (<= 24) from the specified PER data pointer.
+ * Extract a small number of bits (<= 31) from the specified PER data pointer.
* This function returns -1 if the specified number of bits could not be
* extracted due to EOD or other conditions.
*/
diff --git a/skeletons/tests/check-PER.c b/skeletons/tests/check-PER.c
index 94f5fe42..5fcb1aee 100644
--- a/skeletons/tests/check-PER.c
+++ b/skeletons/tests/check-PER.c
@@ -14,22 +14,27 @@ main() {
z = per_get_few_bits(&pos, 32);
assert(z == -1);
+ assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 0);
assert(z == 0);
assert(pos.nboff == 0);
+ assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 1);
assert(z == 1);
assert(pos.nboff == 1);
+ assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 2);
assert(z == 1);
assert(pos.nboff == 3);
+ assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 2);
assert(z == 2);
assert(pos.nboff == 5);
+ assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 3);
assert(z == 7);
@@ -61,6 +66,20 @@ main() {
z = per_get_few_bits(&pos, 24);
assert(z == 14443711);
+ /* Get full 31-bit range */
+ pos.buffer = buf;
+ pos.nboff = 7;
+ pos.nbits = sizeof(buf) * 8;
+ z = per_get_few_bits(&pos, 31);
+ assert(z == 1179384747);
+
+ /* Get a bit shifted range */
+ pos.buffer = buf;
+ pos.nboff = 6;
+ pos.nbits = sizeof(buf) * 8;
+ z = per_get_few_bits(&pos, 31);
+ assert(z == 1663434197);
+
pos.buffer = buf;
pos.nboff = 0;
pos.nbits = sizeof(buf) * 8;