From: Phil Carmody Date: Mon, 9 Jun 2014 20:02:52 +0000 (+0300) Subject: lib: bit twiddles X-Git-Tag: 2.2.14.rc1~423 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3637a2ad3b2ead17efd5591f73effd3b140d8d2d;p=thirdparty%2Fdovecot%2Fcore.git lib: bit twiddles bits_requiredXX() gives the number of bits required to store an unsigned integer. Here, XX is 8, 16, 32, 64, reperesenting the size of the operand. It belongs in the same file as nearest_power(), which makes most sense in a separate bit twiddles file. Universal enough to stay in lib.h by inclusion. Signed-off-by: Phil Carmody --- diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index 67aa4affd5..fc6661706c 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -17,6 +17,7 @@ liblib_la_SOURCES = \ askpass.c \ backtrace-string.c \ base64.c \ + bits.c \ bsearch-insert-pos.c \ buffer.c \ child-wait.c \ @@ -146,6 +147,7 @@ headers = \ askpass.h \ backtrace-string.h \ base64.h \ + bits.h \ bsearch-insert-pos.h \ buffer.h \ child-wait.h \ diff --git a/src/lib/bits.c b/src/lib/bits.c new file mode 100644 index 0000000000..28f03f7e41 --- /dev/null +++ b/src/lib/bits.c @@ -0,0 +1,22 @@ +/* Copyright (c) 2001-2014 Dovecot authors, see the included COPYING file */ + +#include "lib.h" + +size_t nearest_power(size_t num) +{ + size_t n = 1; + + i_assert(num <= ((size_t)1 << (CHAR_BIT*sizeof(size_t) - 1))); + + while (n < num) n <<= 1; + return n; +} + +unsigned int bits_required8(uint8_t num) +{ + int ret = 0; + if (num > 0xf) { ret += 4; num >>= 4; } + if (num > 0x3) { ret += 2; num >>= 2; } + num &= ~(num>>1); /* 3->2, else unchanged */ + return ret + num; +} diff --git a/src/lib/bits.h b/src/lib/bits.h new file mode 100644 index 0000000000..528152a064 --- /dev/null +++ b/src/lib/bits.h @@ -0,0 +1,38 @@ +#ifndef BITS_H +#define BITS_H + +/* default lib includes */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include "macros.h" + +#include +#include +#include + +size_t nearest_power(size_t num) ATTR_CONST; + +unsigned int bits_required8(uint8_t num) ATTR_CONST; + +static inline +unsigned int bits_required16(uint16_t num) +{ + return (num <= 0xff) ? bits_required8(num) + : 8 + bits_required16(num >> 8); +} +static inline +unsigned int bits_required32(uint32_t num) +{ + return (num <= 0xffff) ? bits_required16(num) + : 16 + bits_required16(num >> 16); +} +static inline +unsigned int bits_required64(uint64_t num) +{ + return (num <= 0xffffffff) ? bits_required32(num) + : 32 + bits_required32(num >> 32); +} + +#endif diff --git a/src/lib/lib.c b/src/lib/lib.c index c9046ffa5e..475e89595b 100644 --- a/src/lib/lib.c +++ b/src/lib/lib.c @@ -13,16 +13,6 @@ static ARRAY(lib_atexit_callback_t *) atexit_callbacks = ARRAY_INIT; -size_t nearest_power(size_t num) -{ - size_t n = 1; - - i_assert(num <= ((size_t)1 << (CHAR_BIT*sizeof(size_t) - 1))); - - while (n < num) n <<= 1; - return n; -} - int close_keep_errno(int *fd) { int ret, old_errno = errno; diff --git a/src/lib/lib.h b/src/lib/lib.h index 6e799e97bc..73b6488814 100644 --- a/src/lib/lib.h +++ b/src/lib/lib.h @@ -38,11 +38,11 @@ struct ostream; typedef void lib_atexit_callback_t(void); #include "array-decl.h" /* ARRAY*()s may exist in any header */ +#include "bits.h" #include "hash-decl.h" /* HASH_TABLE*()s may exist in any header */ #include "strfuncs.h" #include "strnum.h" -size_t nearest_power(size_t num) ATTR_CONST; int close_keep_errno(int *fd); /* Call the given callback at the beginning of lib_deinit(). The main