summaryrefslogtreecommitdiff
path: root/src/bitstring.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2008-07-23 05:27:30 +0000
committerMike Buland <eichlan@xagasoft.com>2008-07-23 05:27:30 +0000
commit0047991313fd7c67b45c59d58e3fde0236bf3872 (patch)
treeb2b0abbc67f7c276a71583270e57c1da46293f4d /src/bitstring.cpp
parent57046f7fcbc6cd50105bd926b8f34732e302988a (diff)
downloadlibbu++-0047991313fd7c67b45c59d58e3fde0236bf3872.tar.gz
libbu++-0047991313fd7c67b45c59d58e3fde0236bf3872.tar.bz2
libbu++-0047991313fd7c67b45c59d58e3fde0236bf3872.tar.xz
libbu++-0047991313fd7c67b45c59d58e3fde0236bf3872.zip
Added BitString, it was used in a few projects. It needs a few functions to
be corrected, they were using standard library features, that shouldn't be hard to fix though.
Diffstat (limited to 'src/bitstring.cpp')
-rw-r--r--src/bitstring.cpp440
1 files changed, 440 insertions, 0 deletions
diff --git a/src/bitstring.cpp b/src/bitstring.cpp
new file mode 100644
index 0000000..8d99992
--- /dev/null
+++ b/src/bitstring.cpp
@@ -0,0 +1,440 @@
1#include "bitstring.h"
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5
6#ifdef _WIN32
7#define random() rand()
8#endif
9
10#define bitsToBytes( nBits ) (((nBits/8)+((nBits%8)?(1):(0))));
11
12Bu::BitString::BitString()
13{
14 caData = NULL;
15 cTopByteMask = 0;
16 nBits = nBytes = 0;
17}
18
19Bu::BitString::BitString( const Bu::BitString &xSrc )
20{
21 nBits = xSrc.nBits;
22 nBytes = xSrc.nBytes;
23 cTopByteMask = xSrc.cTopByteMask;
24 caData = new unsigned char[nBytes];
25 memcpy( caData, xSrc.caData, nBytes );
26
27 fixup();
28}
29
30Bu::BitString::BitString( long nNewBits, bool bFillRandomly )
31{
32 long j;
33 nBits = nNewBits;
34 nBytes = bitsToBytes( nNewBits );//(nNewBits/8)+((nNewBits%8)?(1):(0));
35 caData = new unsigned char[nBytes];
36
37 // This can either mean that there are a multiple of eight bits or zero, if there are zero you're an idiot
38 // (zero can't happen, because we would allocate an extra byte and never use it)
39 if( (nBits%8 == 0) )
40 {
41 cTopByteMask = 0xFF;
42 }
43 else
44 {
45 cTopByteMask = 0;
46 for( j = 0; j < (nBits%8); j++ )
47 {
48 cTopByteMask |= (1<<j);
49 }
50 }
51
52 if( bFillRandomly )
53 {
54 // rand() only returns a value up to RAND_MAX (0x7FFF on my system) so I'll just use the low order byte)
55 for( j = 0; j < nBytes; j++ )
56 {
57 caData[j] = (unsigned char)(random() & 0xFF);
58 }
59 }
60 else
61 {
62 clearString();
63 }
64
65 fixup();
66}
67
68Bu::BitString::~BitString()
69{
70 if( caData != NULL ) delete[] caData;
71}
72
73Bu::BitString &Bu::BitString::operator=( const Bu::BitString &xSrc )
74{
75 if( caData != NULL )
76 {
77 delete[] caData;
78 }
79 nBits = xSrc.nBits;
80 nBytes = xSrc.nBytes;
81 cTopByteMask = xSrc.cTopByteMask;
82 caData = new unsigned char[nBytes];
83 memcpy( caData, xSrc.caData, nBytes );
84
85 fixup();
86
87 return *this;
88}
89
90Bu::BitString Bu::BitString::operator~()
91{
92 Bu::BitString xRet( *this );
93
94 for( int j = 0; j < xRet.nBytes; j++ )
95 {
96 xRet.caData[j] = ~xRet.caData[j];
97 }
98
99 xRet.fixup();
100
101 return xRet;
102}
103
104Bu::BitString Bu::BitString::operator<<( const long nAmt )
105{
106 if( nAmt == 0 )
107 {
108 return (*this);
109 }
110 //int nByteShift = nAmt/8;
111
112 Bu::BitString xSub( getBitLength() );
113
114 long shft = (nAmt%8);
115 long base = (nAmt/8);
116 unsigned char lowmask=0;
117 for( long j = 0; j < 8-shft; j++ )
118 {
119 lowmask |= (1<<j);
120 }
121 for( long j = 0; j < xSub.nBytes; j++ )
122 {
123 xSub.caData[base+j] = ((caData[j]>>shft)&(lowmask)) | ((caData[j+1]<<(8-shft))&(~lowmask));
124 }
125 xSub.fixup();
126
127 return xSub;
128}
129
130Bu::BitString Bu::BitString::operator>>( const long nAmt )
131{
132 if( nAmt == 0 )
133 {
134 return (*this);
135 }
136 return (*this);
137}
138
139void Bu::BitString::shiftLeft( long nAmt )
140{
141 if( nAmt == 0 )
142 {
143 return;
144 }
145 else if( nAmt < 0 )
146 {
147 shiftRight( -nAmt );
148 return;
149 }
150
151 long nByteShift = nAmt/8;
152 long nBitShift = nAmt%8;
153
154 long j;
155 for( j = nBytes-1; j >= 0; j-- )
156 {
157 caData[j] = (((j-nByteShift)<0)?(0):((caData[j-nByteShift]<<nBitShift))) | (((j-nByteShift-1)<0)?(0):((caData[j-nByteShift-1]>>(8-nBitShift))));
158 }
159
160 fixup();
161}
162
163void Bu::BitString::shiftRight( long nAmt )
164{
165 if( nAmt == 0 )
166 {
167 return;
168 }
169 else if( nAmt < 0 )
170 {
171 shiftLeft( -nAmt );
172 return;
173 }
174
175 long nByteShift = nAmt/8;
176 long nBitShift = nAmt%8;
177
178 long j;
179 for( j = 0; j < nBytes; j++ )
180 {
181 caData[j] = (((j+nByteShift)>nBytes)?(0):((caData[j+nByteShift]>>nBitShift))) | (((j+nByteShift+1)>nBytes)?(0):((caData[j+nByteShift+1]<<(8-nBitShift))));
182 }
183
184 fixup();
185}
186/*
187long Bu::BitString::bitsToBytes( long nBits )
188{
189 return (nBits/8)+((nBits%8)?(1):(0));
190}
191*/
192void Bu::BitString::fixup()
193{
194 if( caData != NULL )
195 {
196 caData[nBytes-1] &= cTopByteMask;
197 }
198}
199
200void Bu::BitString::setBit( long nBit, bool bBitState )
201{
202 if( bBitState )
203 {
204 caData[nBit/8] |= (1<<(nBit%8));
205 }
206 else
207 {
208 caData[nBit/8] &= ~(1<<(nBit%8));
209 }
210}
211
212void Bu::BitString::flipBit( long nBit )
213{
214 caData[nBit/8] ^= (1<<(nBit%8));
215}
216
217bool Bu::BitString::getBit( long nBit )
218{
219 if( nBit >= nBits || nBit < 0 ) return false;
220 if( (caData[nBit/8] & (1<<(nBit%8))) == 0 )
221 {
222 return false;
223 }
224 return true;
225}
226
227long Bu::BitString::getBitLength()
228{
229 return nBits;
230}
231
232class Bu::BitString Bu::BitString::getSubString( long nLower, long nUpper )
233{
234 if( nUpper == 0 || nUpper < nLower ) nUpper = nBits;
235
236 Bu::BitString xSub( nUpper-nLower+1 );
237
238 long shft = (nLower%8);
239 long base = (nLower/8);
240 unsigned char lowmask=0;
241 for( long j = 0; j < 8-shft; j++ )
242 {
243 lowmask |= (1<<j);
244 }
245 for( long j = 0; j < xSub.nBytes; j++ )
246 {
247 xSub.caData[j] = ((caData[base+j]>>shft)&(lowmask)) | ((caData[base+j+1]<<(8-shft))&(~lowmask));
248 }
249 xSub.fixup();
250
251 return xSub;
252}
253
254long Bu::BitString::toLong( long nStart, long nSize )
255{
256 if( nSize < 1 ) nSize = 1;
257 if( nSize > 32 ) nSize = 32;
258 if( nStart < 0 ) return 0;
259 if( nStart+nSize > getBitLength() ) return 0;
260
261 Bu::BitString tmpo;
262 tmpo = getSubString( nStart, nStart+nSize-1 );
263 long x = *((long *)tmpo.caData);
264
265 return x;
266}
267/*
268std::string Bu::BitString::toString( bool bAddSpacers )
269{
270 long nSz = nBits;
271 if( bAddSpacers )
272 {
273 nSz += (nBits/8);
274 if( nBits%8 == 0 ) nSz--;
275 }
276 std::string xStr;
277
278 int bw=0;
279 int of=0;
280 for( int j = nBits-1; j >= 0; j-- )
281 {
282 if( getBit( j ) )
283 {
284 xStr += '1';
285 }
286 else
287 {
288 xStr += '0';
289 }
290
291 if( bAddSpacers )
292 {
293 bw++;
294 if( bw >= 8 && j < nBits-1 )
295 {
296 bw = 0;
297 of++;
298 xStr += ' ';
299 }
300 }
301 }
302
303 return xStr;
304}
305*/
306void Bu::BitString::clearString()
307{
308 if( caData != NULL )
309 {
310 memset( caData, 0, nBytes );
311 }
312}
313
314bool Bu::BitString::setBitLength( long nLength, bool bClear )
315{
316 if( nBits != nLength )
317 {
318 if( bClear || caData == NULL )
319 {
320 //long j;
321 nBits = nLength;
322 nBytes = bitsToBytes( nLength );//(nNewBits/8)+((nNewBits%8)?(1):(0));
323 if( caData != NULL ) delete[] caData;
324 caData = new unsigned char[nBytes];
325 memset( caData, 0, nBytes );
326 }
327 else
328 {
329 //long j;
330 nBits = nLength;
331 long nNewBytes = bitsToBytes( nLength );//(nNewBits/8)+((nNewBits%8)?(1):(0));
332 unsigned char *tmp = caData;
333 caData = new unsigned char[nBytes];
334 if( nNewBytes < nBytes )
335 {
336 memcpy( caData, tmp, nNewBytes );
337 }
338 else
339 {
340 memcpy( caData, tmp, nBytes );
341 }
342 delete[] tmp;
343 nBytes = nNewBytes;
344 }
345
346 // This can either mean that there are a multiple of eight bits or zero, if there are zero you're an idiot
347 // (zero can't happen, because we would allocate an extra byte and never use it)
348 if( (nBits%8 == 0) )
349 {
350 cTopByteMask = 0xFF;
351 }
352 else
353 {
354 cTopByteMask = 0;
355 for( long j = 0; j < (nBits%8); j++ )
356 {
357 cTopByteMask |= (1<<j);
358 }
359 }
360 }
361 else if( bClear )
362 {
363 clearString();
364 }
365
366 return true;
367}
368
369void Bu::BitString::randomize()
370{
371 if( caData != NULL )
372 {
373 for( int j = 0; j < nBytes; j++ )
374 {
375 caData[j] = (unsigned char)(random() & 0xFF);
376 }
377 fixup();
378 }
379}
380
381void Bu::BitString::invert()
382{
383 if( caData != NULL )
384 {
385 for( long j = 0; j < nBytes; j++ )
386 {
387 caData[j] = ~caData[j];
388 }
389 fixup();
390 }
391}
392
393long Bu::BitString::getHighestOrderBitPos()
394{
395 for( long j = nBits-1; j >= 0; j-- )
396 {
397 if( getBit( j ) )
398 {
399 return j;
400 }
401 }
402
403 return -1;
404}
405/*
406bool Bu::BitString::writeToFile( FILE *fh )
407{
408 fwrite( &nBits, sizeof(long), 1, fh );
409 fwrite( caData, sizeof(char), nBytes, fh );
410
411 return true;
412}
413
414bool Bu::BitString::readFromFile( FILE *fh )
415{
416 fread( &nBits, sizeof(long), 1, fh );
417
418 nBytes = bitsToBytes( nBits );
419 if( caData ) delete[] caData;
420 caData = new unsigned char[nBytes];
421
422 fread( caData, sizeof(char), nBytes, fh );
423
424 if( (nBits%8 == 0) )
425 {
426 cTopByteMask = 0xFF;
427 }
428 else
429 {
430 cTopByteMask = 0;
431 for( int j = 0; j < (nBits%8); j++ )
432 {
433 cTopByteMask |= (1<<j);
434 }
435 }
436
437 fixup();
438
439 return true;
440}*/