blob: 76797c8ef61d1b9f30f2fe1a4144ff2654bc518f [file] [log] [blame]
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00001#pragma once
2
3#include "pstdint.h"
4
5#include <stdlib.h> // for _rotl, _rotr, etc.
tanjent@gmail.comf67ce942011-03-14 09:11:18 +00006#include <vector>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +00007
8//-----------------------------------------------------------------------------
9
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000010void printbits ( void * blob, int len );
11void printhex32 ( void * blob, int len );
tanjent@gmail.combabb5532011-02-28 06:03:12 +000012void printbytes ( void * blob, int len );
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000013
14uint32_t getbit ( void * blob, int len, uint32_t bit );
15uint32_t getbit_wrap ( void * blob, int len, uint32_t bit );
16
17void setbit ( void * blob, int len, uint32_t bit );
18void setbit ( void * blob, int len, uint32_t bit, uint32_t val );
19
20void clearbit ( void * blob, int len, uint32_t bit );
21
22void flipbit ( void * blob, int len, uint32_t bit );
23
tanjent@gmail.comf67ce942011-03-14 09:11:18 +000024int countbits ( uint32_t v );
25int countbits ( std::vector<uint32_t> & v );
26
27int countbits ( void * blob, int len );
28
29void invert ( std::vector<uint32_t> & v );
30
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000031//----------
32
33template< typename T >
34inline uint32_t getbit ( T & blob, uint32_t bit )
35{
36 return getbit(&blob,sizeof(blob),bit);
37}
38
39template<> inline uint32_t getbit ( uint32_t & blob, uint32_t bit ) { return (blob >> (bit & 31)) & 1; }
40template<> inline uint32_t getbit ( uint64_t & blob, uint32_t bit ) { return (blob >> (bit & 63)) & 1; }
41
42//----------
43
44template< typename T >
45inline void setbit ( T & blob, uint32_t bit )
46{
47 return setbit(&blob,sizeof(blob),bit);
48}
49
50template<> inline void setbit ( uint32_t & blob, uint32_t bit ) { blob |= uint32_t(1) << (bit & 31); }
51template<> inline void setbit ( uint64_t & blob, uint32_t bit ) { blob |= uint64_t(1) << (bit & 63); }
52
53//----------
54
55template< typename T >
56inline void flipbit ( T & blob, uint32_t bit )
57{
58 flipbit(&blob,sizeof(blob),bit);
59}
60
61template<> inline void flipbit ( uint32_t & blob, uint32_t bit ) { bit &= 31; blob ^= (uint32_t(1) << bit); }
62template<> inline void flipbit ( uint64_t & blob, uint32_t bit ) { bit &= 63; blob ^= (uint64_t(1) << bit); }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000063
64//-----------------------------------------------------------------------------
65// Left and right shift of blobs. The shift(N) versions work on chunks of N
66// bits at a time (faster)
67
68void lshift1 ( void * blob, int len, int c );
69void lshift8 ( void * blob, int len, int c );
70void lshift32 ( void * blob, int len, int c );
71
72void rshift1 ( void * blob, int len, int c );
73void rshift8 ( void * blob, int len, int c );
74void rshift32 ( void * blob, int len, int c );
75
76inline void lshift ( void * blob, int len, int c )
77{
78 if((len & 3) == 0)
79 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000080 lshift32(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000081 }
82 else
83 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000084 lshift8(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000085 }
86}
87
88inline void rshift ( void * blob, int len, int c )
89{
90 if((len & 3) == 0)
91 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000092 rshift32(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000093 }
94 else
95 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000096 rshift8(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000097 }
98}
99
100template < typename T >
101inline void lshift ( T & blob, int c )
102{
103 if((sizeof(T) & 3) == 0)
104 {
105 lshift32(&blob,sizeof(T),c);
106 }
107 else
108 {
109 lshift8(&blob,sizeof(T),c);
110 }
111}
112
113template < typename T >
114inline void rshift ( T & blob, int c )
115{
116 if((sizeof(T) & 3) == 0)
117 {
118 lshift32(&blob,sizeof(T),c);
119 }
120 else
121 {
122 lshift8(&blob,sizeof(T),c);
123 }
124}
125
126template<> inline void lshift ( uint32_t & blob, int c ) { blob <<= c; }
127template<> inline void lshift ( uint64_t & blob, int c ) { blob <<= c; }
128template<> inline void rshift ( uint32_t & blob, int c ) { blob >>= c; }
129template<> inline void rshift ( uint64_t & blob, int c ) { blob >>= c; }
130
131//-----------------------------------------------------------------------------
132// Left and right rotate of blobs. The rot(N) versions work on chunks of N
133// bits at a time (faster)
134
135void lrot1 ( void * blob, int len, int c );
136void lrot8 ( void * blob, int len, int c );
137void lrot32 ( void * blob, int len, int c );
138
139void rrot1 ( void * blob, int len, int c );
140void rrot8 ( void * blob, int len, int c );
141void rrot32 ( void * blob, int len, int c );
142
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000143inline void lrot ( void * blob, int len, int c )
144{
145 if((len & 3) == 0)
146 {
147 return lrot32(blob,len,c);
148 }
149 else
150 {
151 return lrot8(blob,len,c);
152 }
153}
154
155inline void rrot ( void * blob, int len, int c )
156{
157 if((len & 3) == 0)
158 {
159 return rrot32(blob,len,c);
160 }
161 else
162 {
163 return rrot8(blob,len,c);
164 }
165}
166
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000167template < typename T >
168inline void lrot ( T & blob, int c )
169{
170 if((sizeof(T) & 3) == 0)
171 {
172 return lrot32(&blob,sizeof(T),c);
173 }
174 else
175 {
176 return lrot8(&blob,sizeof(T),c);
177 }
178}
179
180template < typename T >
181inline void rrot ( T & blob, int c )
182{
183 if((sizeof(T) & 3) == 0)
184 {
185 return rrot32(&blob,sizeof(T),c);
186 }
187 else
188 {
189 return rrot8(&blob,sizeof(T),c);
190 }
191}
192
193template<> inline void lrot ( uint32_t & blob, int c ) { blob = _rotl(blob,c); }
194template<> inline void lrot ( uint64_t & blob, int c ) { blob = _rotl64(blob,c); }
195template<> inline void rrot ( uint32_t & blob, int c ) { blob = _rotr(blob,c); }
196template<> inline void rrot ( uint64_t & blob, int c ) { blob = _rotr64(blob,c); }
197
198//-----------------------------------------------------------------------------
199// Bit-windowing functions - select some N-bit subset of the input blob
200
201uint32_t window1 ( void * blob, int len, int start, int count );
202uint32_t window8 ( void * blob, int len, int start, int count );
203uint32_t window32 ( void * blob, int len, int start, int count );
204
205inline uint32_t window ( void * blob, int len, int start, int count )
206{
207 if(len & 3)
208 {
209 return window8(blob,len,start,count);
210 }
211 else
212 {
213 return window32(blob,len,start,count);
214 }
215}
216
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000217template < typename T >
218inline uint32_t window ( T & blob, int start, int count )
219{
220 if((sizeof(T) & 3) == 0)
221 {
222 return window32(&blob,sizeof(T),start,count);
223 }
224 else
225 {
226 return window8(&blob,sizeof(T),start,count);
227 }
228}
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000229
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000230template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000231inline uint32_t window ( uint32_t & blob, int start, int count )
232{
233 return _rotr(blob,start) & ((1<<count)-1);
234}
235
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000236template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000237inline uint32_t window ( uint64_t & blob, int start, int count )
238{
239 return (uint32_t)_rotr64(blob,start) & ((1<<count)-1);
240}
241
242//-----------------------------------------------------------------------------