dovecot-2.2: liblib: Added "number packing" API.
dovecot at dovecot.org
dovecot at dovecot.org
Sat Aug 11 07:47:40 EEST 2012
details: http://hg.dovecot.org/dovecot-2.2/rev/b45d968adff8
changeset: 14861:b45d968adff8
user: Timo Sirainen <tss at iki.fi>
date: Sat Aug 11 07:46:42 2012 +0300
description:
liblib: Added "number packing" API.
diffstat:
src/lib/Makefile.am | 3 +++
src/lib/numpack.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
src/lib/numpack.h | 10 ++++++++++
src/lib/test-lib.c | 1 +
src/lib/test-lib.h | 1 +
src/lib/test-numpack.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 104 insertions(+), 0 deletions(-)
diffs (160 lines):
diff -r f0feae227c60 -r b45d968adff8 src/lib/Makefile.am
--- a/src/lib/Makefile.am Sat Aug 11 05:47:03 2012 +0300
+++ b/src/lib/Makefile.am Sat Aug 11 07:46:42 2012 +0300
@@ -95,6 +95,7 @@
mountpoint.c \
network.c \
nfs-workarounds.c \
+ numpack.c \
ostream.c \
ostream-file.c \
ostream-buffer.c \
@@ -207,6 +208,7 @@
mountpoint.h \
network.h \
nfs-workarounds.h \
+ numpack.h \
ostream.h \
ostream-private.h \
ostream-rawlog.h \
@@ -273,6 +275,7 @@
test-llist.c \
test-mempool-alloconly.c \
test-network.c \
+ test-numpack.c \
test-ostream-file.c \
test-primes.c \
test-priorityq.c \
diff -r f0feae227c60 -r b45d968adff8 src/lib/numpack.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/numpack.c Sat Aug 11 07:46:42 2012 +0300
@@ -0,0 +1,45 @@
+/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "buffer.h"
+#include "numpack.h"
+
+void numpack_encode(buffer_t *buf, uint64_t num)
+{
+ /* number continues as long as the highest bit is set */
+ while (num >= 0x80) {
+ buffer_append_c(buf, (num & 0x7f) | 0x80);
+ num >>= 7;
+ }
+
+ buffer_append_c(buf, num);
+}
+
+int numpack_decode(const uint8_t **p, const uint8_t *end, uint64_t *num_r)
+{
+ const uint8_t *c = *p;
+ uint64_t value = 0;
+ unsigned int bits = 0;
+
+ for (;;) {
+ if (c == end)
+ return -1;
+
+ value |= (uint64_t)(*c & 0x7f) << bits;
+ if (*c < 0x80)
+ break;
+
+ bits += 7;
+ c++;
+ }
+
+ if (bits >= 64) {
+ /* overflow */
+ *p = end;
+ return -1;
+ }
+
+ *p = c + 1;
+ *num_r = value;
+ return 0;
+}
diff -r f0feae227c60 -r b45d968adff8 src/lib/numpack.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/numpack.h Sat Aug 11 07:46:42 2012 +0300
@@ -0,0 +1,10 @@
+#ifndef NUMPACK_H
+#define NUMPACK_H
+
+/* Numbers are stored by 7 bits at a time. The highest bit specifies if the
+ number continues to next byte. */
+
+void numpack_encode(buffer_t *buf, uint64_t num);
+int numpack_decode(const uint8_t **p, const uint8_t *end, uint64_t *num_r);
+
+#endif
diff -r f0feae227c60 -r b45d968adff8 src/lib/test-lib.c
--- a/src/lib/test-lib.c Sat Aug 11 05:47:03 2012 +0300
+++ b/src/lib/test-lib.c Sat Aug 11 07:46:42 2012 +0300
@@ -23,6 +23,7 @@
test_llist,
test_mempool_alloconly,
test_network,
+ test_numpack,
test_ostream_file,
test_primes,
test_priorityq,
diff -r f0feae227c60 -r b45d968adff8 src/lib/test-lib.h
--- a/src/lib/test-lib.h Sat Aug 11 05:47:03 2012 +0300
+++ b/src/lib/test-lib.h Sat Aug 11 07:46:42 2012 +0300
@@ -22,6 +22,7 @@
void test_llist(void);
void test_mempool_alloconly(void);
void test_network(void);
+void test_numpack(void);
void test_ostream_file(void);
void test_primes(void);
void test_priorityq(void);
diff -r f0feae227c60 -r b45d968adff8 src/lib/test-numpack.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/test-numpack.c Sat Aug 11 07:46:42 2012 +0300
@@ -0,0 +1,44 @@
+/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "buffer.h"
+#include "numpack.h"
+
+#include <stdlib.h>
+
+static struct test {
+ uint64_t input;
+ uint8_t output[10];
+ unsigned int output_size;
+} tests[] = {
+ { 0xffffffff, { 0xff, 0xff, 0xff, 0xff, 0xf }, 5 },
+ { 0, { 0 }, 1 },
+ { 0x7f, { 0x7f }, 1 },
+ { 0x80, { 0x80, 1 }, 2 },
+ { 0x81, { 0x81, 1 }, 2 },
+ { 0xdeadbeefcafe, { 0xfe, 0x95, 0xbf, 0xf7, 0xdb, 0xd5, 0x37 }, 7 },
+ { 0xffffffffffffffff, { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 1 }, 10 },
+ { 0xfffffffe, { 0xfe, 0xff, 0xff, 0xff, 0xf }, 5 },
+};
+
+void test_numpack(void)
+{
+ buffer_t *buf = buffer_create_dynamic(pool_datastack_create(), 32);
+ unsigned int i;
+ const uint8_t *p, *end;
+ uint64_t num;
+
+ test_begin("numpack");
+ for (i = 0; i < N_ELEMENTS(tests); i++) {
+ buffer_set_used_size(buf, 0);
+ numpack_encode(buf, tests[i].input);
+ test_assert(buf->used == tests[i].output_size &&
+ memcmp(buf->data, tests[i].output,
+ tests[i].output_size) == 0);
+
+ p = buf->data; end = p + buf->used;
+ test_assert(numpack_decode(&p, end, &num) == 0);
+ test_assert(num == tests[i].input);
+ }
+ test_end();
+}
More information about the dovecot-cvs
mailing list