diff options
author | Mike Buland <eichlan@xagasoft.com> | 2008-10-08 16:17:26 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2008-10-08 16:17:26 +0000 |
commit | 3f1c8998166466245aee2860197fb4908e55f1a2 (patch) | |
tree | b6d148679bbd87125f03cb723d5b59969b90c733 /src/nids.cpp | |
parent | 5883662909051e99093514483c32e2539a3cf850 (diff) | |
download | libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.tar.gz libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.tar.bz2 libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.tar.xz libbu++-3f1c8998166466245aee2860197fb4908e55f1a2.zip |
Ok...corrected a problem with new block allocation in nids, and it no longer
goes into an infinite loop while doing certain kinds of read. Also, it zeros
out new blocks to make things easier to cope with in the hex editor, it'll
probably also compress better.
I also fixed Bu::MemBuf so that you can now write to arbitrary places
mid-stream.
Diffstat (limited to '')
-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 | { |