Commit 60364885 authored by Lev Walkin's avatar Lev Walkin

expanding range: <= 31 bits now

parent d500a967
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#include <per_support.h> #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 int32_t
per_get_few_bits(asn_per_data_t *pd, int nbits) { 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) { ...@@ -16,8 +16,6 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
if(nbits < 0 || pd->nboff + nbits > pd->nbits) if(nbits < 0 || pd->nboff + nbits > pd->nbits)
return -1; return -1;
if(nbits == 0)
return 0;
/* /*
* Normalize position indicator. * Normalize position indicator.
...@@ -34,7 +32,7 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) { ...@@ -34,7 +32,7 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
* Extract specified number of bits. * Extract specified number of bits.
*/ */
if(off <= 8) if(off <= 8)
accum = (buf[0]) >> (8 - off); accum = nbits ? (buf[0]) >> (8 - off) : 0;
else if(off <= 16) else if(off <= 16)
accum = ((buf[0] << 8) + buf[1]) >> (16 - off); accum = ((buf[0] << 8) + buf[1]) >> (16 - off);
else if(off <= 24) else if(off <= 24)
...@@ -42,12 +40,18 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) { ...@@ -42,12 +40,18 @@ per_get_few_bits(asn_per_data_t *pd, int nbits) {
else if(off <= 31) else if(off <= 31)
accum = ((buf[0] << 24) + (buf[1] << 16) accum = ((buf[0] << 24) + (buf[1] << 16)
+ (buf[2] << 8) + (buf[3])) >> (32 - off); + (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 */ pd->nboff -= nbits; /* Oops, revert back */
return -1; return -1;
} }
return (accum & ((1 << nbits) - 1)); return (accum & (((uint32_t)1 << nbits) - 1));
} }
/* /*
......
...@@ -21,7 +21,7 @@ typedef struct asn_per_data_s { ...@@ -21,7 +21,7 @@ typedef struct asn_per_data_s {
} asn_per_data_t; } 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 * This function returns -1 if the specified number of bits could not be
* extracted due to EOD or other conditions. * extracted due to EOD or other conditions.
*/ */
......
...@@ -14,22 +14,27 @@ main() { ...@@ -14,22 +14,27 @@ main() {
z = per_get_few_bits(&pos, 32); z = per_get_few_bits(&pos, 32);
assert(z == -1); assert(z == -1);
assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 0); z = per_get_few_bits(&pos, 0);
assert(z == 0); assert(z == 0);
assert(pos.nboff == 0); assert(pos.nboff == 0);
assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 1); z = per_get_few_bits(&pos, 1);
assert(z == 1); assert(z == 1);
assert(pos.nboff == 1); assert(pos.nboff == 1);
assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 2); z = per_get_few_bits(&pos, 2);
assert(z == 1); assert(z == 1);
assert(pos.nboff == 3); assert(pos.nboff == 3);
assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 2); z = per_get_few_bits(&pos, 2);
assert(z == 2); assert(z == 2);
assert(pos.nboff == 5); assert(pos.nboff == 5);
assert(pos.nbits == sizeof(buf) * 8);
z = per_get_few_bits(&pos, 3); z = per_get_few_bits(&pos, 3);
assert(z == 7); assert(z == 7);
...@@ -61,6 +66,20 @@ main() { ...@@ -61,6 +66,20 @@ main() {
z = per_get_few_bits(&pos, 24); z = per_get_few_bits(&pos, 24);
assert(z == 14443711); 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.buffer = buf;
pos.nboff = 0; pos.nboff = 0;
pos.nbits = sizeof(buf) * 8; pos.nbits = sizeof(buf) * 8;
......
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