summaryrefslogtreecommitdiff
path: root/src/nids.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2008-10-08 16:17:26 +0000
committerMike Buland <eichlan@xagasoft.com>2008-10-08 16:17:26 +0000
commit3f1c8998166466245aee2860197fb4908e55f1a2 (patch)
treeb6d148679bbd87125f03cb723d5b59969b90c733 /src/nids.cpp
parent5883662909051e99093514483c32e2539a3cf850 (diff)
downloadlibbu++-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 'src/nids.cpp')
-rw-r--r--src/nids.cpp115
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
45Bu::Nids::~Nids() 28Bu::Nids::~Nids()
@@ -49,6 +32,7 @@ Bu::Nids::~Nids()
49void Bu::Nids::initialize() 32void 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
63void Bu::Nids::initialize( int iBlockSize, int iPreAllocate ) 70void 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
114void 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
107uint32_t Bu::Nids::createBlock( uint32_t uFirstBlock, uint32_t uPrevBlock, 134uint32_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
126int Bu::Nids::createStream( int iPreAllocate ) 152int Bu::Nids::createStream( int iPreAllocate )
@@ -169,15 +195,22 @@ void Bu::Nids::updateStreamSize( uint32_t uIndex, uint32_t uSize )
169} 195}
170 196
171uint32_t Bu::Nids::getNextBlock( uint32_t uIndex, 197uint32_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 {