blob: 1a475d130a4978bfb7869b8d5def4910a3b1a2f3 [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.
6
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.comad4b3632010-11-05 01:20:58 +000023//----------
24
25template< typename T >
26inline uint32_t getbit ( T & blob, uint32_t bit )
27{
28 return getbit(&blob,sizeof(blob),bit);
29}
30
31template<> inline uint32_t getbit ( uint32_t & blob, uint32_t bit ) { return (blob >> (bit & 31)) & 1; }
32template<> inline uint32_t getbit ( uint64_t & blob, uint32_t bit ) { return (blob >> (bit & 63)) & 1; }
33
34//----------
35
36template< typename T >
37inline void setbit ( T & blob, uint32_t bit )
38{
39 return setbit(&blob,sizeof(blob),bit);
40}
41
42template<> inline void setbit ( uint32_t & blob, uint32_t bit ) { blob |= uint32_t(1) << (bit & 31); }
43template<> inline void setbit ( uint64_t & blob, uint32_t bit ) { blob |= uint64_t(1) << (bit & 63); }
44
45//----------
46
47template< typename T >
48inline void flipbit ( T & blob, uint32_t bit )
49{
50 flipbit(&blob,sizeof(blob),bit);
51}
52
53template<> inline void flipbit ( uint32_t & blob, uint32_t bit ) { bit &= 31; blob ^= (uint32_t(1) << bit); }
54template<> inline void flipbit ( uint64_t & blob, uint32_t bit ) { bit &= 63; blob ^= (uint64_t(1) << bit); }
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000055
56//-----------------------------------------------------------------------------
57// Left and right shift of blobs. The shift(N) versions work on chunks of N
58// bits at a time (faster)
59
60void lshift1 ( void * blob, int len, int c );
61void lshift8 ( void * blob, int len, int c );
62void lshift32 ( void * blob, int len, int c );
63
64void rshift1 ( void * blob, int len, int c );
65void rshift8 ( void * blob, int len, int c );
66void rshift32 ( void * blob, int len, int c );
67
68inline void lshift ( void * blob, int len, int c )
69{
70 if((len & 3) == 0)
71 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000072 lshift32(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000073 }
74 else
75 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000076 lshift8(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000077 }
78}
79
80inline void rshift ( void * blob, int len, int c )
81{
82 if((len & 3) == 0)
83 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000084 rshift32(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000085 }
86 else
87 {
tanjent@gmail.comad4b3632010-11-05 01:20:58 +000088 rshift8(blob,len,c);
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +000089 }
90}
91
92template < typename T >
93inline void lshift ( T & blob, int c )
94{
95 if((sizeof(T) & 3) == 0)
96 {
97 lshift32(&blob,sizeof(T),c);
98 }
99 else
100 {
101 lshift8(&blob,sizeof(T),c);
102 }
103}
104
105template < typename T >
106inline void rshift ( T & blob, int c )
107{
108 if((sizeof(T) & 3) == 0)
109 {
110 lshift32(&blob,sizeof(T),c);
111 }
112 else
113 {
114 lshift8(&blob,sizeof(T),c);
115 }
116}
117
118template<> inline void lshift ( uint32_t & blob, int c ) { blob <<= c; }
119template<> inline void lshift ( uint64_t & blob, int c ) { blob <<= c; }
120template<> inline void rshift ( uint32_t & blob, int c ) { blob >>= c; }
121template<> inline void rshift ( uint64_t & blob, int c ) { blob >>= c; }
122
123//-----------------------------------------------------------------------------
124// Left and right rotate of blobs. The rot(N) versions work on chunks of N
125// bits at a time (faster)
126
127void lrot1 ( void * blob, int len, int c );
128void lrot8 ( void * blob, int len, int c );
129void lrot32 ( void * blob, int len, int c );
130
131void rrot1 ( void * blob, int len, int c );
132void rrot8 ( void * blob, int len, int c );
133void rrot32 ( void * blob, int len, int c );
134
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000135inline void lrot ( void * blob, int len, int c )
136{
137 if((len & 3) == 0)
138 {
139 return lrot32(blob,len,c);
140 }
141 else
142 {
143 return lrot8(blob,len,c);
144 }
145}
146
147inline void rrot ( void * blob, int len, int c )
148{
149 if((len & 3) == 0)
150 {
151 return rrot32(blob,len,c);
152 }
153 else
154 {
155 return rrot8(blob,len,c);
156 }
157}
158
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000159template < typename T >
160inline void lrot ( T & blob, int c )
161{
162 if((sizeof(T) & 3) == 0)
163 {
164 return lrot32(&blob,sizeof(T),c);
165 }
166 else
167 {
168 return lrot8(&blob,sizeof(T),c);
169 }
170}
171
172template < typename T >
173inline void rrot ( T & blob, int c )
174{
175 if((sizeof(T) & 3) == 0)
176 {
177 return rrot32(&blob,sizeof(T),c);
178 }
179 else
180 {
181 return rrot8(&blob,sizeof(T),c);
182 }
183}
184
185template<> inline void lrot ( uint32_t & blob, int c ) { blob = _rotl(blob,c); }
186template<> inline void lrot ( uint64_t & blob, int c ) { blob = _rotl64(blob,c); }
187template<> inline void rrot ( uint32_t & blob, int c ) { blob = _rotr(blob,c); }
188template<> inline void rrot ( uint64_t & blob, int c ) { blob = _rotr64(blob,c); }
189
190//-----------------------------------------------------------------------------
191// Bit-windowing functions - select some N-bit subset of the input blob
192
193uint32_t window1 ( void * blob, int len, int start, int count );
194uint32_t window8 ( void * blob, int len, int start, int count );
195uint32_t window32 ( void * blob, int len, int start, int count );
196
197inline uint32_t window ( void * blob, int len, int start, int count )
198{
199 if(len & 3)
200 {
201 return window8(blob,len,start,count);
202 }
203 else
204 {
205 return window32(blob,len,start,count);
206 }
207}
208
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000209template < typename T >
210inline uint32_t window ( T & blob, int start, int count )
211{
212 if((sizeof(T) & 3) == 0)
213 {
214 return window32(&blob,sizeof(T),start,count);
215 }
216 else
217 {
218 return window8(&blob,sizeof(T),start,count);
219 }
220}
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000221
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000222template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000223inline uint32_t window ( uint32_t & blob, int start, int count )
224{
225 return _rotr(blob,start) & ((1<<count)-1);
226}
227
tanjent@gmail.comad4b3632010-11-05 01:20:58 +0000228template<>
tanjent@gmail.com7e5c3632010-11-02 00:50:04 +0000229inline uint32_t window ( uint64_t & blob, int start, int count )
230{
231 return (uint32_t)_rotr64(blob,start) & ((1<<count)-1);
232}
233
234//-----------------------------------------------------------------------------