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