1 /*
2 * Copyright (C) 2011 Rudolf Polzer All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * RUDOLF POLZER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 */
21
22 #ifndef S2TC_COMMON_H
23 #define S2TC_COMMON_H
24
min(const T & a,const T & b)25 template <class T> inline T min(const T &a, const T &b)
26 {
27 if(b < a)
28 return b;
29 return a;
30 }
31
max(const T & a,const T & b)32 template <class T> inline T max(const T &a, const T &b)
33 {
34 if(b > a)
35 return b;
36 return a;
37 }
38
byteidx(int bit)39 inline int byteidx(int bit)
40 {
41 return bit >> 3;
42 }
43
bitidx(int bit)44 inline int bitidx(int bit)
45 {
46 return bit & 7;
47 }
48
49 inline void setbit(unsigned char *arr, int bit, int v = 1)
50 {
51 arr[byteidx(bit)] |= (v << bitidx(bit));
52 }
53
54 inline void xorbit(unsigned char *arr, int bit, int v = 1)
55 {
56 arr[byteidx(bit)] ^= (v << bitidx(bit));
57 }
58
59 inline int testbit(const unsigned char *arr, int bit, int v = 1)
60 {
61 return (arr[byteidx(bit)] & (v << bitidx(bit)));
62 }
63
64 template<class T, int count, int width> class bitarray
65 {
66 T bits;
67 public:
bitarray()68 inline bitarray(): bits(0)
69 {
70 }
get(size_t i)71 inline int get(size_t i) const
72 {
73 return (bits >> (i * width)) & ((T(1) << width) - 1);
74 }
set(size_t i,int v)75 inline void set(size_t i, int v)
76 {
77 size_t shift = i * width;
78 T mask = ((T(1) << width) - 1) << shift;
79 bits = (bits & ~mask) | (T(v) << shift);
80 }
do_or(size_t i,int v)81 inline void do_or(size_t i, int v)
82 {
83 bits |= (T(v) << (i * width));
84 }
do_xor(size_t i,int v)85 inline void do_xor(size_t i, int v)
86 {
87 bits ^= (T(v) << (i * width));
88 }
clear()89 inline void clear()
90 {
91 bits = 0;
92 }
getbyte(size_t p)93 inline unsigned char getbyte(size_t p) const
94 {
95 return (bits >> (p * 8)) & 0xFF;
96 }
nbytes()97 inline size_t nbytes() const
98 {
99 return (count * width + 7) >> 3;
100 }
tobytes(unsigned char * out)101 inline void tobytes(unsigned char *out) const
102 {
103 size_t s = nbytes();
104 for(size_t i = 0; i < s; ++i)
105 out[i] = getbyte(i);
106 }
107 };
108
109 template<int count, int width> class bitarray<void, count, width>
110 {
111 unsigned char bits[count];
112 public:
bitarray()113 inline bitarray(): bits()
114 {
115 clear();
116 }
get(size_t i)117 inline int get(size_t i) const
118 {
119 return bits[i];
120 }
set(size_t i,int v)121 inline void set(size_t i, int v)
122 {
123 bits[i] = v;
124 }
do_or(size_t i,int v)125 inline void do_or(size_t i, int v)
126 {
127 bits[i] |= v;
128 }
do_xor(size_t i,int v)129 inline void do_xor(size_t i, int v)
130 {
131 bits[i] ^= v;
132 }
clear()133 inline void clear()
134 {
135 memset(bits, 0, sizeof(bits));
136 }
getbyte(size_t p)137 inline unsigned char getbyte(size_t p) const
138 {
139 size_t bitpos_min = p * 8;
140 size_t bitpos_max = p * 8 + 7;
141 size_t word_min = bitpos_min / width;
142 size_t word_max = bitpos_max / width;
143 int shift = bitpos_min % width;
144 unsigned char out = get(word_min) >> shift;
145 for(size_t i = word_min+1; i <= word_max; ++i)
146 out |= get(i) << ((i - word_min) * width - shift);
147 return out;
148 }
nbytes()149 inline size_t nbytes() const
150 {
151 return (count * width + 7) >> 3;
152 }
tobytes(unsigned char * out)153 inline void tobytes(unsigned char *out) const
154 {
155 size_t s = nbytes();
156 for(size_t i = 0; i < s; ++i)
157 out[i] = getbyte(i);
158 }
159 };
160
161 #endif
162