aboutsummaryrefslogtreecommitdiff
path: root/src/nids.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/nids.cpp')
-rw-r--r--src/nids.cpp275
1 files changed, 0 insertions, 275 deletions
diff --git a/src/nids.cpp b/src/nids.cpp
deleted file mode 100644
index 6628f14..0000000
--- a/src/nids.cpp
+++ /dev/null
@@ -1,275 +0,0 @@
1/*
2 * Copyright (C) 2007-2010 Xagasoft, All rights reserved.
3 *
4 * This file is part of the libbu++ library and is released under the
5 * terms of the license contained in the file LICENSE.
6 */
7
8#include "bu/nids.h"
9#include "bu/stream.h"
10#include "bu/nidsstream.h"
11#include <stdio.h>
12
13#define NIDS_MAGIC_CODE ((unsigned char *)"\xFF\xC3\x99\xBD")
14
15namespace Bu
16{
17 subExceptionDef( NidsException )
18}
19
20Bu::Nids::Nids( Bu::Stream &sStore ) :
21 sStore( sStore ),
22 iBlockSize( 0 ),
23 iBlocks( 0 ),
24 iBlockStart( -1 ),
25 iUsed( 0 )
26{
27}
28
29Bu::Nids::~Nids()
30{
31 updateHeader();
32}
33
34void Bu::Nids::sync()
35{
36 updateHeader();
37
38 // Later, also flush all caches.
39}
40
41void Bu::Nids::initialize()
42{
43 unsigned char buf[4];
44 if( sStore.read( buf, 4 ) < 4 )
45 throw NidsException("Input stream appears to be empty.");
46 if( memcmp( buf, NIDS_MAGIC_CODE, 4 ) )
47 {
48 throw NidsException(
49 "Stream does not appear to be a valid NIDS format.");
50 }
51 sStore.read( buf, 2 );
52 if( buf[0] != 0 )
53 throw NidsException(
54 "We can only handle version 0 for now.");
55 if( buf[1] != 4 )
56 throw NidsException(
57 "We can only handle 4-byte words at the moment.");
58 sStore.read( &iBlockSize, 4 );
59 sStore.read( &iBlocks, 4 );
60 sStore.read( &iUsed, 4 ); // number of used blocks...
61 sStore.seek( 7 ); // skip reserved space.
62 iBlockStart = sStore.tell();
63
64 //printf("%d blocks, %db each, %db block offset\n",
65 // iBlocks, iBlockSize, iBlockStart );
66
67 bsBlockUsed.setSize( iBlocks, true );
68 Block bTmp;
69 for( int j = 0; j < iBlocks; j++ )
70 {
71 sStore.seek( iBlockStart+iBlockSize*j );
72 sStore.read( &bTmp, sizeof(bTmp) );
73 if( bTmp.uFirstBlock != blockUnused )
74 bsBlockUsed.setBit( j );
75 }
76}
77
78void Bu::Nids::initialize( int iBlockSize, int iPreAllocate )
79{
80 char cBuf = 0;
81 int iBuf = 0;
82
83 // Magic number
84 sStore.write( NIDS_MAGIC_CODE, 4 );
85
86 // Version (0)
87 sStore.write( &cBuf, 1 );
88
89 // Bytes per int
90 cBuf = 4;
91 sStore.write( &cBuf, 1 );
92
93 // The size of each block and the number of blocks we're pre-allocating
94 sStore.write( &iBlockSize, 4 );
95 sStore.write( &iPreAllocate, 4 );
96
97 // The number of used blocks
98 sStore.write( &iBuf, 4 );
99
100 // Reserved space
101 sStore.write( "\x00\x00\x00\x00\x00\x00\x00", 7 );
102
103 this->iBlockSize = iBlockSize;
104 this->iBlocks = iPreAllocate;
105 this->iBlockStart = sStore.tell();
106 //printf("iBlockStart = %d\n", this->iBlockStart );
107 bsBlockUsed.setSize( iPreAllocate, true );
108
109 //printf("%d blocks, %db each, %db block offset\n",
110 // iBlocks, iBlockSize, iBlockStart );
111
112 Block *block = (Block *)new char[iBlockSize];
113 memset( block, 0, iBlockSize );
114 block->uFirstBlock = block->uNextBlock /*=block->uPrevBlock*/ = blockUnused;
115 for( int j = 0; j < iPreAllocate; j++ )
116 {
117 sStore.write( block, iBlockSize );
118 }
119 delete[] (char *)block;
120}
121
122void Bu::Nids::updateHeader()
123{
124 if( !sStore.canWrite() )
125 return;
126 sStore.setPos( 10 ); // Skip the magic number, version, bpi, block size
127 sStore.write( &iBlocks, 4 );
128 sStore.write( &iUsed, 4 );
129}
130
131void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock,
132 /*uint32_t uPrevBlock,*/ bool bNew )
133{
134 Block b = { uPos, blockUnused, /*uPrevBlock, 0,*/ 0, { } };
135 if( uFirstBlock != blockUnused )
136 b.uFirstBlock = uFirstBlock;
137 bsBlockUsed.setBit( uPos );
138 sStore.setPos( iBlockStart+(iBlockSize*uPos) );
139 sStore.write( &b, sizeof(Block) );
140 if( bNew )
141 {
142 // It's a new one, at the end, write some zeros.
143 int iSize = iBlockSize-sizeof(Block);
144 char *buf = new char[iSize];
145 memset( buf, 0, iSize );
146 sStore.write( buf, iSize );
147 delete[] buf;
148 }
149 iUsed++;
150}
151
152uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, /*uint32_t uPrevBlock,*/
153 int /*iPreAllocate*/ )
154{
155 for( int j = 0; j < iBlocks; j++ )
156 {
157 if( !bsBlockUsed.getBit( j ) )
158 {
159 initBlock( j, uFirstBlock/*, uPrevBlock*/ );
160 return j;
161 }
162 }
163 // Oh, we don't have any blocks left...allocate a new one.
164 iBlocks++;
165 bsBlockUsed.setSize( iBlocks, false );
166 initBlock( iBlocks-1, uFirstBlock/*, uPrevBlock*/, true );
167 return iBlocks-1;
168}
169
170int Bu::Nids::createStream( int iPreAllocate )
171{
172 return createBlock( blockUnused, /*blockUnused,*/ iPreAllocate );
173}
174
175void Bu::Nids::deleteStream( int /*iID*/ )
176{
177}
178
179Bu::NidsStream Bu::Nids::openStream( int iID )
180{
181 if( iBlockStart < 0 )
182 {
183 initialize();
184 }
185 return NidsStream( *this, iID );
186}
187
188int Bu::Nids::getBlockSize()
189{
190 return iBlockSize;
191}
192
193int Bu::Nids::getNumBlocks()
194{
195 return iBlocks;
196}
197
198int Bu::Nids::getNumUsedBlocks()
199{
200 return iUsed;
201}
202
203int Bu::Nids::getBlockStart()
204{
205 return iBlockStart;
206}
207
208int Bu::Nids::getBlockOverhead()
209{
210 return sizeof(Block);
211}
212
213/*
214void Bu::Nids::extendStream( int iID, int iBlockCount )
215{
216}*/
217
218void Bu::Nids::getBlock( uint32_t uIndex, Bu::Nids::Block *pBlock )
219{
220 sStore.setPos( iBlockStart + (iBlockSize*uIndex) );
221 sStore.read( pBlock, iBlockSize );
222}
223
224void Bu::Nids::setBlock( uint32_t uIndex, Bu::Nids::Block *pBlock )
225{
226 sStore.setPos( iBlockStart + (iBlockSize*uIndex) );
227 sStore.write( pBlock, iBlockSize );
228}
229
230void Bu::Nids::updateStreamSize( uint32_t uIndex, uint32_t uSize )
231{
232 if( !sStore.canWrite() )
233 return;
234 sStore.setPos( iBlockStart + (iBlockSize*uIndex)+4*2 );
235 sStore.write( &uSize, 4 );
236}
237
238uint32_t Bu::Nids::getNextBlock( uint32_t uIndex,
239 struct Bu::Nids::Block *pBlock, bool bCreate )
240{
241 uint32_t uNew;
242 if( pBlock->uNextBlock == blockUnused )
243 {
244 if( bCreate )
245 {
246 uNew = createBlock( pBlock->uFirstBlock, uIndex );
247 sStore.setPos( iBlockStart + (iBlockSize*uIndex)+1*4 );
248 sStore.write( &uNew, 4 );
249 getBlock( uNew, pBlock );
250 //printf("Allocated new block (%u) for stream %u.\n",
251 // uNew, pBlock->uFirstBlock );
252 }
253 else
254 {
255 throw Bu::NidsException("Reached end of stream.");
256 }
257 }
258 else
259 {
260 uNew = pBlock->uNextBlock;
261 getBlock( pBlock->uNextBlock, pBlock );
262 }
263 return uNew;
264}
265
266Bu::Nids::Block *Bu::Nids::newBlock()
267{
268 return (Block *)new char[iBlockSize];
269}
270
271void Bu::Nids::deleteBlock( Block *pBlock )
272{
273 delete[] (char *)pBlock;
274}
275