summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2008-09-15 20:03:56 +0000
committerMike Buland <eichlan@xagasoft.com>2008-09-15 20:03:56 +0000
commit597a1487c716b799428f4b4a4903e65df4c93ba9 (patch)
treec743b0d4dfc3bacbffc196589543ec4e9abf1aaf /src
parent3c6cb7f2347aed974543f9082a0ccd297577db41 (diff)
downloadlibbu++-597a1487c716b799428f4b4a4903e65df4c93ba9.tar.gz
libbu++-597a1487c716b799428f4b4a4903e65df4c93ba9.tar.bz2
libbu++-597a1487c716b799428f4b4a4903e65df4c93ba9.tar.xz
libbu++-597a1487c716b799428f4b4a4903e65df4c93ba9.zip
Whoa! Loads of NIDS work. It actually compiles, runs, and I'm optimizing the
hell out of it. Good times, everyone. This is a major chunk for congo, and the new optimizations should be good.
Diffstat (limited to 'src')
-rw-r--r--src/archive.cpp2
-rw-r--r--src/bitstring.cpp305
-rw-r--r--src/bitstring.h197
-rw-r--r--src/file.h1
-rw-r--r--src/fstring.h11
-rw-r--r--src/hash.h50
-rw-r--r--src/nids.cpp93
-rw-r--r--src/nids.h31
-rw-r--r--src/nidsstream.cpp88
-rw-r--r--src/nidsstream.h32
-rw-r--r--src/tests/hash.cpp2
-rw-r--r--src/tests/nids.cpp19
-rw-r--r--src/unit/hash.cpp22
-rw-r--r--src/util.h9
14 files changed, 610 insertions, 252 deletions
diff --git a/src/archive.cpp b/src/archive.cpp
index 90211fe..c1c89cc 100644
--- a/src/archive.cpp
+++ b/src/archive.cpp
@@ -512,7 +512,7 @@ void Bu::Archive::assocPtrID( void **ptr, uint32_t id )
512 if( !hPtrDest.has( id ) ) 512 if( !hPtrDest.has( id ) )
513 hPtrDest.insert( id, List<void **>() ); 513 hPtrDest.insert( id, List<void **>() );
514 514
515 hPtrDest[id].value().append( ptr ); 515 hPtrDest[id].getValue().append( ptr );
516} 516}
517 517
518void Bu::Archive::readID( const void *ptr, uint32_t id ) 518void Bu::Archive::readID( const void *ptr, uint32_t id )
diff --git a/src/bitstring.cpp b/src/bitstring.cpp
index 8d99992..85f89e2 100644
--- a/src/bitstring.cpp
+++ b/src/bitstring.cpp
@@ -7,59 +7,47 @@
7#define random() rand() 7#define random() rand()
8#endif 8#endif
9 9
10#define bitsToBytes( nBits ) (((nBits/8)+((nBits%8)?(1):(0)))); 10#define bitsToBytes( iBits ) (((iBits/8)+((iBits%8)?(1):(0))));
11 11
12Bu::BitString::BitString() 12Bu::BitString::BitString()
13{ 13{
14 caData = NULL; 14 caData = NULL;
15 cTopByteMask = 0; 15 cTopByteMask = 0;
16 nBits = nBytes = 0; 16 iBits = iBytes = 0;
17} 17}
18 18
19Bu::BitString::BitString( const Bu::BitString &xSrc ) 19Bu::BitString::BitString( const Bu::BitString &xSrc )
20{ 20{
21 nBits = xSrc.nBits; 21 iBits = xSrc.iBits;
22 nBytes = xSrc.nBytes; 22 iBytes = xSrc.iBytes;
23 cTopByteMask = xSrc.cTopByteMask; 23 cTopByteMask = xSrc.cTopByteMask;
24 caData = new unsigned char[nBytes]; 24 caData = new unsigned char[iBytes];
25 memcpy( caData, xSrc.caData, nBytes ); 25 memcpy( caData, xSrc.caData, iBytes );
26 26
27 fixup(); 27 fixup();
28} 28}
29 29
30Bu::BitString::BitString( long nNewBits, bool bFillRandomly ) 30Bu::BitString::BitString( long iNewBits, bool bFillRandomly )
31{ 31{
32 long j; 32 long j;
33 nBits = nNewBits; 33 iBits = iNewBits;
34 nBytes = bitsToBytes( nNewBits );//(nNewBits/8)+((nNewBits%8)?(1):(0)); 34 iBytes = bitsToBytes( iNewBits );//(iNewBits/8)+((iNewBits%8)?(1):(0));
35 caData = new unsigned char[nBytes]; 35 caData = new unsigned char[iBytes];
36 36
37 // This can either mean that there are a multiple of eight bits or zero, if there are zero you're an idiot 37 setMask();
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 38
52 if( bFillRandomly ) 39 if( bFillRandomly )
53 { 40 {
54 // rand() only returns a value up to RAND_MAX (0x7FFF on my system) so I'll just use the low order byte) 41 // rand() only returns a value up to RAND_MAX (0x7FFF on my system) so
55 for( j = 0; j < nBytes; j++ ) 42 // I'll just use the low order byte)
43 for( j = 0; j < iBytes; j++ )
56 { 44 {
57 caData[j] = (unsigned char)(random() & 0xFF); 45 caData[j] = (unsigned char)(random() & 0xFF);
58 } 46 }
59 } 47 }
60 else 48 else
61 { 49 {
62 clearString(); 50 clear();
63 } 51 }
64 52
65 fixup(); 53 fixup();
@@ -76,11 +64,11 @@ Bu::BitString &Bu::BitString::operator=( const Bu::BitString &xSrc )
76 { 64 {
77 delete[] caData; 65 delete[] caData;
78 } 66 }
79 nBits = xSrc.nBits; 67 iBits = xSrc.iBits;
80 nBytes = xSrc.nBytes; 68 iBytes = xSrc.iBytes;
81 cTopByteMask = xSrc.cTopByteMask; 69 cTopByteMask = xSrc.cTopByteMask;
82 caData = new unsigned char[nBytes]; 70 caData = new unsigned char[iBytes];
83 memcpy( caData, xSrc.caData, nBytes ); 71 memcpy( caData, xSrc.caData, iBytes );
84 72
85 fixup(); 73 fixup();
86 74
@@ -91,7 +79,7 @@ Bu::BitString Bu::BitString::operator~()
91{ 79{
92 Bu::BitString xRet( *this ); 80 Bu::BitString xRet( *this );
93 81
94 for( int j = 0; j < xRet.nBytes; j++ ) 82 for( int j = 0; j < xRet.iBytes; j++ )
95 { 83 {
96 xRet.caData[j] = ~xRet.caData[j]; 84 xRet.caData[j] = ~xRet.caData[j];
97 } 85 }
@@ -101,24 +89,24 @@ Bu::BitString Bu::BitString::operator~()
101 return xRet; 89 return xRet;
102} 90}
103 91
104Bu::BitString Bu::BitString::operator<<( const long nAmt ) 92Bu::BitString Bu::BitString::operator<<( const long iAmt )
105{ 93{
106 if( nAmt == 0 ) 94 if( iAmt == 0 )
107 { 95 {
108 return (*this); 96 return (*this);
109 } 97 }
110 //int nByteShift = nAmt/8; 98 //int iByteShift = iAmt/8;
111 99
112 Bu::BitString xSub( getBitLength() ); 100 Bu::BitString xSub( getSize() );
113 101
114 long shft = (nAmt%8); 102 long shft = (iAmt%8);
115 long base = (nAmt/8); 103 long base = (iAmt/8);
116 unsigned char lowmask=0; 104 unsigned char lowmask=0;
117 for( long j = 0; j < 8-shft; j++ ) 105 for( long j = 0; j < 8-shft; j++ )
118 { 106 {
119 lowmask |= (1<<j); 107 lowmask |= (1<<j);
120 } 108 }
121 for( long j = 0; j < xSub.nBytes; j++ ) 109 for( long j = 0; j < xSub.iBytes; j++ )
122 { 110 {
123 xSub.caData[base+j] = ((caData[j]>>shft)&(lowmask)) | ((caData[j+1]<<(8-shft))&(~lowmask)); 111 xSub.caData[base+j] = ((caData[j]>>shft)&(lowmask)) | ((caData[j+1]<<(8-shft))&(~lowmask));
124 } 112 }
@@ -127,97 +115,97 @@ Bu::BitString Bu::BitString::operator<<( const long nAmt )
127 return xSub; 115 return xSub;
128} 116}
129 117
130Bu::BitString Bu::BitString::operator>>( const long nAmt ) 118Bu::BitString Bu::BitString::operator>>( const long iAmt )
131{ 119{
132 if( nAmt == 0 ) 120 if( iAmt == 0 )
133 { 121 {
134 return (*this); 122 return (*this);
135 } 123 }
136 return (*this); 124 return (*this);
137} 125}
138 126
139void Bu::BitString::shiftLeft( long nAmt ) 127void Bu::BitString::shiftLeft( long iAmt )
140{ 128{
141 if( nAmt == 0 ) 129 if( iAmt == 0 )
142 { 130 {
143 return; 131 return;
144 } 132 }
145 else if( nAmt < 0 ) 133 else if( iAmt < 0 )
146 { 134 {
147 shiftRight( -nAmt ); 135 shiftRight( -iAmt );
148 return; 136 return;
149 } 137 }
150 138
151 long nByteShift = nAmt/8; 139 long iByteShift = iAmt/8;
152 long nBitShift = nAmt%8; 140 long iBitShift = iAmt%8;
153 141
154 long j; 142 long j;
155 for( j = nBytes-1; j >= 0; j-- ) 143 for( j = iBytes-1; j >= 0; j-- )
156 { 144 {
157 caData[j] = (((j-nByteShift)<0)?(0):((caData[j-nByteShift]<<nBitShift))) | (((j-nByteShift-1)<0)?(0):((caData[j-nByteShift-1]>>(8-nBitShift)))); 145 caData[j] = (((j-iByteShift)<0)?(0):((caData[j-iByteShift]<<iBitShift))) | (((j-iByteShift-1)<0)?(0):((caData[j-iByteShift-1]>>(8-iBitShift))));
158 } 146 }
159 147
160 fixup(); 148 fixup();
161} 149}
162 150
163void Bu::BitString::shiftRight( long nAmt ) 151void Bu::BitString::shiftRight( long iAmt )
164{ 152{
165 if( nAmt == 0 ) 153 if( iAmt == 0 )
166 { 154 {
167 return; 155 return;
168 } 156 }
169 else if( nAmt < 0 ) 157 else if( iAmt < 0 )
170 { 158 {
171 shiftLeft( -nAmt ); 159 shiftLeft( -iAmt );
172 return; 160 return;
173 } 161 }
174 162
175 long nByteShift = nAmt/8; 163 long iByteShift = iAmt/8;
176 long nBitShift = nAmt%8; 164 long iBitShift = iAmt%8;
177 165
178 long j; 166 long j;
179 for( j = 0; j < nBytes; j++ ) 167 for( j = 0; j < iBytes; j++ )
180 { 168 {
181 caData[j] = (((j+nByteShift)>nBytes)?(0):((caData[j+nByteShift]>>nBitShift))) | (((j+nByteShift+1)>nBytes)?(0):((caData[j+nByteShift+1]<<(8-nBitShift)))); 169 caData[j] = (((j+iByteShift)>iBytes)?(0):((caData[j+iByteShift]>>iBitShift))) | (((j+iByteShift+1)>iBytes)?(0):((caData[j+iByteShift+1]<<(8-iBitShift))));
182 } 170 }
183 171
184 fixup(); 172 fixup();
185} 173}
186/* 174/*
187long Bu::BitString::bitsToBytes( long nBits ) 175long Bu::BitString::bitsToBytes( long iBits )
188{ 176{
189 return (nBits/8)+((nBits%8)?(1):(0)); 177 return (iBits/8)+((iBits%8)?(1):(0));
190} 178}
191*/ 179*/
192void Bu::BitString::fixup() 180void Bu::BitString::fixup()
193{ 181{
194 if( caData != NULL ) 182 if( caData != NULL )
195 { 183 {
196 caData[nBytes-1] &= cTopByteMask; 184 caData[iBytes-1] &= cTopByteMask;
197 } 185 }
198} 186}
199 187
200void Bu::BitString::setBit( long nBit, bool bBitState ) 188void Bu::BitString::setBit( long iBit, bool bBitState )
201{ 189{
202 if( bBitState ) 190 if( bBitState )
203 { 191 {
204 caData[nBit/8] |= (1<<(nBit%8)); 192 caData[iBit/8] |= (1<<(iBit%8));
205 } 193 }
206 else 194 else
207 { 195 {
208 caData[nBit/8] &= ~(1<<(nBit%8)); 196 caData[iBit/8] &= ~(1<<(iBit%8));
209 } 197 }
210} 198}
211 199
212void Bu::BitString::flipBit( long nBit ) 200void Bu::BitString::flipBit( long iBit )
213{ 201{
214 caData[nBit/8] ^= (1<<(nBit%8)); 202 caData[iBit/8] ^= (1<<(iBit%8));
215} 203}
216 204
217bool Bu::BitString::getBit( long nBit ) 205bool Bu::BitString::getBit( long iBit )
218{ 206{
219 if( nBit >= nBits || nBit < 0 ) return false; 207 if( iBit >= iBits || iBit < 0 ) return false;
220 if( (caData[nBit/8] & (1<<(nBit%8))) == 0 ) 208 if( (caData[iBit/8] & (1<<(iBit%8))) == 0 )
221 { 209 {
222 return false; 210 return false;
223 } 211 }
@@ -226,23 +214,28 @@ bool Bu::BitString::getBit( long nBit )
226 214
227long Bu::BitString::getBitLength() 215long Bu::BitString::getBitLength()
228{ 216{
229 return nBits; 217 return iBits;
218}
219
220long Bu::BitString::getSize()
221{
222 return iBits;
230} 223}
231 224
232class Bu::BitString Bu::BitString::getSubString( long nLower, long nUpper ) 225class Bu::BitString Bu::BitString::getSubString( long iLower, long iUpper )
233{ 226{
234 if( nUpper == 0 || nUpper < nLower ) nUpper = nBits; 227 if( iUpper == 0 || iUpper < iLower ) iUpper = iBits;
235 228
236 Bu::BitString xSub( nUpper-nLower+1 ); 229 Bu::BitString xSub( iUpper-iLower+1 );
237 230
238 long shft = (nLower%8); 231 long shft = (iLower%8);
239 long base = (nLower/8); 232 long base = (iLower/8);
240 unsigned char lowmask=0; 233 unsigned char lowmask=0;
241 for( long j = 0; j < 8-shft; j++ ) 234 for( long j = 0; j < 8-shft; j++ )
242 { 235 {
243 lowmask |= (1<<j); 236 lowmask |= (1<<j);
244 } 237 }
245 for( long j = 0; j < xSub.nBytes; j++ ) 238 for( long j = 0; j < xSub.iBytes; j++ )
246 { 239 {
247 xSub.caData[j] = ((caData[base+j]>>shft)&(lowmask)) | ((caData[base+j+1]<<(8-shft))&(~lowmask)); 240 xSub.caData[j] = ((caData[base+j]>>shft)&(lowmask)) | ((caData[base+j+1]<<(8-shft))&(~lowmask));
248 } 241 }
@@ -251,15 +244,15 @@ class Bu::BitString Bu::BitString::getSubString( long nLower, long nUpper )
251 return xSub; 244 return xSub;
252} 245}
253 246
254long Bu::BitString::toLong( long nStart, long nSize ) 247long Bu::BitString::toLong( long iStart, long iSize )
255{ 248{
256 if( nSize < 1 ) nSize = 1; 249 if( iSize < 1 ) iSize = 1;
257 if( nSize > 32 ) nSize = 32; 250 if( iSize > 32 ) iSize = 32;
258 if( nStart < 0 ) return 0; 251 if( iStart < 0 ) return 0;
259 if( nStart+nSize > getBitLength() ) return 0; 252 if( iStart+iSize > getSize() ) return 0;
260 253
261 Bu::BitString tmpo; 254 Bu::BitString tmpo;
262 tmpo = getSubString( nStart, nStart+nSize-1 ); 255 tmpo = getSubString( iStart, iStart+iSize-1 );
263 long x = *((long *)tmpo.caData); 256 long x = *((long *)tmpo.caData);
264 257
265 return x; 258 return x;
@@ -267,17 +260,17 @@ long Bu::BitString::toLong( long nStart, long nSize )
267/* 260/*
268std::string Bu::BitString::toString( bool bAddSpacers ) 261std::string Bu::BitString::toString( bool bAddSpacers )
269{ 262{
270 long nSz = nBits; 263 long iSz = iBits;
271 if( bAddSpacers ) 264 if( bAddSpacers )
272 { 265 {
273 nSz += (nBits/8); 266 iSz += (iBits/8);
274 if( nBits%8 == 0 ) nSz--; 267 if( iBits%8 == 0 ) iSz--;
275 } 268 }
276 std::string xStr; 269 std::string xStr;
277 270
278 int bw=0; 271 int bw=0;
279 int of=0; 272 int of=0;
280 for( int j = nBits-1; j >= 0; j-- ) 273 for( int j = iBits-1; j >= 0; j-- )
281 { 274 {
282 if( getBit( j ) ) 275 if( getBit( j ) )
283 { 276 {
@@ -291,7 +284,7 @@ std::string Bu::BitString::toString( bool bAddSpacers )
291 if( bAddSpacers ) 284 if( bAddSpacers )
292 { 285 {
293 bw++; 286 bw++;
294 if( bw >= 8 && j < nBits-1 ) 287 if( bw >= 8 && j < iBits-1 )
295 { 288 {
296 bw = 0; 289 bw = 0;
297 of++; 290 of++;
@@ -303,74 +296,111 @@ std::string Bu::BitString::toString( bool bAddSpacers )
303 return xStr; 296 return xStr;
304} 297}
305*/ 298*/
306void Bu::BitString::clearString() 299void Bu::BitString::clear()
307{ 300{
308 if( caData != NULL ) 301 if( caData != NULL )
309 { 302 {
310 memset( caData, 0, nBytes ); 303 memset( caData, 0, iBytes );
311 } 304 }
312} 305}
313 306
314bool Bu::BitString::setBitLength( long nLength, bool bClear ) 307bool Bu::BitString::setBitLength( long iLength, bool bClear )
315{ 308{
316 if( nBits != nLength ) 309 return setSize( iLength, bClear );
310}
311
312bool Bu::BitString::setSize( long iLength, bool bClear )
313{
314 // First, if there's nothing, then allocate an empty one.
315 if( caData == NULL )
317 { 316 {
318 if( bClear || caData == NULL ) 317 iBits = iLength;
318 iBytes = bitsToBytes( iLength );
319 caData = new unsigned char[iBytes];
320 memset( caData, 0, iBytes );
321 return true;
322 }
323
324 // If the new length is the same as the old, don't do anything, but do
325 // check to see if we should still clear the data.
326 if( iBits != iLength )
327 {
328 // Ok, we are changing the number if bits, but are we changing the
329 // number of bytes?
330 long iNewBytes = bitsToBytes( iLength );
331 if( iBytes == iNewBytes )
319 { 332 {
320 //long j; 333 // No? That makes life easier
321 nBits = nLength; 334 iBits = iLength;
322 nBytes = bitsToBytes( nLength );//(nNewBits/8)+((nNewBits%8)?(1):(0)); 335 setMask();
323 if( caData != NULL ) delete[] caData; 336 if( bClear )
324 caData = new unsigned char[nBytes]; 337 {
325 memset( caData, 0, nBytes ); 338 clear();
339 }
326 } 340 }
327 else 341 else
328 { 342 {
329 //long j; 343 // Ok, reallocate and copy...
330 nBits = nLength; 344 iBits = iLength;
331 long nNewBytes = bitsToBytes( nLength );//(nNewBits/8)+((nNewBits%8)?(1):(0)); 345 long iNewBytes = bitsToBytes( iLength );
332 unsigned char *tmp = caData; 346 if( bClear )
333 caData = new unsigned char[nBytes];
334 if( nNewBytes < nBytes )
335 { 347 {
336 memcpy( caData, tmp, nNewBytes ); 348 delete[] caData;
349 caData = new unsigned char[iNewBytes];
350 memset( caData, 0, iNewBytes );
337 } 351 }
338 else 352 else
339 { 353 {
340 memcpy( caData, tmp, nBytes ); 354 unsigned char *tmp = caData;
355 caData = new unsigned char[iBytes];
356 if( iNewBytes < iBytes )
357 {
358 memcpy( caData, tmp, iNewBytes );
359 }
360 else
361 {
362 memcpy( caData, tmp, iBytes );
363 }
364 delete[] tmp;
341 } 365 }
342 delete[] tmp; 366 iBytes = iNewBytes;
343 nBytes = nNewBytes; 367
368 setMask();
344 } 369 }
345 370
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 } 371 }
361 else if( bClear ) 372 else if( bClear )
362 { 373 {
363 clearString(); 374 clear();
364 } 375 }
365 376
366 return true; 377 return true;
367} 378}
368 379
380void Bu::BitString::setMask()
381{
382 // This can either mean that there are a multiple of eight bits or
383 // zero, if there are zero you're an idiot (zero can't happen, because
384 // we would allocate an extra byte and never use it)
385 if( (iBits%8 == 0) )
386 {
387 cTopByteMask = 0xFF;
388 }
389 else
390 {
391 cTopByteMask = 0;
392 for( long j = 0; j < (iBits%8); j++ )
393 {
394 cTopByteMask |= (1<<j);
395 }
396 }
397}
398
369void Bu::BitString::randomize() 399void Bu::BitString::randomize()
370{ 400{
371 if( caData != NULL ) 401 if( caData != NULL )
372 { 402 {
373 for( int j = 0; j < nBytes; j++ ) 403 for( int j = 0; j < iBytes; j++ )
374 { 404 {
375 caData[j] = (unsigned char)(random() & 0xFF); 405 caData[j] = (unsigned char)(random() & 0xFF);
376 } 406 }
@@ -382,7 +412,7 @@ void Bu::BitString::invert()
382{ 412{
383 if( caData != NULL ) 413 if( caData != NULL )
384 { 414 {
385 for( long j = 0; j < nBytes; j++ ) 415 for( long j = 0; j < iBytes; j++ )
386 { 416 {
387 caData[j] = ~caData[j]; 417 caData[j] = ~caData[j];
388 } 418 }
@@ -392,7 +422,7 @@ void Bu::BitString::invert()
392 422
393long Bu::BitString::getHighestOrderBitPos() 423long Bu::BitString::getHighestOrderBitPos()
394{ 424{
395 for( long j = nBits-1; j >= 0; j-- ) 425 for( long j = iBits-1; j >= 0; j-- )
396 { 426 {
397 if( getBit( j ) ) 427 if( getBit( j ) )
398 { 428 {
@@ -405,34 +435,23 @@ long Bu::BitString::getHighestOrderBitPos()
405/* 435/*
406bool Bu::BitString::writeToFile( FILE *fh ) 436bool Bu::BitString::writeToFile( FILE *fh )
407{ 437{
408 fwrite( &nBits, sizeof(long), 1, fh ); 438 fwrite( &iBits, sizeof(long), 1, fh );
409 fwrite( caData, sizeof(char), nBytes, fh ); 439 fwrite( caData, sizeof(char), iBytes, fh );
410 440
411 return true; 441 return true;
412} 442}
413 443
414bool Bu::BitString::readFromFile( FILE *fh ) 444bool Bu::BitString::readFromFile( FILE *fh )
415{ 445{
416 fread( &nBits, sizeof(long), 1, fh ); 446 fread( &iBits, sizeof(long), 1, fh );
417 447
418 nBytes = bitsToBytes( nBits ); 448 iBytes = bitsToBytes( iBits );
419 if( caData ) delete[] caData; 449 if( caData ) delete[] caData;
420 caData = new unsigned char[nBytes]; 450 caData = new unsigned char[iBytes];
421 451
422 fread( caData, sizeof(char), nBytes, fh ); 452 fread( caData, sizeof(char), iBytes, fh );
423 453
424 if( (nBits%8 == 0) ) 454 setMask();
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 455
437 fixup(); 456 fixup();
438 457
diff --git a/src/bitstring.h b/src/bitstring.h
index 8052691..f124d2d 100644
--- a/src/bitstring.h
+++ b/src/bitstring.h
@@ -1,6 +1,8 @@
1#ifndef BU_BITSTRING_H 1#ifndef BU_BITSTRING_H
2#define BU_BITSTRING_H 2#define BU_BITSTRING_H
3 3
4#include "bu/util.h"
5
4namespace Bu 6namespace Bu
5{ 7{
6 /** 8 /**
@@ -18,32 +20,32 @@ namespace Bu
18 { 20 {
19 public: 21 public:
20 /** 22 /**
21 * Constructs a blank and basic BitString. This is actually useful since 23 * Constructs a blank and basic BitString. This is actually useful
22 * you can resize BitStrings at will, and even retain the data that was 24 * since you can resize BitStrings at will, and even retain the data
23 * in them. 25 * that was in them.
24 */ 26 */
25 BitString(); 27 BitString();
26 28
27 /** 29 /**
28 * Constructs a BitString object as a copy of another BitString. This is 30 * Constructs a BitString object as a copy of another BitString. This
29 * a standard copy constructor and produces an exact duplicate of the 31 * is a standard copy constructor and produces an exact duplicate of
30 * original BitString object. 32 * the original BitString object.
31 *@param xSrc Source BitString to copy data from. 33 *@param xSrc Source BitString to copy data from.
32 */ 34 */
33 BitString( const BitString &xSrc ); 35 BitString( const BitString &xSrc );
34 36
35 /** 37 /**
36 * Constructs a BitString with length nBits and optionally fills it with 38 * Constructs a BitString with length iBits and optionally fills it with
37 * random data. The default setting, to not fill randomly, will produce 39 * random data. The default setting, to not fill randomly, will produce
38 * a blank (all zeros) string of the specified size. 40 * a blank (all zeros) string of the specified size.
39 *@param nBits The length of the new BitString in bits. 41 *@param iBits The length of the new BitString in bits.
40 *@param bFillRandomly Wether or not to randomize this BitString. 42 *@param bFillRandomly Wether or not to randomize this BitString.
41 */ 43 */
42 BitString( long nBits, bool bFillRandomly=false ); 44 BitString( long iBits, bool bFillRandomly=false );
43 45
44 /** 46 /**
45 * Virtual deconstructor for the BitString. Takes care of cleanup for you. 47 * Virtual deconstructor for the BitString. Takes care of cleanup for
46 * What more do you really want to know? 48 * you. What more do you really want to know?
47 */ 49 */
48 virtual ~BitString(); 50 virtual ~BitString();
49 51
@@ -52,86 +54,94 @@ namespace Bu
52 * Sets a bit in the BitString. In it's normal mode it will always turn 54 * Sets a bit in the BitString. In it's normal mode it will always turn
53 * the given bit on, to clear a bit set bBitState to false instead of 55 * the given bit on, to clear a bit set bBitState to false instead of
54 * true. This operation runs in O(1). 56 * true. This operation runs in O(1).
55 *@param nBit The zero-based index of the bit to modify. 57 *@param iBit The zero-based index of the bit to modify.
56 *@param bBitState Set to true to set the bit to 1, set to false to set 58 *@param bBitState Set to true to set the bit to 1, set to false to set
57 * the bit to 0. 59 * the bit to 0.
58 */ 60 */
59 void setBit( long nBit, bool bBitState=true ); 61 void setBit( long iBit, bool bBitState=true );
60 62
61 /** 63 /**
62 * Reverses the state of the given bit. This will set the given bit to a 64 * Reverses the state of the given bit. This will set the given bit
63 * 1 if it was 0, and to 0 if it was 1. This operation runs in O(1), and 65 * to a 1 if it was 0, and to 0 if it was 1. This operation runs in
64 * it should be noted that using this is marginally faster than doing the 66 * O(1), and it should be noted that using this is marginally faster
65 * test and flip yourself with getBit and setBit since it uses a bitwise 67 * than doing the test and flip yourself with getBit and setBit since
66 * not operation and doesn't actually test the bit itself. 68 * it uses a bitwise not operation and doesn't actually test the bit
67 *@param nBit The index of the bit to flip. 69 * itself.
70 *@param iBit The index of the bit to flip.
68 */ 71 */
69 void flipBit( long nBit ); 72 void flipBit( long iBit );
70 73
71 /** 74 /**
72 * Gets the state of the given bit. This follows the standard convention 75 * Gets the state of the given bit. This follows the standard
73 * used so far, a returned value of true means the bit in question is 1, 76 * convention used so far, a returned value of true means the bit in
74 * and a value of flase means the bit is 0. All bits out of range of the 77 * question is 1, and a value of flase means the bit is 0. All bits
75 * BitString are treated as off, but are "accessable" in that this does not 78 * out of range of the BitString are treated as off, but are
76 * produce any kind of error message. This is intentional. This operation 79 * "accessable" in that this does not produce any kind of error
77 * runs in O(1). 80 * message. This is intentional. This operation runs in O(1).
78 *@param nBit The index of the bit to test. 81 *@param iBit The index of the bit to test.
79 *@returns True for a 1, false for a 0. 82 *@returns True for a 1, false for a 0.
80 */ 83 */
81 bool getBit( long nBit ); 84 bool getBit( long iBit );
82 85
83 /** 86 /**
84 * Inverts the entire BitString, in effect this calls flipBit on every bit 87 * Inverts the entire BitString, in effect this calls flipBit on every
85 * in the string but is faster since it can operate on whole bytes at a 88 * bit in the string but is faster since it can operate on whole bytes
86 * time instead of individual bits. This operation runs in O(N). 89 * at a time instead of individual bits. This operation runs in O(N).
87 */ 90 */
88 void invert(); 91 void invert();
89 92
90 /** 93 /**
91 * Returns the number of bits allocated in this BitString. This operation 94 * Returns the number of bits allocated in this BitString. This
92 * runs in O(N) time since this value is cached and not computed. 95 * operation runs in O(1) time since this value is cached and not
96 * computed.
93 *@returns The number of bits allocated in this BitString. 97 *@returns The number of bits allocated in this BitString.
94 */ 98 */
99 DEPRECATED
95 long getBitLength(); 100 long getBitLength();
96 101
102 long getSize();
103
97 /** 104 /**
98 * Sets the entire BitString to zeros, but it does it very quickly. This 105 * Sets the entire BitString to zeros, but it does it very quickly.
99 * operation runs in O(N). 106 * This operation runs in O(N).
100 */ 107 */
101 void clearString(); 108 void clear();
102 109
103 /** 110 /**
104 * Gets another BitString that is autonomous of the current one (contains 111 * Gets another BitString that is autonomous of the current one
105 * a copy of the memory, not a pointer) and contains a subset of the data 112 * (contains a copy of the memory, not a pointer) and contains a subset
106 * in the current BitString. This is an inclusive operation, so grabbing 113 * of the data in the current BitString. This is an inclusive
107 * bits 0-5 will give you 6 bits. This is based on a very tricky 114 * operation, so grabbing bits 0-5 will give you 6 bits. This is based
108 * bit-shifting algorithm and runs very quickly, in O(N) time. 115 * on a very tricky bit-shifting algorithm and runs very quickly, in
109 * Passing in a value of zero for nUpper, or any value for nUpper that is 116 * O(N) time. Passing in a value of zero for iUpper, or any value for
110 * less than nLower will set nUpper equal to the number of bits in the 117 * iUpper that is less than iLower will set iUpper equal to the number
111 * BitString. 118 * of bits in the BitString.
112 *@param nLower The first bit in the current string, will be the first bit 119 *@param iLower The first bit in the current string, will be the first
113 * (0 index) in the new sub string. 120 * bit (0 index) in the new sub string.
114 *@param nUpper The last bit in the current string, will be the last bit in 121 *@param iUpper The last bit in the current string, will be the last
115 * the new sub string. nUpper is included in the sub string. 122 * bit in the new sub string. iUpper is included in the sub string.
116 *@returns A new BitString object ready to be used. Please note that 123 *@returns A new BitString object ready to be used. Please note that
117 * managing this new object is up to whomever calls this function. 124 * managing this new object is up to whomever calls this function.
118 */ 125 */
119 class BitString getSubString( long nLower, long nUpper ); 126 class BitString getSubString( long iLower, long iUpper );
120 127
121 /** 128 /**
122 * Sets the number of bits in the BitString, allocating more memory if 129 * Sets the number of bits in the BitString, allocating more memory if
123 * necesarry, or freeing extra if able. The default operation of this 130 * necesarry, or freeing extra if able. The default operation of this
124 * function clears all data in the BitString while resizing it. If you 131 * function clears all data in the BitString while resizing it. If you
125 * would like to keep as much of the data that you had in your BitString 132 * would like to keep as much of the data that you had in your BitString
126 * as possible, then set bClear to false, and any data that will fit into 133 * as possible, then set bClear to false, and any data that will fit
127 * the new BitString length will be retained. If increasing the number of 134 * into the new BitString length will be retained. If increasing the
128 * bits, the new bits will come into existance cleared (set to 0). 135 * number of bits, the new bits will come into existance cleared (set
129 *@param nLength The number of bits to set the BitString to. 136 * to 0).
130 *@param bClear When true, all data is eradicated and zeroed, when set to 137 *@param iLength The number of bits to set the BitString to.
131 * false an effort is made to retain the existing data. 138 *@param bClear When true, all data is eradicated and zeroed, when set
139 * to false an effort is made to retain the existing data.
132 *@returns true on success, false on failure. 140 *@returns true on success, false on failure.
133 */ 141 */
134 bool setBitLength( long nLength, bool bClear=true ); 142 DEPRECATED
143 bool setBitLength( long iLength, bool bClear=true );
144 bool setSize( long iLength, bool bClear=true );
135 145
136 /** 146 /**
137 * Randomize the entire BitString, one bit at a time. This is actually 147 * Randomize the entire BitString, one bit at a time. This is actually
@@ -145,55 +155,57 @@ namespace Bu
145 * Operates exactly like <<. All data in the BitString is shifted to 155 * Operates exactly like <<. All data in the BitString is shifted to
146 * the left by some number of bits, any data pushed off the edge of the 156 * the left by some number of bits, any data pushed off the edge of the
147 * BitString is lost, and all new data coming in will be zeroed. 157 * BitString is lost, and all new data coming in will be zeroed.
148 * Using a negative value in the shiftLeft function will turn it into the 158 * Using a negative value in the shiftLeft function will turn it into
149 * shiftRight function. 159 * the shiftRight function.
150 *@param nAmt The number of bit positions to shift all data. 160 *@param iAmt The number of bit positions to shift all data.
151 */ 161 */
152 void shiftLeft( long nAmt ); // just like << 162 void shiftLeft( long iAmt ); // just like <<
153 163
154 /** 164 /**
155 * Operates exactly like >>. All data in the BitString is shifted to 165 * Operates exactly like >>. All data in the BitString is shifted to
156 * the right by some number of bits, any data pushed off the edge of the 166 * the right by some number of bits, any data pushed off the edge of the
157 * BitString is lost, and all new data coming in will be zeroed. 167 * BitString is lost, and all new data coming in will be zeroed.
158 * Using a negative value in the shiftRight function will turn it into the 168 * Using a negative value in the shiftRight function will turn it into
159 * shiftLeft function. 169 * the shiftLeft function.
160 *@param nAmt The number of bit positions to shift all data. 170 *@param iAmt The number of bit positions to shift all data.
161 */ 171 */
162 void shiftRight( long nAmt ); // just like >> 172 void shiftRight( long iAmt ); // just like >>
163 173
164 /** 174 /**
165 * Searches through the BitString and returns the index of the highest 175 * Searches through the BitString and returns the index of the highest
166 * order bit position (the highest index) with an on bit (a bit set to 1). 176 * order bit position (the highest index) with an on bit (a bit set to
167 * This is a handy helper function and rather faster than calling getBit() 177 * 1). This is a handy helper function and rather faster than calling
168 * over and over again. 178 * getBit() over and over again.
169 *@returns The index of the highest indexed on bit. 179 *@returns The index of the highest indexed on bit.
170 */ 180 */
171 long getHighestOrderBitPos(); 181 long getHighestOrderBitPos();
172 182
173 // Conversion 183 // Conversion
174 /** 184 /**
175 * Convert a block of data (no more than 32 bits) to a primitive long type. 185 * Convert a block of data (no more than 32 bits) to a primitive long
186 * type.
176 * This is done in a little bit interesting way, so it may not always be 187 * This is done in a little bit interesting way, so it may not always be
177 * the fastest way to access the data that you want, although it will 188 * the fastest way to access the data that you want, although it will
178 * always ensure that the long that is written makes numerical sense, as 189 * always ensure that the long that is written makes numerical sense, as
179 * we write numbers, regaurdless of platform. 190 * we write numbers, regaurdless of platform.
180 *@param nStart The first bit in the BitString to include in the long 191 *@param iStart The first bit in the BitString to include in the long
181 *@param nSize THe number of bits to include, if this value is set over 192 *@param iSize THe number of bits to include, if this value is set over
182 * 32 it will be automatically truncated to, or however many bits there 193 * 32 it will be automatically truncated to, or however many bits there
183 * are in a long in your system. 194 * are in a long in your system.
184 *@returns A long converted from your raw BitString data. 195 *@returns A long converted from your raw BitString data.
185 */ 196 */
186 long toLong( long nStart = 0, long nSize = 32 ); 197 long toLong( long iStart = 0, long iSize = 32 );
187 198
188 /** 199 /**
189 * Converts the data into a human-readable SString object. SString is 200 * Converts the data into a human-readable SString object. SString is
190 * used to make transport of the string and management very simple. Since 201 * used to make transport of the string and management very simple.
191 * BitStrings will generally be longer than your average strip of ints a 202 * Since BitStrings will generally be longer than your average strip of
192 * faculty is included and turned on by default that will insert spacers 203 * ints a faculty is included and turned on by default that will insert
193 * into the output text every 8 places. For debugging work, this is 204 * spacers into the output text every 8 places. For debugging work,
194 * definately reccomended. 205 * this is definately reccomended.
195 *@param bAddSpacers Leave set to true in order to have the output broken 206 *@param bAddSpacers Leave set to true in order to have the output
196 * into logical groupings of 8 bits per block. Set to off to have a harder 207 * broken into logical groupings of 8 bits per block. Set to off to
208 * have a harder
197 * to read solid block of bits. 209 * to read solid block of bits.
198 *@returns A SString object containing the produced string. 210 *@returns A SString object containing the produced string.
199 */ 211 */
@@ -202,24 +214,25 @@ namespace Bu
202 // Utility 214 // Utility
203 /** 215 /**
204 * Converts the given number of bits into the smallest allocatable unit, 216 * Converts the given number of bits into the smallest allocatable unit,
205 * which is bytes in C and on most systems nowadays. This is the minimum 217 * which is bytes in C and on most systems nowadays. This is the
206 * number of bytes needed to contain the given number of bits, so there is 218 * minimum number of bytes needed to contain the given number of bits,
207 * generally some slop if they are not evenly divisible. 219 * so there is generally some slop if they are not evenly divisible.
208 *@param nBits The number of bits you wish to use. 220 *@param iBits The number of bits you wish to use.
209 *@returns The number of bytes you will need to contain the given number 221 *@returns The number of bytes you will need to contain the given number
210 * of bits. 222 * of bits.
211 */ 223 */
212 //static long bitsToBytes( long nBits ); 224 //static long bitsToBytes( long iBits );
213 225
214 /** 226 /**
215 * Writes all data in the BitString, including a small header block 227 * Writes all data in the BitString, including a small header block
216 * describing the number of bits in the BitString to the file described 228 * describing the number of bits in the BitString to the file described
217 * by the given file descriptor. The data writen is purely sequential and 229 * by the given file descriptor. The data writen is purely sequential
218 * probably not too easy to read by other mechanisms, although the 230 * and probably not too easy to read by other mechanisms, although the
219 * readFromFile function should always be able to do it. This function 231 * readFromFile function should always be able to do it. This function
220 * does not open nor close the file pointed to by fh. 232 * does not open nor close the file pointed to by fh.
221 *@param fh The file descriptor of the file to write the data to. 233 *@param fh The file descriptor of the file to write the data to.
222 *@returns true if the operation completed without error, false otherwise. 234 *@returns true if the operation completed without error, false
235 * otherwise.
223 */ 236 */
224 //bool writeToFile( FILE *fh ); 237 //bool writeToFile( FILE *fh );
225 238
@@ -229,21 +242,23 @@ namespace Bu
229 * original BitString that it may be replacing. This function does not 242 * original BitString that it may be replacing. This function does not
230 * open nor close the file pointed to by fh. 243 * open nor close the file pointed to by fh.
231 *@param fh The file descriptor to try to read the data from. 244 *@param fh The file descriptor to try to read the data from.
232 *@returns true if the operation completed without error, false otherwise. 245 *@returns true if the operation completed without error, false
246 * otherwise.
233 */ 247 */
234 //bool readFromFile( FILE *fh ); 248 //bool readFromFile( FILE *fh );
235 249
236 //operators 250 //operators
237 BitString &operator=( const BitString &xSrc ); 251 BitString &operator=( const BitString &xSrc );
238 BitString operator~(); 252 BitString operator~();
239 BitString operator<<( const long nAmt ); 253 BitString operator<<( const long iAmt );
240 BitString operator>>( const long nAmt ); 254 BitString operator>>( const long iAmt );
241 255
242 private: 256 private:
243 void fixup(); 257 void fixup();
258 void setMask();
244 unsigned char *caData; 259 unsigned char *caData;
245 long nBits; 260 long iBits;
246 long nBytes; 261 long iBytes;
247 unsigned char cTopByteMask; 262 unsigned char cTopByteMask;
248 }; 263 };
249}; 264};
diff --git a/src/file.h b/src/file.h
index b7ce17d..554ebc9 100644
--- a/src/file.h
+++ b/src/file.h
@@ -32,6 +32,7 @@ namespace Bu
32 virtual void close(); 32 virtual void close();
33 virtual size_t read( void *pBuf, size_t nBytes ); 33 virtual size_t read( void *pBuf, size_t nBytes );
34 virtual size_t write( const void *pBuf, size_t nBytes ); 34 virtual size_t write( const void *pBuf, size_t nBytes );
35 using Stream::write;
35 36
36 virtual long tell(); 37 virtual long tell();
37 virtual void seek( long offset ); 38 virtual void seek( long offset );
diff --git a/src/fstring.h b/src/fstring.h
index 31b55d2..a9b4c95 100644
--- a/src/fstring.h
+++ b/src/fstring.h
@@ -19,21 +19,12 @@
19#include "bu/archival.h" 19#include "bu/archival.h"
20#include "bu/archive.h" 20#include "bu/archive.h"
21#include "bu/hash.h" 21#include "bu/hash.h"
22#include "bu/util.h"
22 23
23#ifndef min 24#ifndef min
24#define min( a, b ) ((a<b)?(a):(b)) 25#define min( a, b ) ((a<b)?(a):(b))
25#endif 26#endif
26 27
27/* I borrowed this from someone who borrowed it from glib who borrowed it
28 * from...
29 */
30#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
31#define DEPRECATED __attribute__((__deprecated__))
32#else
33#define DEPRECATED
34#endif /* __GNUC__ */
35
36
37namespace Bu 28namespace Bu
38{ 29{
39 template< typename chr > 30 template< typename chr >
diff --git a/src/hash.h b/src/hash.h
index 30ad256..25dc509 100644
--- a/src/hash.h
+++ b/src/hash.h
@@ -16,6 +16,7 @@
16#include <utility> 16#include <utility>
17#include "bu/exceptionbase.h" 17#include "bu/exceptionbase.h"
18#include "bu/list.h" 18#include "bu/list.h"
19#include "bu/util.h"
19///#include "archival.h" 20///#include "archival.h"
20///#include "archive.h" 21///#include "archive.h"
21 22
@@ -97,6 +98,7 @@ namespace Bu
97 * Direct function for retrieving a value out of the HashProxy. 98 * Direct function for retrieving a value out of the HashProxy.
98 *@returns (value_type &) The value pointed to by this HashProxy. 99 *@returns (value_type &) The value pointed to by this HashProxy.
99 */ 100 */
101 DEPRECATED
100 _value &value() 102 _value &value()
101 { 103 {
102 if( bFilled == false ) 104 if( bFilled == false )
@@ -106,6 +108,20 @@ namespace Bu
106 ); 108 );
107 return *pValue; 109 return *pValue;
108 } 110 }
111
112 /**
113 * Direct function for retrieving a value out of the HashProxy.
114 *@returns (value_type &) The value pointed to by this HashProxy.
115 */
116 _value &getValue()
117 {
118 if( bFilled == false )
119 throw HashException(
120 excodeNotFilled,
121 "No data assosiated with that key."
122 );
123 return *pValue;
124 }
109 125
110 /** 126 /**
111 * Whether this HashProxy points to something real or not. 127 * Whether this HashProxy points to something real or not.
@@ -165,7 +181,39 @@ namespace Bu
165 }; 181 };
166 182
167 /** 183 /**
168 * Libbu Template Hash Table 184 * Libbu++ Template Hash Table. This is your average hash table, that uses
185 * template functions in order to do fast, efficient, generalized hashing.
186 * It's pretty easy to use, and works well with all other libbu++ types so
187 * far.
188 *
189 * In order to use it, I recommend the following for all basic usage:
190 *@code
191 // Define a Hash typedef with strings as keys and ints as values.
192 typedef Bu::Hash<Bu::FString, int> StrIntHash;
193
194 // Create one
195 StrIntHash hInts;
196
197 // Insert some integers
198 hInts["one"] = 1;
199 hInts["forty-two"] = 42;
200 hInts.insert("forty two", 42 );
201
202 // Get values out of the hash, the last two options are the most explicit,
203 // and must be used if the hash's value type does not match what you're
204 // comparing to exactly.
205 if( hInts["one"] == 1 ) doSomething();
206 if( hInts["forty-two"].value() == 42 ) doSomething();
207 if( hInts.get("forty two") == 42 ) doSomething();
208
209 // Iterate through the Hash
210 for( StrIntHash::iterator i = hInts.begin(); i != hInts.end(); i++ )
211 {
212 // i.getValue() works too
213 print("'%s' = %d\n", i.getKey().getStr(), (*i) );
214 }
215
216 @endcode
169 *@param key (typename) The datatype of the hashtable keys 217 *@param key (typename) The datatype of the hashtable keys
170 *@param value (typename) The datatype of the hashtable data 218 *@param value (typename) The datatype of the hashtable data
171 *@param sizecalc (typename) Functor to compute new table size on rehash 219 *@param sizecalc (typename) Functor to compute new table size on rehash
diff --git a/src/nids.cpp b/src/nids.cpp
index b8ea13b..41c4dc1 100644
--- a/src/nids.cpp
+++ b/src/nids.cpp
@@ -1,8 +1,30 @@
1#include "bu/nids.h" 1#include "bu/nids.h"
2#include "bu/stream.h"
3#include "bu/nidsstream.h"
4#include <stdio.h>
2 5
3Bu::Nids::Nids( Bu::Stream &sStore ) : 6Bu::Nids::Nids( Bu::Stream &sStore ) :
4 sStore( sStore ) 7 sStore( sStore )
5{ 8{
9 printf("Stream caps:\n"
10 " canRead: %s\n"
11 " canWrite: %s\n"
12 " isReadable: %s\n"
13 " isWritable: %s\n"
14 " isSeekable: %s\n"
15 " isBlocking: %s\n"
16 " isEOS: %s\n"
17 " isOpen: %s\n",
18 sStore.canRead()?"yes":"no",
19 sStore.canWrite()?"yes":"no",
20 sStore.isReadable()?"yes":"no",
21 sStore.isWritable()?"yes":"no",
22 sStore.isSeekable()?"yes":"no",
23 sStore.isBlocking()?"yes":"no",
24 sStore.isEOS()?"yes":"no",
25 sStore.isOpen()?"yes":"no"
26 );
27 printf("sizeof(Block) = %db\n", sizeof(Block) );
6} 28}
7 29
8Bu::Nids::~Nids() 30Bu::Nids::~Nids()
@@ -11,11 +33,82 @@ Bu::Nids::~Nids()
11 33
12void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) 34void Bu::Nids::initialize( int iBlockSize, int iPreAllocate )
13{ 35{
36 char cBuf = 0;
37 int iBuf = 0;
38
39 // Magic number
40 sStore.write( "\xFF\xC3\x99\xBD", 4 );
41
42 // Version (0)
43 sStore.write( &cBuf, 1 );
44
45 // Bytes per int
46 cBuf = 4;
47 sStore.write( &cBuf, 1 );
48
49 // The size of each block and the number of blocks we're pre-allocating
50 sStore.write( &iBlockSize, 4 );
51 sStore.write( &iPreAllocate, 4 );
52
53 // The number of used blocks
54 sStore.write( &iBuf, 4 );
55
56 // Reserved space
57 sStore.write( "\x00\x00\x00\x00\x00\x00\x00", 7 );
58
59 this->iBlockSize = iBlockSize;
60 this->iBlocks = iPreAllocate;
61 this->iBlockStart = sStore.tell();
62 bsBlockUsed.setSize( iPreAllocate, true );
63
64 printf("%d blocks, %db each, %db block offset\n",
65 iBlocks, iBlockSize, iBlockStart );
66
67 char *block = new char[iBlockSize];
68 memset( block, 0, iBlockSize );
69 for( int j = 0; j < iPreAllocate; j++ )
70 {
71 sStore.write( block, iBlockSize );
72 }
14} 73}
15 74
16int Bu::Nids::createStream( int iPreAllocate ) 75int Bu::Nids::createStream( int iPreAllocate )
17{ 76{
77 for( int j = 0; j < iBlocks; j++ )
78 {
79 if( !bsBlockUsed.getBit( j ) )
80 {
81 Block b = { j, blockUnused, blockUnused, 0, 0 };
82 bsBlockUsed.setBit( j );
83 sStore.setPos( iBlockStart+(iBlockSize*j) );
84 sStore.write( &b, sizeof(b) );
85 }
86 }
18 return 0; 87 return 0;
19} 88}
20 89
90void Bu::Nids::deleteStream( int iID )
91{
92}
93
94Bu::NidsStream Bu::Nids::openStream( int iID )
95{
96 return NidsStream( *this );
97}
98
99void Bu::Nids::extendStream( int iID, int iBlockCount )
100{
101}
102
103void Bu::Nids::getBlock( int iIndex, Bu::Nids::Block *pBlock )
104{
105 sStore.setPos( iBlockStart + (iBlockSize*iIndex) );
106 sStore.read( pBlock, iBlockSize );
107}
108
109void Bu::Nids::setBlock( int iIndex, Bu::Nids::Block *pBlock )
110{
111 sStore.setPos( iBlockStart + (iBlockSize*iIndex) );
112 sStore.write( pBlock, iBlockSize );
113}
21 114
diff --git a/src/nids.h b/src/nids.h
index 9954146..e364289 100644
--- a/src/nids.h
+++ b/src/nids.h
@@ -1,9 +1,13 @@
1#ifndef BU_NIDS_H 1#ifndef BU_NIDS_H
2#define BU_NIDS_H 2#define BU_NIDS_H
3 3
4#include <stdint.h>
5#include "bu/bitstring.h"
6
4namespace Bu 7namespace Bu
5{ 8{
6 class Stream; 9 class Stream;
10 class NidsStream;
7 11
8 /** 12 /**
9 * Numerically Indexed Data Streams. This is a working name so I can 13 * Numerically Indexed Data Streams. This is a working name so I can
@@ -14,6 +18,7 @@ namespace Bu
14 */ 18 */
15 class Nids 19 class Nids
16 { 20 {
21 friend class NidsStream;
17 public: 22 public:
18 Nids( Bu::Stream &sStore ); 23 Nids( Bu::Stream &sStore );
19 virtual ~Nids(); 24 virtual ~Nids();
@@ -39,10 +44,34 @@ namespace Bu
39 /** 44 /**
40 * Return a new Stream object assosiated with the given stream ID. 45 * Return a new Stream object assosiated with the given stream ID.
41 */ 46 */
42 Bu::Stream &openStream( int iID ); 47 NidsStream openStream( int iID );
48
49 private:
50 typedef struct Block
51 {
52 uint32_t iFirstBlock;
53 uint32_t iNextBlock;
54 uint32_t iPrevBlock;
55 uint32_t iBytesUsed;
56 uint32_t iReserved;
57 unsigned char pData[0];
58 } Block;
59
60 enum
61 {
62 blockUnused = 0xFFFFFFFFUL
63 };
64
65 void extendStream( int iID, int iBlockCount=1 );
66 void getBlock( int iIndex, struct Nids::Block *pBlock );
67 void setBlock( int iIndex, struct Nids::Block *pBlock );
43 68
44 private: 69 private:
45 Bu::Stream &sStore; 70 Bu::Stream &sStore;
71 int iBlockSize;
72 int iBlocks;
73 int iBlockStart;
74 Bu::BitString bsBlockUsed;
46 }; 75 };
47}; 76};
48 77
diff --git a/src/nidsstream.cpp b/src/nidsstream.cpp
index d05fbc0..e3bd731 100644
--- a/src/nidsstream.cpp
+++ b/src/nidsstream.cpp
@@ -1,10 +1,96 @@
1#include "bu/nidsstream.h" 1#include "bu/nidsstream.h"
2 2
3Bu::NidsStream::NidsStream() 3Bu::NidsStream::NidsStream( Nids &rNids ) :
4 rNids( rNids )
4{ 5{
5} 6}
6 7
8Bu::NidsStream::NidsStream( const Bu::NidsStream &rSrc ) :
9 rNids( rSrc.rNids )
10{
11
12}
13
7Bu::NidsStream::~NidsStream() 14Bu::NidsStream::~NidsStream()
8{ 15{
9} 16}
10 17
18void Bu::NidsStream::close()
19{
20}
21
22size_t Bu::NidsStream::read( void *pBuf, size_t nBytes )
23{
24 return 0;
25}
26
27size_t Bu::NidsStream::write( const void *pBuf, size_t nBytes )
28{
29 return 0;
30}
31
32long Bu::NidsStream::tell()
33{
34 return 0;
35}
36
37void Bu::NidsStream::seek( long offset )
38{
39}
40
41void Bu::NidsStream::setPos( long pos )
42{
43}
44
45void Bu::NidsStream::setPosEnd( long pos )
46{
47}
48
49bool Bu::NidsStream::isEOS()
50{
51 return true;
52}
53
54bool Bu::NidsStream::isOpen()
55{
56 return true;
57}
58
59void Bu::NidsStream::flush()
60{
61}
62
63bool Bu::NidsStream::canRead()
64{
65 return true;
66}
67
68bool Bu::NidsStream::canWrite()
69{
70 return true;
71}
72
73bool Bu::NidsStream::isReadable()
74{
75 return true;
76}
77
78bool Bu::NidsStream::isWritable()
79{
80 return true;
81}
82
83bool Bu::NidsStream::isSeekable()
84{
85 return true;
86}
87
88bool Bu::NidsStream::isBlocking()
89{
90 return true;
91}
92
93void Bu::NidsStream::setBlocking( bool bBlocking )
94{
95}
96
diff --git a/src/nidsstream.h b/src/nidsstream.h
index 08b45eb..8021dee 100644
--- a/src/nidsstream.h
+++ b/src/nidsstream.h
@@ -2,16 +2,46 @@
2#define BU_NIDS_STREAM_H 2#define BU_NIDS_STREAM_H
3 3
4#include "bu/stream.h" 4#include "bu/stream.h"
5#include "bu/nids.h"
5 6
6namespace Bu 7namespace Bu
7{ 8{
8 class NidsStream : public Bu::Stream 9 class NidsStream : public Bu::Stream
9 { 10 {
11 friend class Nids;
12 private:
13 /**
14 * These can only be created by the Nids class.
15 */
16 NidsStream( Nids &rNids );
17 NidsStream( const NidsStream &rSrc );
18
10 public: 19 public:
11 NidsStream();
12 virtual ~NidsStream(); 20 virtual ~NidsStream();
13 21
22 virtual void close();
23 virtual size_t read( void *pBuf, size_t nBytes );
24 virtual size_t write( const void *pBuf, size_t nBytes );
25 using Stream::write;
26 virtual long tell();
27 virtual void seek( long offset );
28 virtual void setPos( long pos );
29 virtual void setPosEnd( long pos );
30 virtual bool isEOS();
31 virtual bool isOpen();
32 virtual void flush();
33 virtual bool canRead();
34 virtual bool canWrite();
35 virtual bool isReadable();
36 virtual bool isWritable();
37 virtual bool isSeekable();
38 virtual bool isBlocking();
39 virtual void setBlocking( bool bBlocking=true );
40
14 private: 41 private:
42 Nids &rNids;
43 typedef struct Bu::Hash<int, struct Nids::Block *> BlockHash;
44 BlockHash hBlock;
15 }; 45 };
16}; 46};
17 47
diff --git a/src/tests/hash.cpp b/src/tests/hash.cpp
index 76cf0ec..9cc45f5 100644
--- a/src/tests/hash.cpp
+++ b/src/tests/hash.cpp
@@ -25,7 +25,7 @@ int main()
25 25
26 for( int j = 0; j < 10; j++ ) 26 for( int j = 0; j < 10; j++ )
27 { 27 {
28 printf("%d\n", lb[j].value()->nID ); 28 printf("%d\n", lb[j].getValue()->nID );
29 } 29 }
30} 30}
31 31
diff --git a/src/tests/nids.cpp b/src/tests/nids.cpp
new file mode 100644
index 0000000..1197ac1
--- /dev/null
+++ b/src/tests/nids.cpp
@@ -0,0 +1,19 @@
1#include "bu/file.h"
2#include "bu/nids.h"
3
4int main( int argc, char *argv[] )
5{
6 if( argc < 2 )
7 {
8 printf("usage: %s <output>\n\n", argv[0] );
9 return 1;
10 }
11
12 Bu::File fOut( argv[1], "wb");
13 Bu::Nids n( fOut );
14
15 n.initialize( 1024, 5 );
16
17 Bu::NidsStream s = n.openStream( n.createStream() );
18}
19
diff --git a/src/unit/hash.cpp b/src/unit/hash.cpp
index 481256b..b869bdd 100644
--- a/src/unit/hash.cpp
+++ b/src/unit/hash.cpp
@@ -15,18 +15,22 @@ class Unit : public Bu::UnitSuite
15{ 15{
16private: 16private:
17 typedef Bu::Hash<Bu::FString, int> StrIntHash; 17 typedef Bu::Hash<Bu::FString, int> StrIntHash;
18 typedef Bu::Hash<Bu::FString, Bu::FString> StrStrHash;
19
18public: 20public:
19 Unit() 21 Unit()
20 { 22 {
21 setName("Hash"); 23 setName("Hash");
22 addTest( Unit::test_probe ); 24 addTest( Unit::insert1 );
25 addTest( Unit::insert2 );
26 addTest( Unit::probe1 );
23 } 27 }
24 28
25 virtual ~Unit() 29 virtual ~Unit()
26 { 30 {
27 } 31 }
28 32
29 void test_probe() 33 void probe1()
30 { 34 {
31 StrIntHash h; 35 StrIntHash h;
32 char buf[20]; 36 char buf[20];
@@ -38,6 +42,20 @@ public:
38 unitTest( h.has(sTmp) ); 42 unitTest( h.has(sTmp) );
39 } 43 }
40 } 44 }
45
46 void insert1()
47 {
48 StrIntHash h;
49 h["Hi"] = 42;
50 unitTest( h["Hi"] == 42 );
51 }
52
53 void insert2()
54 {
55 StrStrHash h;
56 h["Hi"] = "Yo";
57 unitTest( h["Hi"].getValue() == "Yo" );
58 }
41}; 59};
42 60
43int main( int argc, char *argv[] ) 61int main( int argc, char *argv[] )
diff --git a/src/util.h b/src/util.h
index 6205c04..b55ceee 100644
--- a/src/util.h
+++ b/src/util.h
@@ -8,6 +8,15 @@
8#ifndef BU_UTIL_H 8#ifndef BU_UTIL_H
9#define BU_UTIL_H 9#define BU_UTIL_H
10 10
11/* I borrowed this from someone who borrowed it from glib who borrowed it
12 * from...
13 */
14#if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1))
15#define DEPRECATED __attribute__((__deprecated__))
16#else
17#define DEPRECATED
18#endif /* __GNUC__ */
19
11namespace Bu 20namespace Bu
12{ 21{
13 template<typename item> 22 template<typename item>