1 /***************************************************************************
2 * Copyright (C) 2012~2012 by CSSlayer *
3 * wengxt@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
20
21
22 #ifndef _FCITX_UTILS_BITSET_H_
23 #define _FCITX_UTILS_BITSET_H_
24
25 #include <string.h>
26 #include <stdint.h>
27 #include <fcitx-utils/utils.h>
28
29 typedef struct _FcitxBitSet FcitxBitSet;
30
31 struct _FcitxBitSet {
32 size_t size;
33 uint8_t data[1];
34 };
35
fcitx_bitset_datasize(size_t bits)36 static inline size_t fcitx_bitset_datasize(size_t bits)
37 {
38 return (bits + 7) / 8;
39 }
40
fcitx_bitset_size(size_t bits)41 static inline size_t fcitx_bitset_size(size_t bits)
42 {
43 return (sizeof(size_t) + fcitx_bitset_datasize(bits));
44 }
45
46 /**
47 * create a bitset with size
48 *
49 * @param bits bits inside this bitset
50 *
51 * @return bitset
52 */
fcitx_bitset_new(size_t bits)53 static inline FcitxBitSet* fcitx_bitset_new(size_t bits)
54 {
55 /* round up */
56 FcitxBitSet* bitset = fcitx_utils_malloc0(fcitx_bitset_size(bits));
57 bitset->size = bits;
58 return bitset;
59 }
60
fcitx_bitset_copy(FcitxBitSet * dst,FcitxBitSet * src)61 static inline void fcitx_bitset_copy(FcitxBitSet* dst, FcitxBitSet* src)
62 {
63 if (dst->size != src->size)
64 return;
65 memcpy(dst->data, src->data, fcitx_bitset_datasize(dst->size));
66 }
67
68 /**
69 * clear entire bitset
70 *
71 * @param bitset bitset
72 * @return void
73 */
fcitx_bitset_clear(FcitxBitSet * bitset)74 static inline void fcitx_bitset_clear(FcitxBitSet* bitset)
75 {
76 memset(bitset->data, 0, fcitx_bitset_datasize(bitset->size));
77 }
78
79 /**
80 * check a bit in bitset is set
81 *
82 * @param bitset bitset
83 * @param offset bit offset
84 * @return non-zero for is set
85 */
fcitx_bitset_isset(FcitxBitSet * bitset,size_t offset)86 static inline uint8_t fcitx_bitset_isset(FcitxBitSet* bitset, size_t offset)
87 {
88 size_t byte = offset / 8;
89 size_t byteoffset = offset % 8;
90 return bitset->data[byte] & (1 << byteoffset);
91 }
92
93 /**
94 * set a bit in bitset
95 *
96 * @param bitset bitset
97 * @param offset bit offset
98 * @return void
99 */
fcitx_bitset_set(FcitxBitSet * bitset,size_t offset)100 static inline void fcitx_bitset_set(FcitxBitSet* bitset, size_t offset)
101 {
102 size_t byte = offset / 8;
103 size_t byteoffset = offset % 8;
104 bitset->data[byte] |= (1 << byteoffset);
105 }
106
107 /**
108 * clear a bit in bitset
109 *
110 * @param bitset bitset
111 * @param offset bit offset
112 * @return void
113 */
fcitx_bitset_unset(FcitxBitSet * bitset,size_t offset)114 static inline void fcitx_bitset_unset(FcitxBitSet* bitset, size_t offset)
115 {
116 size_t byte = offset / 8;
117 size_t byteoffset = offset % 8;
118 uint8_t s = (1 << byteoffset);
119 s = ~s;
120 bitset->data[byte] &= s;
121 }
122
123 /**
124 * free bitset is set
125 *
126 * @param bitset bitset
127 * @return void
128 */
129 #define fcitx_bitset_free(bitset) free(bitset)
130
131 #endif
132