diff options
Diffstat (limited to 'src/nids.cpp')
| -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 | |||
