From: Pierre Habouzit Date: Sat, 26 May 2007 16:42:17 +0000 (+0200) Subject: Add efficient bit-fields manipulations. X-Git-Url: http://git.madism.org/?a=commitdiff_plain;h=aed03232cc25bcb1104a17c631924b867659944c;p=apps%2Fmadmutt.git Add efficient bit-fields manipulations. Signed-off-by: Pierre Habouzit --- diff --git a/lib-lib/CMakeLists.txt b/lib-lib/CMakeLists.txt index b8af186..2a6e031 100644 --- a/lib-lib/CMakeLists.txt +++ b/lib-lib/CMakeLists.txt @@ -1,14 +1,15 @@ ADD_LIBRARY(lib - str.c - md5.c - utf8.c + array.c + bits.c buffer.c + date.c + file.c hash.c - array.c list.c - file.c mapping.c - date.c + md5.c rx.c + str.c url.c + utf8.c ) diff --git a/lib-lib/bits.c b/lib-lib/bits.c new file mode 100644 index 0000000..1cd09ef --- /dev/null +++ b/lib-lib/bits.c @@ -0,0 +1,48 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +/* + * Copyright © 2007 Pierre Habouzit + */ + +#include "lib-lib.h" + +#define UPPER_32(x) (((x) + 31) & ~31) +#define LOWER_32(x) ((x) & ~31) + +void bits_extend(bits_t *bits, int pos) +{ + if (bits->size == 0) { + bits->start = LOWER_32(pos >> 3); + } + + if (pos >> 3 > bits->start + bits->size) { + int newsize = UPPER_32((pos >> 3) - bits->start + 1); + p_realloc(&bits->bits, bits->size = newsize); + return; + } + + if (pos >> 3 < bits->start) { + unsigned char *tmp = bits->bits; + int prepend = LOWER_32(bits->start - (pos >> 3)); + + bits->bits = p_new(unsigned char, bits->size + prepend); + memcpy(bits->bits + prepend, tmp, bits->size); + bits->size += prepend; + bits->start -= prepend; + p_delete(&tmp); + } +} diff --git a/lib-lib/bits.h b/lib-lib/bits.h new file mode 100644 index 0000000..499189b --- /dev/null +++ b/lib-lib/bits.h @@ -0,0 +1,83 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +/* + * Copyright © 2007 Pierre Habouzit + */ + +#ifndef MUTT_LIB_LIB_BITS_H +#define MUTT_LIB_LIB_BITS_H + +typedef struct bits_t { + int start; + int size; + unsigned char *bits; +} bits_t; + +void bits_extend(bits_t *bits, int pos); + +DO_INIT(bits_t, bits); +static inline void bits_wipe(bits_t *bits) { + p_delete(&bits->bits); +} +DO_NEW(bits_t, bits); +DO_DELETE(bits_t, bits); + +static inline void bits_clear(bits_t *bits) +{ + bits_wipe(bits); + bits_init(bits); +} + +static inline bool bit_isset(const bits_t *bits, int pos) +{ + int offs = (pos >> 3) - bits->start; + if (offs < 0 || offs > bits->size) + return false; + + return (bits->bits[offs] & (1 << (pos & 7))) != 0; +} + +static inline void bit_set(bits_t *bits, int pos) +{ + int offs = (pos >> 3) - bits->start; + if (offs < 0 || offs > bits->size) { + bits_extend(bits, pos); + offs = (pos >> 3) - bits->start; + } + bits->bits[offs] |= 1 << (pos & 7); +} + +static inline void bit_clear(bits_t *bits, int pos) +{ + int offs = (pos >> 3) - bits->start; + if (offs < 0 || offs > bits->size) + return; + bits->bits[offs] &= ~(1 << (pos & 7)); +} + +static inline void bit_toggle(bits_t *bits, int pos) +{ + int offs = (pos >> 3) - bits->start; + if (offs < 0 || offs > bits->size) { + bits_extend(bits, pos); + offs = (pos >> 3) - bits->start; + } + bits->bits[offs] ^= 1 << (pos & 7); +} + + +#endif /* MUTT_LIB_LIB_BITS_H */ diff --git a/lib-lib/lib-lib.h b/lib-lib/lib-lib.h index c254e95..edee99b 100644 --- a/lib-lib/lib-lib.h +++ b/lib-lib/lib-lib.h @@ -58,6 +58,7 @@ #elif HAVE_INTTYPES_H # include #endif +#include #ifdef HAVE_SYS_TIME_H # include @@ -113,6 +114,7 @@ typedef union __attribute__((transparent_union)) anytype { #include "utf8.h" #include "array.h" +#include "bits.h" #include "buffer.h" #include "date.h" #include "file.h"