aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--misc/raa_format.txt20
-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
15 files changed, 620 insertions, 262 deletions
diff --git a/misc/raa_format.txt b/misc/raa_format.txt
index 1b2c9f8..693cbc8 100644
--- a/misc/raa_format.txt
+++ b/misc/raa_format.txt
@@ -22,16 +22,17 @@ structures.
22The basic header: 22The basic header:
23 23
2400-03: Magic Number, something cute, I dunno yet (encoding independant) 2400-03: Magic Number, something cute, I dunno yet (encoding independant)
2504: Byte count/order for standard indexes (8/4 for 64/32bit systems) 2504: Version code (0)
26 High order bit masked out determines endianness (1 = big, 0 = small) 2605: Byte count/order for standard indexes (8/4 for 64/32bit systems)
27 High order bit masked out determines endianness (1 = big, 0 = little)
27 The program will only accept one word-width for now, we can make it 28 The program will only accept one word-width for now, we can make it
28 adjustable later, or fix this at 4 bytes. 29 adjustable later, or fix this at 4 bytes.
2905-08: Blocksize in bytes, could be anything, I don't think we need to worry 3006-09: Blocksize in bytes, could be anything, I don't think we need to worry
30 about OS related things for this, but it should be set intelligently by 31 about OS related things for this, but it should be set intelligently by
31 the owner. This includes the bytes reserved for a block header. 32 the owner. This includes the bytes reserved for a block header.
3209-12: Total block count, includes both used and unused blocks. 3310-13: Total block count, includes both used and unused blocks.
3313-16: Total used blocks, useful for determining when to expand. 3414-17: Total used blocks, useful for determining when to expand.
3417-24: Reserved for flags and the like, should be all zeros for now. 3518-24: Reserved for flags and the like, should be all zeros for now.
35 36
36At this point are a number of "blocks" each with their own header and data are 37At this point are a number of "blocks" each with their own header and data are
37laid out sequentially, accessing one should be easy, seek to 38laid out sequentially, accessing one should be easy, seek to
@@ -45,10 +46,9 @@ The block header is as follows:
45 then this block is the last in the chain. 46 then this block is the last in the chain.
4608-11: Prev block in chain. If this number matches the current block index 4708-11: Prev block in chain. If this number matches the current block index
47 then this block is the first in the chain. 48 then this block is the first in the chain.
4812-15: Number of bytes used/allocated remaining in the chain. If this is the 4912-15: Number of bytes used. If this is the first block, this is the total
49 first block, then this is the total size of the object accross all 50 amount of data in the stream, otherwise it's the amount of data in the
50 blocks in the chain. For the last block in the chain this will usually 51 current block.
51 be less than the available space.
5216-19: Reserved flagspace or something, make sure it's all zeros. 5216-19: Reserved flagspace or something, make sure it's all zeros.
5320-xx: Block data, whatever you wanted to store. At the moment this is going 5320-xx: Block data, whatever you wanted to store. At the moment this is going
54 to be (blocksize) - 20 for now, it will change if the block header 54 to be (blocksize) - 20 for now, it will change if the block header
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>