// // 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. // /////////////////////////////////////////////////////////////////////////////// // hierdbnode.h // // these classes are used by cHierDatabase as the nodes in the hierarchy // #ifndef __HIERDBNODE_H #define __HIERDBNODE_H #ifndef __TYPES_H #include "types.h" #endif #ifndef __ARCHIVE_H #include "archive.h" #endif /////////////////////////// // BIG TODO -- I need to change all of these strings to be wchar_t instead of TSTRINGS // Also, they should serialize themselves in a platform-neutral byte order /////////////////////////// //----------------------------------------------------------------------------- // cHierNode -- the base class for all other nodes; this class contains type // information //----------------------------------------------------------------------------- class cHierNode { public: enum Type { TYPE_INVALID = -1, TYPE_MIN = 0, TYPE_ROOT = 1, TYPE_ENTRY, TYPE_ARRAY, TYPE_ARRAY_INFO, TYPE_MAX }; cHierNode( Type type = TYPE_INVALID ) : mType( type ) {} virtual ~cHierNode() {} int32 mType; ///////////////////////////////////////// // methods to override ///////////////////////////////////////// virtual int32 CalcArchiveSize() const { return ( sizeof(mType) ); } // this method should return the amount of space that this class will take up in an archive // derived classes should override this if they have any data members that will be stored // with Read() or Write() virtual void Write ( cArchive& arch ) const //throw(eArchive) { arch.WriteInt32( mType ); } virtual void Read ( cArchive& arch ) //throw(eArchive) { arch.ReadInt32( mType ); // // do a rudimentary integrity check... // if( (mType <= TYPE_MIN) || (mType >= TYPE_MAX) ) { ASSERT( false ); throw eArchiveFormat( _T("Invalid type encountered in cHierNode::Read") ); } } // these methods read and write the class to an archive. We had better be sure that // we don't write more than we said we would in CalcArchiveSize() ! }; //----------------------------------------------------------------------------- // cHierAddr -- the "address" of different items in the hierarchy //----------------------------------------------------------------------------- class cHierAddr { public: int32 mBlockNum; int32 mIndex; cHierAddr( int32 block = -1, int32 index = -1 ) : mBlockNum( block ), mIndex( index ) {} bool IsNull() const { return (mBlockNum == -1); } // returns true if the address points to "null" (ie -- no valid address) bool operator==( const cHierAddr& rhs ) const { return( (mBlockNum == rhs.mBlockNum) && (mIndex == rhs.mIndex) ); } ///////////////////////////////////////////////// // serialization methods ///////////////////////////////////////////////// int32 CalcArchiveSize () const { return ( sizeof(mBlockNum) + sizeof(mIndex) ); } void Write( cArchive& arch ) const //throw(eArchive) { arch.WriteInt32( mBlockNum ); arch.WriteInt32( mIndex ); } void Read( cArchive& arch ) //throw(eArchive) { arch.ReadInt32 ( mBlockNum ); arch.ReadInt32 ( mIndex ); } }; //----------------------------------------------------------------------------- // cHierRoot -- the root of the hierarchy; you can always count on this being // at (0, 0) //----------------------------------------------------------------------------- class cHierRoot : public cHierNode { public: cHierRoot() : cHierNode( TYPE_ROOT ), mbCaseSensitive(true), mDelimitingChar('/') {} cHierAddr mChild; // points to a cHierArray or an invalid address bool mbCaseSensitive; // determines the case-sensitiveness of lookups, ordering, etc. TCHAR mDelimitingChar; // the delimiting character; this is used when displaying a path to the user ///////////////////////////////////////////////// // serialization methods ///////////////////////////////////////////////// virtual int32 CalcArchiveSize() const { return ( cHierNode::CalcArchiveSize() + mChild.CalcArchiveSize() ); } virtual void Write ( cArchive& arch ) const //throw(eArchive) { cHierNode::Write ( arch ); mChild.Write ( arch ); arch.WriteInt32 ( mbCaseSensitive ? 1 : 0 ); TSTRING dc ( &mDelimitingChar, 1 ); arch.WriteString ( dc ); } virtual void Read ( cArchive& arch ) //throw(eArchive) { cHierNode::Read ( arch ); // // make sure the type is correct // if( mType != TYPE_ROOT ) { ASSERT( false ); throw eArchiveFormat( _T("Invalid type encountered; expected ROOT node") ); } mChild.Read ( arch ); int32 cs; arch.ReadInt32(cs); mbCaseSensitive = cs ? true : false; TSTRING dc; arch.ReadString(dc); if( dc.length() != 1 ) { ASSERT( false ); throw eArchiveFormat( _T("Read of the root node failed; invalid delimiting character.") ); } mDelimitingChar = dc[0]; } }; //----------------------------------------------------------------------------- // cHierEntry -- an entry that contains a name and points to some data //----------------------------------------------------------------------------- class cHierEntry : public cHierNode { public: cHierEntry() : cHierNode( TYPE_ENTRY ) {} TSTRING mName; // TODO -- change this to a wchar_t string cHierAddr mData; cHierAddr mChild; // points to a cHierArray or an invalid address cHierAddr mNext; // the next peer entry in the linked list, or Null() if done ///////////////////////////////////////////////// // serialization methods ///////////////////////////////////////////////// virtual int32 CalcArchiveSize() const { return ( cHierNode::CalcArchiveSize() + mChild.CalcArchiveSize() + mData.CalcArchiveSize() + cArchive::GetStorageSize( mName ) + mNext.CalcArchiveSize() ); } virtual void Write ( cArchive& arch ) const //throw(eArchive) { cHierNode::Write( arch ); arch.WriteString( mName ); mChild.Write ( arch ); mData.Write ( arch ); mNext.Write ( arch ); } virtual void Read ( cArchive& arch ) //throw(eArchive) { cHierNode::Read ( arch ); // // make sure the type is correct // if( mType != TYPE_ENTRY ) { ASSERT( false ); throw eArchiveFormat( _T("Invalid type encountered; expected ENTRY node") ); } arch.ReadString ( mName ); mChild.Read ( arch ); mData.Read ( arch ); mNext.Read ( arch ); } }; //----------------------------------------------------------------------------- // cHierArrayInfo -- constant-size struct that contains information about an array //----------------------------------------------------------------------------- class cHierArrayInfo : public cHierNode { public: cHierArrayInfo() : cHierNode( TYPE_ARRAY_INFO ) {} cHierAddr mParent; // points to a cHierArrayInfo or cHierRoot cHierAddr mArray; // points to cHierEntryArray ///////////////////////////////////////////////// // serialization methods ///////////////////////////////////////////////// virtual int32 CalcArchiveSize() const { return (cHierNode::CalcArchiveSize() + mParent.CalcArchiveSize() + mArray.CalcArchiveSize()); } virtual void Write ( cArchive& arch ) const //throw(eArchive) { cHierNode::Write( arch ); mParent.Write ( arch ); mArray.Write ( arch ); } virtual void Read ( cArchive& arch ) //throw(eArchive) { cHierNode::Read ( arch ); // // make sure the type is correct // if( mType != TYPE_ARRAY_INFO ) { ASSERT( false ); throw eArchiveFormat( _T("Invalid type encountered; expected TYPE_ARRAY_INFO node") ); } mParent.Read ( arch ); mArray.Read ( arch ); } }; #endif //__HIERDBNODE_H