blob: 8a3a1b0fd3b10f4e15d722200f748a521c23b48e [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.com603c8782011-04-01 08:50:06 +00009void printbits ( const void * blob, int len );
10void printhex32 ( const void * blob, int len );
11void printbytes ( const void * blob, int len );
12void printbytes2 ( const void * blob, int len );
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000013
tanjent@gmail.com603c8782011-04-01 08:50:06 +000014uint32_t popcount ( uint32_t v );
15uint32_t parity ( uint32_t v );
16
17uint32_t getbit ( const void * blob, int len, uint32_t bit );
18uint32_t getbit_wrap ( const void * blob, int len, uint32_t bit );
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000019
20void setbit ( void * blob, int len, uint32_t bit );
21void setbit ( void * blob, int len, uint32_t bit, uint32_t val );
22
23void clearbit ( void * blob, int len, uint32_t bit );
24
25void flipbit ( void * blob, int len, uint32_t bit );
26
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000027int countbits ( uint32_t v );
28int countbits ( std::vector<uint32_t> & v );
29
tanjent@gmail.com603c8782011-04-01 08:50:06 +000030int countbits ( const void * blob, int len );
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000031
32void invert ( std::vector<uint32_t> & v );
33
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000034//----------
35
36template< typename T >
37inline uint32_t getbit ( T & blob, uint32_t bit )
38{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000039 return getbit(&blob,sizeof(blob),bit);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000040}
41
42template<> inline uint32_t getbit ( uint32_t & blob, uint32_t bit ) { return (blob >> (bit & 31)) & 1; }
43template<> inline uint32_t getbit ( uint64_t & blob, uint32_t bit ) { return (blob >> (bit & 63)) & 1; }
44
45//----------
46
47template< typename T >
48inline void setbit ( T & blob, uint32_t bit )
49{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000050 return setbit(&blob,sizeof(blob),bit);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000051}
52
53template<> inline void setbit ( uint32_t & blob, uint32_t bit ) { blob |= uint32_t(1) << (bit & 31); }
54template<> inline void setbit ( uint64_t & blob, uint32_t bit ) { blob |= uint64_t(1) << (bit & 63); }
55
56//----------
57
58template< typename T >
59inline void flipbit ( T & blob, uint32_t bit )
60{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000061 flipbit(&blob,sizeof(blob),bit);
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000062}
63
64template<> inline void flipbit ( uint32_t & blob, uint32_t bit ) { bit &= 31; blob ^= (uint32_t(1) << bit); }
65template<> inline void flipbit ( uint64_t & blob, uint32_t bit ) { bit &= 63; blob ^= (uint64_t(1) << bit); }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000066
67//-----------------------------------------------------------------------------
68// Left and right shift of blobs. The shift(N) versions work on chunks of N
69// bits at a time (faster)
70
71void lshift1 ( void * blob, int len, int c );
72void lshift8 ( void * blob, int len, int c );
73void lshift32 ( void * blob, int len, int c );
74
75void rshift1 ( void * blob, int len, int c );
76void rshift8 ( void * blob, int len, int c );
77void rshift32 ( void * blob, int len, int c );
78
79inline void lshift ( void * blob, int len, int c )
80{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000081 if((len & 3) == 0)
82 {
83 lshift32(blob,len,c);
84 }
85 else
86 {
87 lshift8(blob,len,c);
88 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000089}
90
91inline void rshift ( void * blob, int len, int c )
92{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +000093 if((len & 3) == 0)
94 {
95 rshift32(blob,len,c);
96 }
97 else
98 {
99 rshift8(blob,len,c);
100 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000101}
102
103template < typename T >
104inline void lshift ( T & blob, int c )
105{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000106 if((sizeof(T) & 3) == 0)
107 {
108 lshift32(&blob,sizeof(T),c);
109 }
110 else
111 {
112 lshift8(&blob,sizeof(T),c);
113 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000114}
115
116template < typename T >
117inline void rshift ( T & blob, int c )
118{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000119 if((sizeof(T) & 3) == 0)
120 {
121 lshift32(&blob,sizeof(T),c);
122 }
123 else
124 {
125 lshift8(&blob,sizeof(T),c);
126 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000127}
128
129template<> inline void lshift ( uint32_t & blob, int c ) { blob <<= c; }
130template<> inline void lshift ( uint64_t & blob, int c ) { blob <<= c; }
131template<> inline void rshift ( uint32_t & blob, int c ) { blob >>= c; }
132template<> inline void rshift ( uint64_t & blob, int c ) { blob >>= c; }
133
134//-----------------------------------------------------------------------------
135// Left and right rotate of blobs. The rot(N) versions work on chunks of N
136// bits at a time (faster)
137
138void lrot1 ( void * blob, int len, int c );
139void lrot8 ( void * blob, int len, int c );
140void lrot32 ( void * blob, int len, int c );
141
142void rrot1 ( void * blob, int len, int c );
143void rrot8 ( void * blob, int len, int c );
144void rrot32 ( void * blob, int len, int c );
145
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000146inline void lrot ( void * blob, int len, int c )
147{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000148 if((len & 3) == 0)
149 {
150 return lrot32(blob,len,c);
151 }
152 else
153 {
154 return lrot8(blob,len,c);
155 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000156}
157
158inline void rrot ( void * blob, int len, int c )
159{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000160 if((len & 3) == 0)
161 {
162 return rrot32(blob,len,c);
163 }
164 else
165 {
166 return rrot8(blob,len,c);
167 }
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000168}
169
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000170template < typename T >
171inline void lrot ( T & blob, int c )
172{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000173 if((sizeof(T) & 3) == 0)
174 {
175 return lrot32(&blob,sizeof(T),c);
176 }
177 else
178 {
179 return lrot8(&blob,sizeof(T),c);
180 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000181}
182
183template < typename T >
184inline void rrot ( T & blob, int c )
185{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000186 if((sizeof(T) & 3) == 0)
187 {
188 return rrot32(&blob,sizeof(T),c);
189 }
190 else
191 {
192 return rrot8(&blob,sizeof(T),c);
193 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000194}
195
tanjent@gmail.com2aa29c32011-03-19 08:53:53 +0000196template<> inline void lrot ( uint32_t & blob, int c ) { blob = ROTL32(blob,c); }
197template<> inline void lrot ( uint64_t & blob, int c ) { blob = ROTL64(blob,c); }
198template<> inline void rrot ( uint32_t & blob, int c ) { blob = ROTR32(blob,c); }
199template<> inline void rrot ( uint64_t & blob, int c ) { blob = ROTR64(blob,c); }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000200
201//-----------------------------------------------------------------------------
202// Bit-windowing functions - select some N-bit subset of the input blob
203
204uint32_t window1 ( void * blob, int len, int start, int count );
205uint32_t window8 ( void * blob, int len, int start, int count );
206uint32_t window32 ( void * blob, int len, int start, int count );
207
208inline uint32_t window ( void * blob, int len, int start, int count )
209{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000210 if(len & 3)
211 {
212 return window8(blob,len,start,count);
213 }
214 else
215 {
216 return window32(blob,len,start,count);
217 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000218}
219
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000220template < typename T >
221inline uint32_t window ( T & blob, int start, int count )
222{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000223 if((sizeof(T) & 3) == 0)
224 {
225 return window32(&blob,sizeof(T),start,count);
226 }
227 else
228 {
229 return window8(&blob,sizeof(T),start,count);
230 }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000231}
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000232
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000233template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000234inline uint32_t window ( uint32_t & blob, int start, int count )
235{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000236 return ROTR32(blob,start) & ((1<<count)-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000237}
238
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000239template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000240inline uint32_t window ( uint64_t & blob, int start, int count )
241{
tanjent@gmail.com6ffe0102011-03-19 21:28:26 +0000242 return (uint32_t)ROTR64(blob,start) & ((1<<count)-1);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000243}
244
245//-----------------------------------------------------------------------------