diff options
author | Lev Walkin <vlm@lionet.info> | 2005-11-28 06:58:11 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2005-11-28 06:58:11 +0000 |
commit | 6036488576624c21d7e7035dd488cb36502b6986 (patch) | |
tree | 8ee9177fa72bcf03b31132faf5f8f9682ed16967 /skeletons | |
parent | d500a967a593f300fb697a9d51590ff0d4e0d906 (diff) |
expanding range: <= 31 bits now
Diffstat (limited to 'skeletons')
-rw-r--r-- | skeletons/per_support.c | 16 | ||||
-rw-r--r-- | skeletons/per_support.h | 2 | ||||
-rw-r--r-- | skeletons/tests/check-PER.c | 19 |
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; |