aboutsummaryrefslogtreecommitdiff
path: root/src/nids.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-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 {