diff options
Diffstat (limited to 'util')
-rw-r--r-- | util/bitmap.c | 85 | ||||
-rw-r--r-- | util/cutils.c | 8 |
2 files changed, 89 insertions, 4 deletions
diff --git a/util/bitmap.c b/util/bitmap.c index cb618c65a5..1753ff7f5b 100644 --- a/util/bitmap.c +++ b/util/bitmap.c @@ -402,3 +402,88 @@ void bitmap_to_le(unsigned long *dst, const unsigned long *src, { bitmap_to_from_le(dst, src, nbits); } + +/* + * Copy "src" bitmap with a positive offset and put it into the "dst" + * bitmap. The caller needs to make sure the bitmap size of "src" + * is bigger than (shift + nbits). + */ +void bitmap_copy_with_src_offset(unsigned long *dst, const unsigned long *src, + unsigned long shift, unsigned long nbits) +{ + unsigned long left_mask, right_mask, last_mask; + + /* Proper shift src pointer to the first word to copy from */ + src += BIT_WORD(shift); + shift %= BITS_PER_LONG; + + if (!shift) { + /* Fast path */ + bitmap_copy(dst, src, nbits); + return; + } + + right_mask = (1ul << shift) - 1; + left_mask = ~right_mask; + + while (nbits >= BITS_PER_LONG) { + *dst = (*src & left_mask) >> shift; + *dst |= (src[1] & right_mask) << (BITS_PER_LONG - shift); + dst++; + src++; + nbits -= BITS_PER_LONG; + } + + if (nbits > BITS_PER_LONG - shift) { + *dst = (*src & left_mask) >> shift; + nbits -= BITS_PER_LONG - shift; + last_mask = (1ul << nbits) - 1; + *dst |= (src[1] & last_mask) << (BITS_PER_LONG - shift); + } else if (nbits) { + last_mask = (1ul << nbits) - 1; + *dst = (*src >> shift) & last_mask; + } +} + +/* + * Copy "src" bitmap into the "dst" bitmap with an offset in the + * "dst". The caller needs to make sure the bitmap size of "dst" is + * bigger than (shift + nbits). + */ +void bitmap_copy_with_dst_offset(unsigned long *dst, const unsigned long *src, + unsigned long shift, unsigned long nbits) +{ + unsigned long left_mask, right_mask, last_mask; + + /* Proper shift dst pointer to the first word to copy from */ + dst += BIT_WORD(shift); + shift %= BITS_PER_LONG; + + if (!shift) { + /* Fast path */ + bitmap_copy(dst, src, nbits); + return; + } + + right_mask = (1ul << (BITS_PER_LONG - shift)) - 1; + left_mask = ~right_mask; + + *dst &= (1ul << shift) - 1; + while (nbits >= BITS_PER_LONG) { + *dst |= (*src & right_mask) << shift; + dst[1] = (*src & left_mask) >> (BITS_PER_LONG - shift); + dst++; + src++; + nbits -= BITS_PER_LONG; + } + + if (nbits > BITS_PER_LONG - shift) { + *dst |= (*src & right_mask) << shift; + nbits -= BITS_PER_LONG - shift; + last_mask = ((1ul << nbits) - 1) << (BITS_PER_LONG - shift); + dst[1] = (*src & last_mask) >> (BITS_PER_LONG - shift); + } else if (nbits) { + last_mask = (1ul << nbits) - 1; + *dst |= (*src & last_mask) << shift; + } +} diff --git a/util/cutils.c b/util/cutils.c index dfc605f1ef..fd591cadf0 100644 --- a/util/cutils.c +++ b/util/cutils.c @@ -756,11 +756,11 @@ int uleb128_encode_small(uint8_t *out, uint32_t n) { g_assert(n <= 0x3fff); if (n < 0x80) { - *out++ = n; + *out = n; return 1; } else { *out++ = (n & 0x7f) | 0x80; - *out++ = n >> 7; + *out = n >> 7; return 2; } } @@ -768,7 +768,7 @@ int uleb128_encode_small(uint8_t *out, uint32_t n) int uleb128_decode_small(const uint8_t *in, uint32_t *n) { if (!(*in & 0x80)) { - *n = *in++; + *n = *in; return 1; } else { *n = *in++ & 0x7f; @@ -776,7 +776,7 @@ int uleb128_decode_small(const uint8_t *in, uint32_t *n) if (*in & 0x80) { return -1; } - *n |= *in++ << 7; + *n |= *in << 7; return 2; } } |