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