// // The developer of the original code and/or files is Tripwire, Inc. // Portions created by Tripwire, Inc. are copyright (C) 2000 Tripwire, // Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights // reserved. // // This program is free software. The contents of this file are subject // to the terms of the GNU General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your // option) any later version. You may redistribute it and/or modify it // only in compliance with the GNU General Public License. // // This program is distributed in the hope that it will be useful. // However, this program is distributed AS-IS WITHOUT ANY // WARRANTY; INCLUDING THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS // FOR A PARTICULAR PURPOSE. Please see the GNU General Public License // for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, // USA. // // Nothing in the GNU General Public License or any other license to use // the code or files shall permit you to use Tripwire's trademarks, // service marks, or other intellectual property without Tripwire's // prior written consent. // // If you have any questions, please contact Tripwire, Inc. at either // info@tripwire.org or www.tripwire.org. // /////////////////////////////////////////////////////////////////////////////// // block.h // #ifndef __BLOCK_H #define __BLOCK_H #ifndef __ARCHIVE_H #include "core/archive.h" #endif #ifndef __DEBUG_H #include "core/debug.h" #endif //----------------------------------------------------------------------------- // cBlock //----------------------------------------------------------------------------- template class cBlock { public: enum { INVALID_NUM = -1 }; cBlock(); void SetDirty () { mbDirty = true; } bool IsDirty () const { return mbDirty; } int GetBlockNum () const { return mBlockNum; } int8* GetData() { return mpData; } bool AssertValid() const; // this asserts and returns false if the guard bytes have been corrupted bool IsValidAddr(int8* pAddr) const; // returns true if pAddr falls within mpData protected: enum { NUM_GUARD_BLOCKS = 8, // associated with BYTE_ALIGN: see ctor for info GUARD_BLOCK_VAL = 0xAB }; // odd, non-zero value for debugging // guardMin and guardMax are used to detect bad writes uint8 mGuardMin[NUM_GUARD_BLOCKS]; int8 mpData[SIZE]; uint8 mGuardMax[NUM_GUARD_BLOCKS]; bool mbDirty; int mBlockNum; }; /////////////////////////////////////////////////////////////////////////////// // ctor /////////////////////////////////////////////////////////////////////////////// template inline cBlock::cBlock() : mbDirty (false), mBlockNum (cBlock::INVALID_NUM) { // To prevent misaligned memory access, the size of the data and the // number of guard blocks must be a multiple of the byte alignment // and they both must be at least as large as the byte alignment ASSERT( 0 == ( SIZE % BYTE_ALIGN ) ); ASSERT( 0 == ( NUM_GUARD_BLOCKS % BYTE_ALIGN ) ); ASSERT( SIZE >= BYTE_ALIGN ); ASSERT( NUM_GUARD_BLOCKS >= BYTE_ALIGN ); // init guard blocks to dummy value for( int i = 0; i < NUM_GUARD_BLOCKS; i++ ) { mGuardMin[i] = (uint8)GUARD_BLOCK_VAL; mGuardMax[i] = (uint8)GUARD_BLOCK_VAL; } // zero out memory memset( mpData, 0, SIZE ); } /////////////////////////////////////////////////////////////////////////////// // ctor /////////////////////////////////////////////////////////////////////////////// template inline bool cBlock::AssertValid() const { // determine if guard bites have been accidentally overwritten for( int i = 0; i < NUM_GUARD_BLOCKS; i++ ) { if( ( mGuardMin[i] != (uint8) GUARD_BLOCK_VAL ) || ( mGuardMax[i] != (uint8) GUARD_BLOCK_VAL ) ) { ASSERT( false ); return false; } } return true; } template inline bool cBlock::IsValidAddr(int8* pAddr) const { return ( (pAddr >= &mpData[0]) && (pAddr <= &mpData[SIZE-1]) ); } //----------------------------------------------------------------------------- // cBlockImpl //----------------------------------------------------------------------------- template class cBlockImpl : public cBlock { public: enum { INVALID_NUM = -1 }; cBlockImpl(); void SetBlockNum ( int blockNum ) { cBlock::mBlockNum = blockNum; } void SetTimestamp( uint32 timestamp ) { mTimestamp = timestamp; } uint32 GetTimestamp() const { return mTimestamp; } void Write ( cBidirArchive& arch ); //throw( eArchive ) void Read ( cBidirArchive& arch, int blockNum = INVALID_NUM ); //throw( eArchive ) // if blockNum is INVALID_NUM, then it reads in the current block number protected: uint32 mTimestamp; }; /////////////////////////////////////////////////////////////////////////////// // ctor /////////////////////////////////////////////////////////////////////////////// template inline cBlockImpl::cBlockImpl() : cBlock ( ), mTimestamp (0) { } /////////////////////////////////////////////////////////////////////////////// // Write /////////////////////////////////////////////////////////////////////////////// template inline void cBlockImpl::Write( cBidirArchive& arch ) //throw( eArchive ) { ASSERT( mbDirty ); ASSERT( (mBlockNum >= 0) && (((mBlockNum + 1) * SIZE) <= arch.Length()) ); arch.Seek ( (cBlock::mBlockNum * SIZE), cBidirArchive::BEGINNING ); arch.WriteBlob ( cBlock::mpData, SIZE ); cBlock::mbDirty = false; } /////////////////////////////////////////////////////////////////////////////// // Read /////////////////////////////////////////////////////////////////////////////// template inline void cBlockImpl::Read( cBidirArchive& arch, int blockNum ) //throw( eArchive ) { if( blockNum != INVALID_NUM ) cBlock::mBlockNum = blockNum; ASSERT( (mBlockNum >= 0) && (((mBlockNum + 1) * SIZE) <= arch.Length()) ); // std::cout << "cBlockImpl::Read() mBlockNum = " << mBlockNum << " arch.Length() = " << arch.Length() << std::endl; arch.Seek ( (cBlock::mBlockNum * SIZE), cBidirArchive::BEGINNING ); arch.ReadBlob ( cBlock::mpData, SIZE ); cBlock::mbDirty = false; } #endif