From: Max msuraev@sysmocom.de
--- .gitignore | 3 +++ 1 file changed, 3 insertions(+)
diff --git a/.gitignore b/.gitignore index 598f88a..955634e 100644 --- a/.gitignore +++ b/.gitignore @@ -81,6 +81,9 @@ tests/strrb/strrb_test tests/vty/vty_test tests/gb/gprs_bssgp_test tests/smscb/gsm0341_test +tests/bitvec/bitvec_test +tests/gprs/gprs_test +tests/msgb/msgb_test
utils/osmo-arfcn utils/osmo-auc-gen
From: Max msuraev@sysmocom.de
Sponsored-by: On-Waves ehf --- include/osmocom/core/bitvec.h | 11 ++++++----- src/bitvec.c | 14 +++++++------- 2 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h index 89eb784..e03b774 100644 --- a/include/osmocom/core/bitvec.h +++ b/include/osmocom/core/bitvec.h @@ -3,6 +3,7 @@ /* bit vector utility routines */
/* (C) 2009 by Harald Welte laforge@gnumonks.org + * (C) 2015 by Sysmocom s.f.m.c. GmbH * * All Rights Reserved * @@ -66,12 +67,12 @@ int bitvec_set_bit_pos(struct bitvec *bv, unsigned int bitnum, enum bit_value bit); int bitvec_set_bit(struct bitvec *bv, enum bit_value bit); int bitvec_get_bit_high(struct bitvec *bv); -int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count); -int bitvec_set_uint(struct bitvec *bv, unsigned int in, int count); -int bitvec_get_uint(struct bitvec *bv, int num_bits); +int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, unsigned int count); +int bitvec_set_uint(struct bitvec *bv, uint32_t in, unsigned int count); +int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits); int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val); int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit); -int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, int count); -int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, int count); +int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count); +int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count);
/*! @} */ diff --git a/src/bitvec.c b/src/bitvec.c index 726a768..8596d51 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -190,7 +190,7 @@ int bitvec_get_bit_high(struct bitvec *bv) * \param[in] bits array of \ref bit_value * \param[in] count number of bits to set */ -int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count) +int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, unsigned int count) { int i, rc;
@@ -204,10 +204,10 @@ int bitvec_set_bits(struct bitvec *bv, enum bit_value *bits, int count) }
/*! \brief set multiple bits (based on numeric value) at current pos */ -int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits) +int bitvec_set_uint(struct bitvec *bv, unsigned int ui, unsigned int num_bits) { - int i, rc; - + int rc; + unsigned i; for (i = 0; i < num_bits; i++) { int bit = 0; if (ui & (1 << (num_bits - i - 1))) @@ -221,7 +221,7 @@ int bitvec_set_uint(struct bitvec *bv, unsigned int ui, int num_bits) }
/*! \brief get multiple bits (based on numeric value) from current pos */ -int bitvec_get_uint(struct bitvec *bv, int num_bits) +int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) { int i; unsigned int ui = 0; @@ -269,7 +269,7 @@ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, * \param[in] bytes array * \param[in] count number of bytes to copy */ -int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, int count) +int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count) { int byte_offs = bytenum_from_bitnum(bv->cur_bit); int bit_offs = bv->cur_bit % 8; @@ -304,7 +304,7 @@ int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, int count) * \param[in] bytes array * \param[in] count number of bytes to copy */ -int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, int count) +int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count) { int byte_offs = bytenum_from_bitnum(bv->cur_bit); int bit_offs = bv->cur_bit % 8;
On 22 Jan 2016, at 16:46, suraev@alumni.ntnu.no wrote:
Hi!
/* (C) 2009 by Harald Welte laforge@gnumonks.org
- (C) 2015 by Sysmocom s.f.m.c. GmbH
I think it will be difficult to claim s/int/unsigned int/ as copyright. I can amend the commit to remove the copyright notice again.
From: Max msuraev@sysmocom.de
Sponsored-by: On-Waves ehf --- include/osmocom/core/bitvec.h | 8 ++++ src/bitvec.c | 92 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 100 insertions(+)
diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h index e03b774..ef65f9e 100644 --- a/include/osmocom/core/bitvec.h +++ b/include/osmocom/core/bitvec.h @@ -3,6 +3,7 @@ /* bit vector utility routines */
/* (C) 2009 by Harald Welte laforge@gnumonks.org + * (C) 2012 Ivan Klyuchnikov * (C) 2015 by Sysmocom s.f.m.c. GmbH * * All Rights Reserved @@ -74,5 +75,12 @@ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit); int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count); int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count); +struct bitvec * bitvec_alloc(unsigned int size); +void bitvec_free(struct bitvec *bv); +int bitvec_unhex(struct bitvec *bv, const char* src); +unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer); +unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer); +uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned int len); +int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len);
/*! @} */ diff --git a/src/bitvec.c b/src/bitvec.c index 8596d51..68b8d98 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -1,6 +1,7 @@ /* bit vector utility routines */
/* (C) 2009 by Harald Welte laforge@gnumonks.org + * (C) 2012 Ivan Klyuchnikov * (C) 2015 by Sysmocom s.f.m.c. GmbH * * All Rights Reserved @@ -32,11 +33,15 @@ #include <errno.h> #include <stdint.h> #include <string.h> +#include <stdio.h> +#include <talloc.h>
#include <osmocom/core/bitvec.h>
#define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit)
+void *bv_tall_ctx; + static inline unsigned int bytenum_from_bitnum(unsigned int bitnum) { unsigned int bytenum = bitnum / 8; @@ -336,4 +341,91 @@ int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count bv->cur_bit += count * 8; return 0; } + +struct bitvec *bitvec_alloc(unsigned size) +{ + struct bitvec *bv = talloc_zero(bv_tall_ctx, struct bitvec); + bv->data_len = size; + bv->cur_bit = 0; + bv->data = talloc_zero_array(bv_tall_ctx, uint8_t, size); + return bv; +} + +void bitvec_free(struct bitvec *bv) +{ + talloc_free(bv->data); + talloc_free(bv); +} + +unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer) +{ + unsigned int i = 0; + for (i = 0; i < bv->data_len; i++) + { + buffer[i] = bv->data[i]; + } + return i; +} + +unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer) +{ + unsigned int i = 0; + for (i = 0; i < bv->data_len; i++) + { + bv->data[i] = buffer[i]; + } + return i; +} + + +int bitvec_unhex(struct bitvec *bv, const char* src) +{ + unsigned val; + unsigned write_index = 0; + unsigned digits = bv->data_len*2; + for (unsigned i=0; i<digits; i++) { + if (sscanf(src+i, "%1x", &val) < 1) { + return 1; + } + bitvec_write_field(bv, write_index,val, 4); + } + return 0; +} + +uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned int len) +{ + unsigned int i; + uint64_t ui = 0; + bv->cur_bit = read_index; + + for (i = 0; i < len; i++) { + int bit = bitvec_get_bit_pos((const struct bitvec *)bv, bv->cur_bit); + if (bit < 0) + return bit; + if (bit) + ui |= ((uint64_t)1 << (len - i - 1)); + bv->cur_bit++; + } + read_index += len; + return ui; +} + + +int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len) +{ + unsigned int i; + int rc; + bv->cur_bit = write_index; + for (i = 0; i < len; i++) { + int bit = 0; + if (val & ((uint64_t)1 << (len - i - 1))) + bit = 1; + rc = bitvec_set_bit(bv, bit); + if (rc) + return rc; + } + write_index += len; + return 0; +} + /*! @} */
On 22 Jan 2016, at 16:46, suraev@alumni.ntnu.no wrote:
@@ -74,5 +75,12 @@ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit); int bitvec_get_bytes(struct bitvec *bv, uint8_t *bytes, unsigned int count); int bitvec_set_bytes(struct bitvec *bv, const uint8_t *bytes, unsigned int count); +struct bitvec * bitvec_alloc(unsigned int size);
coding style to have ' * ' in the middle of nowwhere
#define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit)
+void *bv_tall_ctx;
static? how is the talloc context "rooted" so that it will show up in the leak detection?
+struct bitvec *bitvec_alloc(unsigned size) +{
- struct bitvec *bv = talloc_zero(bv_tall_ctx, struct bitvec);
- bv->data_len = size;
- bv->cur_bit = 0;
- bv->data = talloc_zero_array(bv_tall_ctx, uint8_t, size);
- return bv;
bv is a talloc context itself so it should be used to create data instead of the global one.
+unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer) +{
- unsigned int i = 0;
- for (i = 0; i < bv->data_len; i++)
- {
coding style for the '{' and in other methods too.
You're right, it does not belong to the lib. Fixed it alongside with style comments in attached patch.
cheers, Max.
On 25 Jan 2016, at 13:28, Max (☭) suraev@alumni.ntnu.no wrote:
<0001-Add-bitvec-related-functions-from-Osmo-PCU.patch>
+struct bitvec *bitvec_alloc(unsigned int size, TALLOC_CTX * bvctx) +{ + struct bitvec *bv = talloc_zero(bvctx, struct bitvec); + bv->data_len = size; + bv->cur_bit = 0; + bv->data = talloc_zero_array(bvctx, uint8_t, size); + return bv; +}
talloc has hierachies. So we pass the context into it but bv->data should be a child of "data". As a library function it needs to handle OOM as well.
bv = talloc_zero(bvctx, struct bitvec); if (!bv) return NULL; bv->data_len = size; .. bv->data = talloc_zero_array(bv, uint8_t, size); if (!bv->data) { talloc_free(bv); return NULL; } return bv
holger
v2 attached - added hierarchical allocation.
cheers, Max.
v3 attached with style corrections.
From: Max msuraev@sysmocom.de
Add bit filling, shifting and oter functions necessary for bit compression implementation.
Sponsored-by: On-Waves ehf --- include/osmocom/core/bitvec.h | 10 +++- src/bitvec.c | 128 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 7 deletions(-)
diff --git a/include/osmocom/core/bitvec.h b/include/osmocom/core/bitvec.h index ef65f9e..8078fc8 100644 --- a/include/osmocom/core/bitvec.h +++ b/include/osmocom/core/bitvec.h @@ -4,7 +4,7 @@
/* (C) 2009 by Harald Welte laforge@gnumonks.org * (C) 2012 Ivan Klyuchnikov - * (C) 2015 by Sysmocom s.f.m.c. GmbH + * (C) 2015 by Sysmocom s.f.m.c. GmbH, Author: Max msuraev@sysmocom.de * * All Rights Reserved * @@ -41,6 +41,7 @@ */
#include <stdint.h> +#include <stdbool.h>
/*! \brief A single GSM bit * @@ -82,5 +83,12 @@ unsigned int bitvec_pack(struct bitvec *bv, uint8_t *buffer); unsigned int bitvec_unpack(struct bitvec *bv, uint8_t *buffer); uint64_t bitvec_read_field(struct bitvec *bv, unsigned int read_index, unsigned int len); int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val, unsigned int len); +int bitvec_fill(struct bitvec *bv, unsigned int num_bits, enum bit_value fill); +char bit_value_to_char(enum bit_value v); +void bitvec_to_string_r(const struct bitvec *bv, char *str); +void bitvec_zero(struct bitvec *bv); +unsigned bitvec_rl(const struct bitvec *bv, bool b); +void bitvec_shiftl(struct bitvec *bv, unsigned int n); +int16_t bitvec_get_int16_msb(const struct bitvec *bv, unsigned int num_bits);
/*! @} */ diff --git a/src/bitvec.c b/src/bitvec.c index 68b8d98..b59d711 100644 --- a/src/bitvec.c +++ b/src/bitvec.c @@ -35,7 +35,9 @@ #include <string.h> #include <stdio.h> #include <talloc.h> +#include <stdbool.h>
+#include <osmocom/core/bits.h> #include <osmocom/core/bitvec.h>
#define BITNUM_FROM_COMP(byte, bit) ((byte*8)+bit) @@ -225,6 +227,21 @@ int bitvec_set_uint(struct bitvec *bv, unsigned int ui, unsigned int num_bits) return 0; }
+/*! \brief get multiple bits (num_bits) from beginning of vector (MSB side) */ +int16_t bitvec_get_int16_msb(const struct bitvec *bv, unsigned int num_bits) +{ + if (num_bits > 15 || bv->cur_bit < num_bits) return -EINVAL; + + if (num_bits < 9) { + return bv->data[0] >> (8 - num_bits); + } + + uint8_t tmp[2]; + memcpy(tmp, bv->data, 2); + uint16_t t = osmo_load16be(tmp); + return t >> (16 - num_bits); +} + /*! \brief get multiple bits (based on numeric value) from current pos */ int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) { @@ -243,17 +260,26 @@ int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) return ui; }
-/*! \brief pad all remaining bits up to num_bits */ -int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) +/*! \brief fill num_bits with \fill starting from the current position + * returns 0 on success, negative otherwise (out of vector boundary) + */ +int bitvec_fill(struct bitvec *bv, unsigned int num_bits, enum bit_value fill) { - unsigned int i; - - for (i = bv->cur_bit; i <= up_to_bit; i++) - bitvec_set_bit(bv, L); + unsigned i, stop = bv->cur_bit + num_bits; + for (i = bv->cur_bit; i < stop; i++) + if (bitvec_set_bit(bv, fill) < 0) return -EINVAL;
return 0; }
+/*! \brief pad all remaining bits up to num_bits */ +int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) +{ + int n = up_to_bit - bv->cur_bit + 1; + if (n < 1) return 0; + return bitvec_fill(bv, n, L); +} + /*! \brief find first bit set in bit vector */ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val) @@ -428,4 +454,94 @@ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val return 0; }
+/*! \brief convert enum to corresponding character */ +char bit_value_to_char(enum bit_value v) +{ + switch (v) { + case ZERO: return '0'; + case ONE: return '1'; + case L: return 'L'; + case H: return 'H'; + } + return 'X'; // make compiler happy +} + +/*! \brief prints bit vector to provided string + * It's caller's responcibility to ensure that we won't shoot him in the foot. + */ +void bitvec_to_string_r(const struct bitvec *bv, char *str) +{ + unsigned i, pos = 0; + char *cur = str; + for (i = 0; i < bv->cur_bit; i++) { + if (0 == i % 8) *cur++ = ' '; + *cur++ = bit_value_to_char(bitvec_get_bit_pos(bv, i)); + pos++; + } + *cur = 0; +} + +/* we assume that x have at least 1 non-b bit */ +static inline unsigned _leading_bits(uint8_t x, bool b) +{ + if (b) { + if (x < 0x80) return 0; + if (x < 0xC0) return 1; + if (x < 0xE0) return 2; + if (x < 0xF0) return 3; + if (x < 0xF8) return 4; + if (x < 0xFC) return 5; + if (x < 0xFE) return 6; + } else { + if (x > 0x7F) return 0; + if (x > 0x3F) return 1; + if (x > 0x1F) return 2; + if (x > 0xF) return 3; + if (x > 7) return 4; + if (x > 3) return 5; + if (x > 1) return 6; + } + return 7; +} +/*! \brief force bit vector to all 0 and current bit to the beginnig of the vector */ +void bitvec_zero(struct bitvec *bv) +{ + bv->cur_bit = 0; + memset(bv->data, 0, bv->data_len); +} + +/*! \brief Return number (bits) of uninterrupted run of \b in \bv starting from the MSB */ +unsigned bitvec_rl(const struct bitvec *bv, bool b) +{ + unsigned i; + for (i = 0; i < (bv->cur_bit % 8 ? bv->cur_bit / 8 + 1 : bv->cur_bit / 8); i++) { + if ( (b ? 0xFF : 0) != bv->data[i]) return i * 8 + _leading_bits(bv->data[i], b); + } + + return bv->cur_bit; +} + +/*! \brief Shifts bitvec to the left, n MSB bits lost */ +void bitvec_shiftl(struct bitvec *bv, unsigned n) +{ + if (0 == n) return; + if (n >= bv->cur_bit) { + bitvec_zero(bv); + return; + } + + memmove(bv->data, bv->data + n / 8, bv->data_len - n / 8); + + uint8_t tmp[2]; + unsigned i; + for (i = 0; i < bv->data_len - 2; i++) { + uint16_t t = osmo_load16be(bv->data + i); + osmo_store16be(t << (n % 8), &tmp); + bv->data[i] = tmp[0]; + } + + bv->data[bv->data_len - 1] <<= (n % 8); + bv->cur_bit -= n; +} + /*! @} */
On 22 Jan 2016, at 16:46, suraev@alumni.ntnu.no wrote:
- (C) 2015 by Sysmocom s.f.m.c. GmbH, Author: Max msuraev@sysmocom.de
not too fair for the previous contributor? So Authors if we want to have it? I let Harald comment on the right way to list authors in case they want to be mentioned.
+/*! \brief get multiple bits (num_bits) from beginning of vector (MSB side) */ +int16_t bitvec_get_int16_msb(const struct bitvec *bv, unsigned int num_bits) +{
- if (num_bits > 15 || bv->cur_bit < num_bits) return -EINVAL;
coding style. Add newline here as well for the return
- if (num_bits < 9) {
return bv->data[0] >> (8 - num_bits);- }
no braces,
- uint8_t tmp[2];
variable definitions not on first use but at the beginning of the scope. :}
/*! \brief get multiple bits (based on numeric value) from current pos */ int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) { @@ -243,17 +260,26 @@ int bitvec_get_uint(struct bitvec *bv, unsigned int num_bits) return ui; }
-/*! \brief pad all remaining bits up to num_bits */ -int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) +/*! \brief fill num_bits with \fill starting from the current position
- returns 0 on success, negative otherwise (out of vector boundary)
- */
+int bitvec_fill(struct bitvec *bv, unsigned int num_bits, enum bit_value fill) {
- unsigned int i;
- for (i = bv->cur_bit; i <= up_to_bit; i++)
bitvec_set_bit(bv, L);
- unsigned i, stop = bv->cur_bit + num_bits;
- for (i = bv->cur_bit; i < stop; i++)
if (bitvec_set_bit(bv, fill) < 0) return -EINVAL;
coding style, add newline and indent for the return statement.
return 0; }
+/*! \brief pad all remaining bits up to num_bits */ +int bitvec_spare_padding(struct bitvec *bv, unsigned int up_to_bit) +{
- int n = up_to_bit - bv->cur_bit + 1;
- if (n < 1) return 0;
coding style.
- return bitvec_fill(bv, n, L);
+}
/*! \brief find first bit set in bit vector */ int bitvec_find_bit_pos(const struct bitvec *bv, unsigned int n, enum bit_value val) @@ -428,4 +454,94 @@ int bitvec_write_field(struct bitvec *bv, unsigned int write_index, uint64_t val return 0; }
+/*! \brief convert enum to corresponding character */ +char bit_value_to_char(enum bit_value v) +{
- switch (v) {
- case ZERO: return '0';
- case ONE: return '1';
- case L: return 'L';
- case H: return 'H';
newline for the return?
- }
- return 'X'; // make compiler happy
is it complaining? use default: and __builtin_not_reached or such?
+}
+/*! \brief prints bit vector to provided string
- It's caller's responcibility to ensure that we won't shoot him in the foot.
- */
+void bitvec_to_string_r(const struct bitvec *bv, char *str) +{
- unsigned i, pos = 0;
- char *cur = str;
- for (i = 0; i < bv->cur_bit; i++) {
if (0 == i % 8) *cur++ = ' ';
coding style and add line wrapping
*cur++ = bit_value_to_char(bitvec_get_bit_pos(bv, i));pos++;- }
- *cur = 0;
+}
+/* we assume that x have at least 1 non-b bit */ +static inline unsigned _leading_bits(uint8_t x, bool b) +{
- if (b) {
if (x < 0x80) return 0;if (x < 0xC0) return 1;if (x < 0xE0) return 2;if (x < 0xF0) return 3;if (x < 0xF8) return 4;if (x < 0xFC) return 5;if (x < 0xFE) return 6;- } else {
if (x > 0x7F) return 0;if (x > 0x3F) return 1;if (x > 0x1F) return 2;if (x > 0xF) return 3;if (x > 7) return 4;if (x > 3) return 5;if (x > 1) return 6;- }
same coding style thing
- return 7;
+} +/*! \brief force bit vector to all 0 and current bit to the beginnig of the vector */ +void bitvec_zero(struct bitvec *bv) +{
- bv->cur_bit = 0;
- memset(bv->data, 0, bv->data_len);
+}
+/*! \brief Return number (bits) of uninterrupted run of \b in \bv starting from the MSB */ +unsigned bitvec_rl(const struct bitvec *bv, bool b) +{
- unsigned i;
- for (i = 0; i < (bv->cur_bit % 8 ? bv->cur_bit / 8 + 1 : bv->cur_bit / 8); i++) {
if ( (b ? 0xFF : 0) != bv->data[i]) return i * 8 + _leading_bits(bv->data[i], b);
coding style add new line
- }
- return bv->cur_bit;
+}
+/*! \brief Shifts bitvec to the left, n MSB bits lost */ +void bitvec_shiftl(struct bitvec *bv, unsigned n) +{
- if (0 == n) return;
coding style
- if (n >= bv->cur_bit) {
bitvec_zero(bv);return;- }
- memmove(bv->data, bv->data + n / 8, bv->data_len - n / 8);
- uint8_t tmp[2];
- unsigned i;
- for (i = 0; i < bv->data_len - 2; i++) {
uint16_t t = osmo_load16be(bv->data + i);osmo_store16be(t << (n % 8), &tmp);bv->data[i] = tmp[0];- }
- bv->data[bv->data_len - 1] <<= (n % 8);
- bv->cur_bit -= n;
otherwise it does look fine.
holger
On 26.01.2016 11:22, Holger Freyther wrote:
On 22 Jan 2016, at 16:46, suraev@alumni.ntnu.no wrote:
+/* we assume that x have at least 1 non-b bit */ +static inline unsigned _leading_bits(uint8_t x, bool b) +{
- if (b) {
if (x < 0x80) return 0;if (x < 0xC0) return 1;if (x < 0xE0) return 2;if (x < 0xF0) return 3;if (x < 0xF8) return 4;if (x < 0xFC) return 5;if (x < 0xFE) return 6;- } else {
if (x > 0x7F) return 0;if (x > 0x3F) return 1;if (x > 0x1F) return 2;if (x > 0xF) return 3;if (x > 7) return 4;if (x > 3) return 5;if (x > 1) return 6;- }
same coding style thing
In such cases, the readability would suffer when putting the returns in the next line. I'd rather right align the numbers after the '>', but YMMV.
Jacob
On 26 Jan 2016, at 12:17, Jacob Erlbeck jerlbeck@sysmocom.de wrote:
On 26.01.2016 11:22, Holger Freyther wrote:
On 22 Jan 2016, at 16:46, suraev@alumni.ntnu.no wrote:
+/* we assume that x have at least 1 non-b bit */ +static inline unsigned _leading_bits(uint8_t x, bool b) +{
- if (b) {
if (x < 0x80) return 0;if (x < 0xC0) return 1;if (x < 0xE0) return 2;if (x < 0xF0) return 3;if (x < 0xF8) return 4;if (x < 0xFC) return 5;if (x < 0xFE) return 6;- } else {
if (x > 0x7F) return 0;if (x > 0x3F) return 1;if (x > 0x1F) return 2;if (x > 0xF) return 3;if (x > 7) return 4;if (x > 3) return 5;if (x > 1) return 6;- }
same coding style thing
In such cases, the readability would suffer when putting the returns in the next line. I'd rather right align the numbers after the '>', but YMMV.
sure or somemthing like case 0xff..0x80: return 0; case 0x7F..0xC0: return 1;
anyway, the above is okay and something we can argue with but if it is more than a "look-up table" then we should break the line.
Attached v2 with style changed in places where it does not adversely affect readability. Feel free to amend commit to adjust copyright header as you see fit.
cheers, Max.
From: Max msuraev@sysmocom.de
Sponsored-by: On-Waves ehf --- tests/bitvec/bitvec_test.c | 143 +++++++++++++++++++++++++++++++++++++++++++- tests/bitvec/bitvec_test.ok | 119 ++++++++++++++++++++++++++++++++++++ 2 files changed, 260 insertions(+), 2 deletions(-)
diff --git a/tests/bitvec/bitvec_test.c b/tests/bitvec/bitvec_test.c index 624e334..c31e5df 100644 --- a/tests/bitvec/bitvec_test.c +++ b/tests/bitvec/bitvec_test.c @@ -3,9 +3,82 @@ #include <stdlib.h> #include <stdint.h> #include <string.h> +#include <time.h> +#include <stdbool.h> +#include <errno.h>
#include <osmocom/core/utils.h> #include <osmocom/core/bitvec.h> +#include <osmocom/core/bits.h> + +#define BIN_PATTERN "%d%d%d%d%d%d%d%d" +#define BIN(byte) \ + (byte & 0x80 ? 1 : 0), \ + (byte & 0x40 ? 1 : 0), \ + (byte & 0x20 ? 1 : 0), \ + (byte & 0x10 ? 1 : 0), \ + (byte & 0x08 ? 1 : 0), \ + (byte & 0x04 ? 1 : 0), \ + (byte & 0x02 ? 1 : 0), \ + (byte & 0x01 ? 1 : 0) + +static char lol[1024]; // we pollute this with printed vectors +static inline void test_rl(const struct bitvec *bv) +{ + bitvec_to_string_r(bv, lol); + printf("%s [%d] RL0=%d, RL1=%d\n", lol, bv->cur_bit, bitvec_rl(bv, false), bitvec_rl(bv, true)); +} + +static inline void test_shift(struct bitvec *bv, unsigned n) +{ + bitvec_to_string_r(bv, lol); + printf("%s << %d:\n", lol, n); + bitvec_shiftl(bv, n); + bitvec_to_string_r(bv, lol); + printf("%s\n", lol); +} + +static inline void test_get(struct bitvec *bv, unsigned n) +{ + bitvec_to_string_r(bv, lol); + printf("%s [%d]", lol, bv->cur_bit); + int16_t x = bitvec_get_int16_msb(bv, n); + uint8_t tmp[2]; + osmo_store16be(x, &tmp); + printf(" -> %d (%u bit) ["BIN_PATTERN" "BIN_PATTERN"]:\n", x, n, BIN(tmp[0]), BIN(tmp[1])); + bitvec_to_string_r(bv, lol); + printf("%s [%d]\n", lol, bv->cur_bit); +} + +static inline void test_fill(struct bitvec *bv, unsigned n, enum bit_value val) +{ + bitvec_to_string_r(bv, lol); + unsigned bvlen = bv->cur_bit; + int fi = bitvec_fill(bv, n, val); + printf("%c> FILL %s [%d] -%d-> [%d]:\n", bit_value_to_char(val), lol, bvlen, n, fi); + bitvec_to_string_r(bv, lol); + printf(" %s [%d]\n\n", lol, bv->cur_bit); +} + +static inline void test_spare(struct bitvec *bv, unsigned n) +{ + bitvec_to_string_r(bv, lol); + unsigned bvlen = bv->cur_bit; + int sp = bitvec_spare_padding(bv, n); + printf("%c> SPARE %s [%d] -%d-> [%d]:\n", bit_value_to_char(L), lol, bvlen, n, sp); + bitvec_to_string_r(bv, lol); + printf(" %s [%d]\n\n", lol, bv->cur_bit); +} + +static inline void test_set(struct bitvec *bv, enum bit_value bit) +{ + bitvec_to_string_r(bv, lol); + unsigned bvlen = bv->cur_bit; + int set = bitvec_set_bit(bv, bit); + printf("%c> SET %s [%d] ++> [%d]:\n", bit_value_to_char(bit), lol, bvlen, set); + bitvec_to_string_r(bv, lol); + printf(" %s [%d]\n\n", lol, bv->cur_bit); +}
static void test_byte_ops() { @@ -33,7 +106,7 @@ static void test_byte_ops() rc = bitvec_set_uint(&bv, 0x7e, 8); OSMO_ASSERT(rc >= 0);
- fprintf(stderr, "bitvec: %s\n", osmo_hexdump(bv.data, bv.data_len)); + printf("bitvec: %s\n", osmo_hexdump(bv.data, bv.data_len));
/* Read from bitvec */ memset(out, 0xff, sizeof(out)); @@ -45,7 +118,7 @@ static void test_byte_ops() rc = bitvec_get_uint(&bv, 8); OSMO_ASSERT(rc == 0x7e);
- fprintf(stderr, "out: %s\n", osmo_hexdump(out, sizeof(out))); + printf("out: %s\n", osmo_hexdump(out, sizeof(out)));
OSMO_ASSERT(out[0] == 0xff); OSMO_ASSERT(out[in_size+1] == 0xff); @@ -57,6 +130,72 @@ static void test_byte_ops()
int main(int argc, char **argv) { + srand(time(NULL)); + + struct bitvec bv; + uint8_t i = 8, test[i]; + + memset(test, 0, i); + bv.data_len = i; + bv.data = test; + bv.cur_bit = 0; + + printf("test shifting...\n"); + + bitvec_set_uint(&bv, 0x0E, 7); + test_shift(&bv, 3); + test_shift(&bv, 17); + bitvec_set_uint(&bv, 0, 32); + bitvec_set_uint(&bv, 0x0A, 7); + test_shift(&bv, 24); + + printf("checking RL functions...\n"); + + bitvec_zero(&bv); + test_rl(&bv); + bitvec_set_uint(&bv, 0x000F, 32); + test_rl(&bv); + bitvec_shiftl(&bv, 18); + test_rl(&bv); + bitvec_set_uint(&bv, 0x0F, 8); + test_rl(&bv); + bitvec_zero(&bv); + bitvec_set_uint(&bv, 0xFF, 8); + test_rl(&bv); + bitvec_set_uint(&bv, 0xFE, 7); + test_rl(&bv); + bitvec_set_uint(&bv, 0, 17); + test_rl(&bv); + bitvec_shiftl(&bv, 18); + test_rl(&bv); + + printf("probing bit access...\n"); + + bitvec_zero(&bv); + bitvec_set_uint(&bv, 0x3747817, 32); + bitvec_shiftl(&bv, 10); + + test_get(&bv, 2); + test_get(&bv, 7); + test_get(&bv, 9); + test_get(&bv, 13); + test_get(&bv, 16); + test_get(&bv, 42); + + printf("feeling bit fills...\n"); + + test_set(&bv, ONE); + test_fill(&bv, 3, ZERO); + test_spare(&bv, 38); + test_spare(&bv, 43); + test_spare(&bv, 1); + test_spare(&bv, 7); + test_fill(&bv, 5, ONE); + test_fill(&bv, 3, L); + + printf("byte me...\n"); + test_byte_ops(); + return 0; } diff --git a/tests/bitvec/bitvec_test.ok b/tests/bitvec/bitvec_test.ok index 1f329af..38575f7 100644 --- a/tests/bitvec/bitvec_test.ok +++ b/tests/bitvec/bitvec_test.ok @@ -1,2 +1,121 @@ +test shifting... + 0001110 << 3: + 1110 + 1110 << 17: + + 00000000 00000000 00000000 00000000 0001010 << 24: + 00000000 0001010 +checking RL functions... + [0] RL0=0, RL1=0 + 00000000 00000000 00000000 00001111 [32] RL0=28, RL1=0 + 00000000 001111 [14] RL0=10, RL1=0 + 00000000 00111100 001111 [22] RL0=10, RL1=0 + 11111111 [8] RL0=0, RL1=8 + 11111111 1111110 [15] RL0=0, RL1=14 + 11111111 11111100 00000000 00000000 [32] RL0=0, RL1=14 + 00000000 000000 [14] RL0=14, RL1=0 +probing bit access... + 11010001 11100000 010111 [22] -> 3 (2 bit) [00000000 00000011]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> 104 (7 bit) [00000000 01101000]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> 419 (9 bit) [00000001 10100011]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> 6716 (13 bit) [00011010 00111100]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> -22 (16 bit) [11111111 11101010]: + 11010001 11100000 010111 [22] + 11010001 11100000 010111 [22] -> -22 (42 bit) [11111111 11101010]: + 11010001 11100000 010111 [22] +feeling bit fills... +1> SET 11010001 11100000 010111 [22] ++> [0]: + 11010001 11100000 0101111 [23] + +0> FILL 11010001 11100000 0101111 [23] -3-> [0]: + 11010001 11100000 01011110 00 [26] + +L> SPARE 11010001 11100000 01011110 00 [26] -38-> [0]: + 11010001 11100000 01011110 00101011 0010101 [39] + +L> SPARE 11010001 11100000 01011110 00101011 0010101 [39] -43-> [0]: + 11010001 11100000 01011110 00101011 00101011 0010 [44] + +L> SPARE 11010001 11100000 01011110 00101011 00101011 0010 [44] -1-> [0]: + 11010001 11100000 01011110 00101011 00101011 0010 [44] + +L> SPARE 11010001 11100000 01011110 00101011 00101011 0010 [44] -7-> [0]: + 11010001 11100000 01011110 00101011 00101011 0010 [44] + +1> FILL 11010001 11100000 01011110 00101011 00101011 0010 [44] -5-> [0]: + 11010001 11100000 01011110 00101011 00101011 00101111 1 [49] + +L> FILL 11010001 11100000 01011110 00101011 00101011 00101111 1 [49] -3-> [0]: + 11010001 11100000 01011110 00101011 00101011 00101111 1010 [52] + +byte me... === start test_byte_ops === +bitvec: 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 7e 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 7e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 3f 20 a1 21 a2 22 a3 23 a4 24 a5 25 a6 26 a7 27 a8 28 a9 29 aa 2a ab 2b ac 2c ad 3f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 1f 90 50 90 d1 11 51 91 d2 12 52 92 d3 13 53 93 d4 14 54 94 d5 15 55 95 d6 16 56 9f 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 0f c8 28 48 68 88 a8 c8 e9 09 29 49 69 89 a9 c9 ea 0a 2a 4a 6a 8a aa ca eb 0b 2b 4f c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 07 e4 14 24 34 44 54 64 74 84 94 a4 b4 c4 d4 e4 f5 05 15 25 35 45 55 65 75 85 95 a7 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 03 f2 0a 12 1a 22 2a 32 3a 42 4a 52 5a 62 6a 72 7a 82 8a 92 9a a2 aa b2 ba c2 ca d3 f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 01 f9 05 09 0d 11 15 19 1d 21 25 29 2d 31 35 39 3d 41 45 49 4d 51 55 59 5d 61 65 69 f8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff +bitvec: 00 00 00 00 fc 82 84 86 88 8a 8c 8e 90 92 94 96 98 9a 9c 9e a0 a2 a4 a6 a8 aa ac ae b0 b2 b4 fc 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 +out: ff 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a ff === end test_byte_ops ===
This is v3 version of bitvec patchset.
Difference from previous submissions:
- fix for build issue with asan - split into several commits - added corresponding functions from osmo-pcu
cheers, Max.