diff options
Diffstat (limited to 'src/nids.cpp')
-rw-r--r-- | src/nids.cpp | 115 |
1 files changed, 74 insertions, 41 deletions
diff --git a/src/nids.cpp b/src/nids.cpp index a6596a2..06895ac 100644 --- a/src/nids.cpp +++ b/src/nids.cpp | |||
@@ -1,3 +1,10 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2008 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 | |||
1 | #include "bu/nids.h" | 8 | #include "bu/nids.h" |
2 | #include "bu/stream.h" | 9 | #include "bu/stream.h" |
3 | #include "bu/nidsstream.h" | 10 | #include "bu/nidsstream.h" |
@@ -16,30 +23,6 @@ Bu::Nids::Nids( Bu::Stream &sStore ) : | |||
16 | iBlocks( 0 ), | 23 | iBlocks( 0 ), |
17 | iBlockStart( -1 ) | 24 | iBlockStart( -1 ) |
18 | { | 25 | { |
19 | printf("blockUnused = %u\n", blockUnused ); | ||
20 | printf("Stream caps:\n" | ||
21 | " canRead: %s\n" | ||
22 | " canWrite: %s\n" | ||
23 | " isReadable: %s\n" | ||
24 | " isWritable: %s\n" | ||
25 | " isSeekable: %s\n" | ||
26 | " isBlocking: %s\n" | ||
27 | " isEOS: %s\n" | ||
28 | " isOpen: %s\n", | ||
29 | sStore.canRead()?"yes":"no", | ||
30 | sStore.canWrite()?"yes":"no", | ||
31 | sStore.isReadable()?"yes":"no", | ||
32 | sStore.isWritable()?"yes":"no", | ||
33 | sStore.isSeekable()?"yes":"no", | ||
34 | sStore.isBlocking()?"yes":"no", | ||
35 | sStore.isEOS()?"yes":"no", | ||
36 | sStore.isOpen()?"yes":"no" | ||
37 | ); | ||
38 | printf("sizeof(Block) = %db\n", sizeof(Block) ); | ||
39 | printf("Magic: %02X%02X%02X%02X\n", | ||
40 | NIDS_MAGIC_CODE[0], NIDS_MAGIC_CODE[1], | ||
41 | NIDS_MAGIC_CODE[2], NIDS_MAGIC_CODE[3] | ||
42 | ); | ||
43 | } | 26 | } |
44 | 27 | ||
45 | Bu::Nids::~Nids() | 28 | Bu::Nids::~Nids() |
@@ -49,6 +32,7 @@ Bu::Nids::~Nids() | |||
49 | void Bu::Nids::initialize() | 32 | void Bu::Nids::initialize() |
50 | { | 33 | { |
51 | unsigned char buf[4]; | 34 | unsigned char buf[4]; |
35 | int iUsed; | ||
52 | if( sStore.read( buf, 4 ) < 4 ) | 36 | if( sStore.read( buf, 4 ) < 4 ) |
53 | throw NidsException("Input stream appears to be empty."); | 37 | throw NidsException("Input stream appears to be empty."); |
54 | if( memcmp( buf, NIDS_MAGIC_CODE, 4 ) ) | 38 | if( memcmp( buf, NIDS_MAGIC_CODE, 4 ) ) |
@@ -56,8 +40,31 @@ void Bu::Nids::initialize() | |||
56 | throw NidsException( | 40 | throw NidsException( |
57 | "Stream does not appear to be a valid NIDS format."); | 41 | "Stream does not appear to be a valid NIDS format."); |
58 | } | 42 | } |
59 | 43 | sStore.read( buf, 2 ); | |
60 | 44 | if( buf[0] != 0 ) | |
45 | throw NidsException( | ||
46 | "We can only handle version 0 for now."); | ||
47 | if( buf[1] != 4 ) | ||
48 | throw NidsException( | ||
49 | "We can only handle 4-byte words at the moment."); | ||
50 | sStore.read( &iBlockSize, 4 ); | ||
51 | sStore.read( &iBlocks, 4 ); | ||
52 | sStore.read( &iUsed, 4 ); // number of used blocks... | ||
53 | sStore.seek( 7 ); // skip reserved space. | ||
54 | iBlockStart = sStore.tell(); | ||
55 | |||
56 | //printf("%d blocks, %db each, %db block offset\n", | ||
57 | // iBlocks, iBlockSize, iBlockStart ); | ||
58 | |||
59 | bsBlockUsed.setSize( iBlocks, true ); | ||
60 | Block bTmp; | ||
61 | for( int j = 0; j < iBlocks; j++ ) | ||
62 | { | ||
63 | sStore.seek( iBlockStart+iBlockSize*j ); | ||
64 | sStore.read( &bTmp, sizeof(bTmp) ); | ||
65 | if( bTmp.uFirstBlock != blockUnused ) | ||
66 | bsBlockUsed.setBit( j ); | ||
67 | } | ||
61 | } | 68 | } |
62 | 69 | ||
63 | void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) | 70 | void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) |
@@ -88,11 +95,11 @@ void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) | |||
88 | this->iBlockSize = iBlockSize; | 95 | this->iBlockSize = iBlockSize; |
89 | this->iBlocks = iPreAllocate; | 96 | this->iBlocks = iPreAllocate; |
90 | this->iBlockStart = sStore.tell(); | 97 | this->iBlockStart = sStore.tell(); |
91 | printf("iBlockStart = %d\n", this->iBlockStart ); | 98 | //printf("iBlockStart = %d\n", this->iBlockStart ); |
92 | bsBlockUsed.setSize( iPreAllocate, true ); | 99 | bsBlockUsed.setSize( iPreAllocate, true ); |
93 | 100 | ||
94 | printf("%d blocks, %db each, %db block offset\n", | 101 | //printf("%d blocks, %db each, %db block offset\n", |
95 | iBlocks, iBlockSize, iBlockStart ); | 102 | // iBlocks, iBlockSize, iBlockStart ); |
96 | 103 | ||
97 | Block *block = (Block *)new char[iBlockSize]; | 104 | Block *block = (Block *)new char[iBlockSize]; |
98 | memset( block, 0, iBlockSize ); | 105 | memset( block, 0, iBlockSize ); |
@@ -104,6 +111,26 @@ void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) | |||
104 | delete[] (char *)block; | 111 | delete[] (char *)block; |
105 | } | 112 | } |
106 | 113 | ||
114 | void Bu::Nids::initBlock( uint32_t uPos, uint32_t uFirstBlock, | ||
115 | uint32_t uPrevBlock, bool bNew ) | ||
116 | { | ||
117 | Block b = { uPos, blockUnused, uPrevBlock, 0, 0, { } }; | ||
118 | if( uFirstBlock != blockUnused ) | ||
119 | b.uFirstBlock = uFirstBlock; | ||
120 | bsBlockUsed.setBit( uPos ); | ||
121 | sStore.setPos( iBlockStart+(iBlockSize*uPos) ); | ||
122 | sStore.write( &b, sizeof(Block) ); | ||
123 | if( bNew ) | ||
124 | { | ||
125 | // It's a new one, at the end, write some zeros. | ||
126 | int iSize = iBlockSize-sizeof(Block); | ||
127 | char *buf = new char[iSize]; | ||
128 | memset( buf, 0, iSize ); | ||
129 | sStore.write( buf, iSize ); | ||
130 | delete[] buf; | ||
131 | } | ||
132 | } | ||
133 | |||
107 | uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, | 134 | uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, |
108 | int /*iPreAllocate*/ ) | 135 | int /*iPreAllocate*/ ) |
109 | { | 136 | { |
@@ -111,16 +138,15 @@ uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, | |||
111 | { | 138 | { |
112 | if( !bsBlockUsed.getBit( j ) ) | 139 | if( !bsBlockUsed.getBit( j ) ) |
113 | { | 140 | { |
114 | Block b = { j, blockUnused, uPrevBlock, 0, 0, { } }; | 141 | initBlock( j, uFirstBlock, uPrevBlock ); |
115 | if( uFirstBlock != blockUnused ) | ||
116 | b.uFirstBlock = uFirstBlock; | ||
117 | bsBlockUsed.setBit( j ); | ||
118 | sStore.setPos( iBlockStart+(iBlockSize*j) ); | ||
119 | sStore.write( &b, sizeof(b) ); | ||
120 | return j; | 142 | return j; |
121 | } | 143 | } |
122 | } | 144 | } |
123 | return blockUnused; | 145 | // Oh, we don't have any blocks left...allocate a new one. |
146 | iBlocks++; | ||
147 | bsBlockUsed.setSize( iBlocks, false ); | ||
148 | initBlock( iBlocks-1, uFirstBlock, uPrevBlock, true ); | ||
149 | return iBlocks-1; | ||
124 | } | 150 | } |
125 | 151 | ||
126 | int Bu::Nids::createStream( int iPreAllocate ) | 152 | int Bu::Nids::createStream( int iPreAllocate ) |
@@ -169,15 +195,22 @@ void Bu::Nids::updateStreamSize( uint32_t uIndex, uint32_t uSize ) | |||
169 | } | 195 | } |
170 | 196 | ||
171 | uint32_t Bu::Nids::getNextBlock( uint32_t uIndex, | 197 | uint32_t Bu::Nids::getNextBlock( uint32_t uIndex, |
172 | struct Bu::Nids::Block *pBlock ) | 198 | struct Bu::Nids::Block *pBlock, bool bCreate ) |
173 | { | 199 | { |
174 | uint32_t uNew; | 200 | uint32_t uNew; |
175 | if( pBlock->uNextBlock == blockUnused ) | 201 | if( pBlock->uNextBlock == blockUnused ) |
176 | { | 202 | { |
177 | uNew = createBlock( pBlock->uFirstBlock, uIndex ); | 203 | if( bCreate ) |
178 | sStore.setPos( iBlockStart + (iBlockSize*uIndex)+1*4 ); | 204 | { |
179 | sStore.write( &uNew, 4 ); | 205 | uNew = createBlock( pBlock->uFirstBlock, uIndex ); |
180 | getBlock( uNew, pBlock ); | 206 | sStore.setPos( iBlockStart + (iBlockSize*uIndex)+1*4 ); |
207 | sStore.write( &uNew, 4 ); | ||
208 | getBlock( uNew, pBlock ); | ||
209 | } | ||
210 | else | ||
211 | { | ||
212 | throw Bu::NidsException("Reached end of stream."); | ||
213 | } | ||
181 | } | 214 | } |
182 | else | 215 | else |
183 | { | 216 | { |