blob: ac91c36eb5833966b535274b0cdb833234ba6c33 [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#pragma once
2
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +00003#include "Platform.h"
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00004
tanjent@gmail.comf67ce942011-03-14 09:11:18 +00005#include <vector>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00006
7//-----------------------------------------------------------------------------
8
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00009void printbits ( void * blob, int len );
10void printhex32 ( void * blob, int len );
tanjent@gmail.combabb5532011-02-28 06:03:12 +000011void printbytes ( void * blob, int len );
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000012
13uint32_t getbit ( void * blob, int len, uint32_t bit );
14uint32_t getbit_wrap ( void * blob, int len, uint32_t bit );
15
16void setbit ( void * blob, int len, uint32_t bit );
17void setbit ( void * blob, int len, uint32_t bit, uint32_t val );
18
19void clearbit ( void * blob, int len, uint32_t bit );
20
21void flipbit ( void * blob, int len, uint32_t bit );
22
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000023int countbits ( uint32_t v );
24int countbits ( std::vector<uint32_t> & v );
25
26int countbits ( void * blob, int len );
27
28void invert ( std::vector<uint32_t> & v );
29
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000030//----------
31
32template< typename T >
33inline uint32_t getbit ( T & blob, uint32_t bit )
34{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000035 return getbit(&blob,sizeof(blob),bit);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000036}
37
38template<> inline uint32_t getbit ( uint32_t & blob, uint32_t bit ) { return (blob >> (bit & 31)) & 1; }
39template<> inline uint32_t getbit ( uint64_t & blob, uint32_t bit ) { return (blob >> (bit & 63)) & 1; }
40
41//----------
42
43template< typename T >
44inline void setbit ( T & blob, uint32_t bit )
45{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000046 return setbit(&blob,sizeof(blob),bit);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000047}
48
49template<> inline void setbit ( uint32_t & blob, uint32_t bit ) { blob |= uint32_t(1) << (bit & 31); }
50template<> inline void setbit ( uint64_t & blob, uint32_t bit ) { blob |= uint64_t(1) << (bit & 63); }
51
52//----------
53
54template< typename T >
55inline void flipbit ( T & blob, uint32_t bit )
56{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000057 flipbit(&blob,sizeof(blob),bit);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000058}
59
60template<> inline void flipbit ( uint32_t & blob, uint32_t bit ) { bit &= 31; blob ^= (uint32_t(1) << bit); }
61template<> inline void flipbit ( uint64_t & blob, uint32_t bit ) { bit &= 63; blob ^= (uint64_t(1) << bit); }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000062
63//-----------------------------------------------------------------------------
64// Left and right shift of blobs. The shift(N) versions work on chunks of N
65// bits at a time (faster)
66
67void lshift1 ( void * blob, int len, int c );
68void lshift8 ( void * blob, int len, int c );
69void lshift32 ( void * blob, int len, int c );
70
71void rshift1 ( void * blob, int len, int c );
72void rshift8 ( void * blob, int len, int c );
73void rshift32 ( void * blob, int len, int c );
74
75inline void lshift ( void * blob, int len, int c )
76{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000077 if((len & 3) == 0)
78 {
79 lshift32(blob,len,c);
80 }
81 else
82 {
83 lshift8(blob,len,c);
84 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000085}
86
87inline void rshift ( void * blob, int len, int c )
88{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000089 if((len & 3) == 0)
90 {
91 rshift32(blob,len,c);
92 }
93 else
94 {
95 rshift8(blob,len,c);
96 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000097}
98
99template < typename T >
100inline void lshift ( T & blob, int c )
101{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000102 if((sizeof(T) & 3) == 0)
103 {
104 lshift32(&blob,sizeof(T),c);
105 }
106 else
107 {
108 lshift8(&blob,sizeof(T),c);
109 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000110}
111
112template < typename T >
113inline void rshift ( T & blob, int c )
114{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000115 if((sizeof(T) & 3) == 0)
116 {
117 lshift32(&blob,sizeof(T),c);
118 }
119 else
120 {
121 lshift8(&blob,sizeof(T),c);
122 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000123}
124
125template<> inline void lshift ( uint32_t & blob, int c ) { blob <<= c; }
126template<> inline void lshift ( uint64_t & blob, int c ) { blob <<= c; }
127template<> inline void rshift ( uint32_t & blob, int c ) { blob >>= c; }
128template<> inline void rshift ( uint64_t & blob, int c ) { blob >>= c; }
129
130//-----------------------------------------------------------------------------
131// Left and right rotate of blobs. The rot(N) versions work on chunks of N
132// bits at a time (faster)
133
134void lrot1 ( void * blob, int len, int c );
135void lrot8 ( void * blob, int len, int c );
136void lrot32 ( void * blob, int len, int c );
137
138void rrot1 ( void * blob, int len, int c );
139void rrot8 ( void * blob, int len, int c );
140void rrot32 ( void * blob, int len, int c );
141
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000142inline void lrot ( void * blob, int len, int c )
143{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000144 if((len & 3) == 0)
145 {
146 return lrot32(blob,len,c);
147 }
148 else
149 {
150 return lrot8(blob,len,c);
151 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000152}
153
154inline void rrot ( void * blob, int len, int c )
155{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000156 if((len & 3) == 0)
157 {
158 return rrot32(blob,len,c);
159 }
160 else
161 {
162 return rrot8(blob,len,c);
163 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000164}
165
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000166template < typename T >
167inline void lrot ( T & blob, int c )
168{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000169 if((sizeof(T) & 3) == 0)
170 {
171 return lrot32(&blob,sizeof(T),c);
172 }
173 else
174 {
175 return lrot8(&blob,sizeof(T),c);
176 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000177}
178
179template < typename T >
180inline void rrot ( T & blob, int c )
181{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000182 if((sizeof(T) & 3) == 0)
183 {
184 return rrot32(&blob,sizeof(T),c);
185 }
186 else
187 {
188 return rrot8(&blob,sizeof(T),c);
189 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000190}
191
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000192template<> inline void lrot ( uint32_t & blob, int c ) { blob = ROTL32(blob,c); }
193template<> inline void lrot ( uint64_t & blob, int c ) { blob = ROTL64(blob,c); }
194template<> inline void rrot ( uint32_t & blob, int c ) { blob = ROTR32(blob,c); }
195template<> inline void rrot ( uint64_t & blob, int c ) { blob = ROTR64(blob,c); }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000196
197//-----------------------------------------------------------------------------
198// Bit-windowing functions - select some N-bit subset of the input blob
199
200uint32_t window1 ( void * blob, int len, int start, int count );
201uint32_t window8 ( void * blob, int len, int start, int count );
202uint32_t window32 ( void * blob, int len, int start, int count );
203
204inline uint32_t window ( void * blob, int len, int start, int count )
205{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000206 if(len & 3)
207 {
208 return window8(blob,len,start,count);
209 }
210 else
211 {
212 return window32(blob,len,start,count);
213 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000214}
215
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000216template < typename T >
217inline uint32_t window ( T & blob, int start, int count )
218{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000219 if((sizeof(T) & 3) == 0)
220 {
221 return window32(&blob,sizeof(T),start,count);
222 }
223 else
224 {
225 return window8(&blob,sizeof(T),start,count);
226 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000227}
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000228
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000229template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000230inline uint32_t window ( uint32_t & blob, int start, int count )
231{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000232 return ROTR32(blob,start) & ((1<<count)-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000233}
234
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000235template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000236inline uint32_t window ( uint64_t & blob, int start, int count )
237{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000238 return (uint32_t)ROTR64(blob,start) & ((1<<count)-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000239}
240
241//-----------------------------------------------------------------------------