]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: bit twiddles
authorPhil Carmody <phil@dovecot.fi>
Mon, 9 Jun 2014 20:02:52 +0000 (23:02 +0300)
committerPhil Carmody <phil@dovecot.fi>
Mon, 9 Jun 2014 20:02:52 +0000 (23:02 +0300)
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 <phil@dovecot.fi>
src/lib/Makefile.am
src/lib/bits.c [new file with mode: 0644]
src/lib/bits.h [new file with mode: 0644]
src/lib/lib.c
src/lib/lib.h

index 67aa4affd5a2748b3c413698103346d28e0b11a1..fc6661706c7c253d90d6d6d3053727fb026da1ef 100644 (file)
@@ -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 (file)
index 0000000..28f03f7
--- /dev/null
@@ -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 (file)
index 0000000..528152a
--- /dev/null
@@ -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 <limits.h>
+#include <stddef.h>
+#include <stdint.h>
+
+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
index c9046ffa5e99e462dcb83b0b2bb12fcf8ac7d7b8..475e89595ba05727c10d012c583593a6b0f1f7f4 100644 (file)
 
 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;
index 6e799e97bc5b1c8d71cb82f01cae6e2c894f0f1b..73b64888149307081356d158d9b545e3fc19ce5e 100644 (file)
@@ -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