diff options
Diffstat (limited to '')
-rw-r--r-- | src/nids.cpp | 275 |
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 | |||
15 | namespace Bu | ||
16 | { | ||
17 | subExceptionDef( NidsException ) | ||
18 | } | ||
19 | |||
20 | Bu::Nids::Nids( Bu::Stream &sStore ) : | ||
21 | sStore( sStore ), | ||
22 | iBlockSize( 0 ), | ||
23 | iBlocks( 0 ), | ||
24 | iBlockStart( -1 ), | ||
25 | iUsed( 0 ) | ||
26 | { | ||
27 | } | ||
28 | |||
29 | Bu::Nids::~Nids() | ||
30 | { | ||
31 | updateHeader(); | ||
32 | } | ||
33 | |||
34 | void Bu::Nids::sync() | ||
35 | { | ||
36 | updateHeader(); | ||
37 | |||
38 | // Later, also flush all caches. | ||
39 | } | ||
40 | |||
41 | void 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 | |||
78 | void 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 | |||
122 | void 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 | |||
131 | void 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 | |||
152 | uint32_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 | |||
170 | int Bu::Nids::createStream( int iPreAllocate ) | ||
171 | { | ||
172 | return createBlock( blockUnused, /*blockUnused,*/ iPreAllocate ); | ||
173 | } | ||
174 | |||
175 | void Bu::Nids::deleteStream( int /*iID*/ ) | ||
176 | { | ||
177 | } | ||
178 | |||
179 | Bu::NidsStream Bu::Nids::openStream( int iID ) | ||
180 | { | ||
181 | if( iBlockStart < 0 ) | ||
182 | { | ||
183 | initialize(); | ||
184 | } | ||
185 | return NidsStream( *this, iID ); | ||
186 | } | ||
187 | |||
188 | int Bu::Nids::getBlockSize() | ||
189 | { | ||
190 | return iBlockSize; | ||
191 | } | ||
192 | |||
193 | int Bu::Nids::getNumBlocks() | ||
194 | { | ||
195 | return iBlocks; | ||
196 | } | ||
197 | |||
198 | int Bu::Nids::getNumUsedBlocks() | ||
199 | { | ||
200 | return iUsed; | ||
201 | } | ||
202 | |||
203 | int Bu::Nids::getBlockStart() | ||
204 | { | ||
205 | return iBlockStart; | ||
206 | } | ||
207 | |||
208 | int Bu::Nids::getBlockOverhead() | ||
209 | { | ||
210 | return sizeof(Block); | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | void Bu::Nids::extendStream( int iID, int iBlockCount ) | ||
215 | { | ||
216 | }*/ | ||
217 | |||
218 | void Bu::Nids::getBlock( uint32_t uIndex, Bu::Nids::Block *pBlock ) | ||
219 | { | ||
220 | sStore.setPos( iBlockStart + (iBlockSize*uIndex) ); | ||
221 | sStore.read( pBlock, iBlockSize ); | ||
222 | } | ||
223 | |||
224 | void Bu::Nids::setBlock( uint32_t uIndex, Bu::Nids::Block *pBlock ) | ||
225 | { | ||
226 | sStore.setPos( iBlockStart + (iBlockSize*uIndex) ); | ||
227 | sStore.write( pBlock, iBlockSize ); | ||
228 | } | ||
229 | |||
230 | void 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 | |||
238 | uint32_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 | |||
266 | Bu::Nids::Block *Bu::Nids::newBlock() | ||
267 | { | ||
268 | return (Block *)new char[iBlockSize]; | ||
269 | } | ||
270 | |||
271 | void Bu::Nids::deleteBlock( Block *pBlock ) | ||
272 | { | ||
273 | delete[] (char *)pBlock; | ||
274 | } | ||
275 | |||