/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ ////////////////////////////////////////////////////////////////////////////// // // plRawPageAccessor - Dangerous little class that lets you take a // plRegistryPageNode and load the objects in raw (i.e. // as block memory buffers). // This should NOT be used in any normal app, only // utility apps that don't want to load objects in // normally (which basically means if you're not mcn, // don't use this!) // //// Why We're Bad /////////////////////////////////////////////////////////// // // To store all the raw buffers, we stuff them as pointers into the keys // themselves. This is Way Bad(tm) because those pointers are expecting // hsKeyedObjects, and what we're giving them certainly ain't those. // This is why it's only safe to use this class in a very small, controlled // environment, one where we know the keys won't be accessed in a normal // fashion so we know nobody will try to use our pointers in a bad way. // ////////////////////////////////////////////////////////////////////////////// #include "hsTypes.h" #include "hsStream.h" #include "hsResMgr.h" #include "plRawKeyedObject.h" #include "../pnKeyedObject/plKeyImp.h" //// Tiny Yet Now Famous Key Hack //////////////////////////////////////////// class plPublicKeyImp : public plKeyImp { public: void SetObjectPtrDirect( hsKeyedObject *obj ) { fObjectPtr = obj; } void SetAsEmpty( void ) { fStartPos = (UInt32)-1; fDataLen = (UInt32)-1; } void SetStartPosFromStream( hsStream *stream ) { fStartPos = stream->GetPosition(); } void SetLengthFromStream( hsStream *stream ) { fDataLen = stream->GetPosition() - fStartPos; } }; //// Constructor/Destructor ////////////////////////////////////////////////// plRawKeyedObject::plRawKeyedObject() { fSrcKey = nil; fBuffer = nil; fBufferSize = 0; } plRawKeyedObject::plRawKeyedObject( const plKey &key, UInt32 size, UInt8 *data ) { fSrcKey = key; ( (plPublicKeyImp *)(plKeyImp *)key )->SetObjectPtrDirect( this ); fBuffer = nil; fBufferSize = 0; SetBuffer( size, data ); } plRawKeyedObject::~plRawKeyedObject() { if( fSrcKey != nil ) { ( (plPublicKeyImp *)(plKeyImp *)fSrcKey )->SetObjectPtrDirect( nil ); fSrcKey = nil; } delete [] fBuffer; } void plRawKeyedObject::SetBuffer( UInt32 size, UInt8 *data ) { delete [] fBuffer; if( data == nil ) { fBufferSize = 0; fBuffer = nil; return; } fBufferSize = size; fBuffer = new UInt8[ size ]; memcpy( fBuffer, data, size ); } void plRawKeyedObject::SetKey( plKey k ) { if( fSrcKey != nil ) { ( (plPublicKeyImp *)(plKeyImp *)fSrcKey )->SetObjectPtrDirect( nil ); } fSrcKey = k; if( fSrcKey != nil ) { ( (plPublicKeyImp *)(plKeyImp *)fSrcKey )->SetObjectPtrDirect( this ); } } void plRawKeyedObject::MarkAsEmpty( plKey &key ) { ( (plPublicKeyImp *)(plKeyImp *)key )->SetAsEmpty(); } void plRawKeyedObject::Write( hsStream *stream ) { // BEFORE we write out, somewhere at the top of our buffer is the key to ourselves // that all hsKeyedObjects write out as part of their Write() function. We need // to REPLACE that key with our new key, since our location has now changed. Note // that this will ONLY work if our location changes, NOT if our name changes, // because we're relying on the fact that the written size of our key is not // going to change!!! { hsWriteOnlyStream replaceStream( fBufferSize, fBuffer ); // Here's the part that REALLY sucks, 'cause it assumes our written format will never change!!!! // It ALSO assumes, VERY dangerously, that ReadSwap16() will ALWAYS read a size UInt16 replaceStream.SetPosition( sizeof( UInt16 ) ); // Get past creatable class that resManager writes out hsgResMgr::ResMgr()->WriteKey( &replaceStream, fSrcKey, hsResMgr::kWriteNoCheck ); } ( (plPublicKeyImp *)(plKeyImp *)fSrcKey )->SetStartPosFromStream( stream ); stream->Write( fBufferSize, fBuffer ); ( (plPublicKeyImp *)(plKeyImp *)fSrcKey )->SetLengthFromStream( stream ); } //// Warning Stubs /////////////////////////////////////////////////////////// void plRawKeyedObject::Validate() { hsAssert( false, "Invalid call on plRawKeyedObject" ); } hsBool plRawKeyedObject::IsFinal() { hsAssert( false, "Invalid call on plRawKeyedObject" ); return false; } void plRawKeyedObject::Read(hsStream *s, hsResMgr *mgr ) { hsAssert( false, "Invalid call on plRawKeyedObject" ); } void plRawKeyedObject::Write(hsStream *s, hsResMgr *mgr ) { hsAssert( false, "Invalid call on plRawKeyedObject" ); } hsBool plRawKeyedObject::MsgReceive( plMessage *msg ) { hsAssert( false, "Invalid call on plRawKeyedObject" ); return false; } hsKeyedObject *plRawKeyedObject::GetSharedObject() { hsAssert( false, "Invalid call on plRawKeyedObject" ); return nil; }