--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wvsettings20/IMPSSrc/IMPSSAPObjectHandler.cpp Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,258 @@
+/*
+* Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Object handler implementation
+*
+*/
+
+// INCLUDES
+#include "IMPSSAPObjectHandler.h"
+#include <s32mem.h>
+
+// size to use if the source object size is 0 in copy
+const TInt KTargetObjectSize = 200;
+
+// ================= LOCAL FUNCTIONS =======================
+
+// -----------------------------------------------------------------------------
+// ImplementationVersionsLeft()
+// -----------------------------------------------------------------------------
+//
+TBool ImplementationVersionsLeft( const MIMPSSapObject& aObj, TInt aVersionID )
+ {
+ return ( aVersionID < aObj.ObjectVersion() );
+ }
+
+
+// -----------------------------------------------------------------------------
+// WriteZeroVersionMarkL()
+// -----------------------------------------------------------------------------
+//
+TStreamPos WriteZeroExtensionMarkL( RWriteStream& aStream )
+ {
+ //Write extension mark & return its position
+ TStreamPos extMarkPos = aStream.Sink()->TellL( MStreamBuf::EWrite );
+ aStream.WriteInt32L( 0 ); //Zero length extension
+ return extMarkPos;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// PatchVersionMarkL()
+// -----------------------------------------------------------------------------
+//
+void PatchExtensionMarkL( const TStreamPos& aExtMarkPos,
+ RWriteStream& aStream,
+ TInt aExtensionLength )
+ {
+ aStream.Sink()->SeekL( MStreamBuf::EWrite, aExtMarkPos );
+ aStream.WriteInt32L( aExtensionLength );
+ }
+
+
+// -----------------------------------------------------------------------------
+// ReadExtensionMarkL()
+// -----------------------------------------------------------------------------
+//
+TInt ReadExtensionMarkL( RReadStream& aStream )
+ {
+ return aStream.ReadInt32L();
+ }
+
+
+// -----------------------------------------------------------------------------
+// ExternalizeVersionL()
+// -----------------------------------------------------------------------------
+//
+TInt ExternalizeVersionL( const MIMPSSapObject& aObj, TInt aVersionID, RWriteStream& aStream )
+ {
+ TStreamPos versionStartPos = aStream.Sink()->TellL( MStreamBuf::EWrite );
+
+ //Write version data & zero extension mark
+ aObj.ExternalizeVersionDataL( aVersionID, aStream );
+ TStreamPos extMarkPos = WriteZeroExtensionMarkL( aStream );
+
+ //Calculate version length
+ TInt extensionLength = 0;
+ TInt versionLenght = aStream.Sink()->TellL( MStreamBuf::EWrite ) -
+ versionStartPos;
+
+
+ //Recurse to next version if needed & patch
+ //the extension mark to contain cumulative length
+ //all data stored during recursion
+ if ( ImplementationVersionsLeft( aObj, aVersionID ) )
+ {
+ extensionLength = ExternalizeVersionL( aObj, ++aVersionID, aStream );
+ PatchExtensionMarkL( extMarkPos, aStream, extensionLength );
+ }
+
+
+ return versionLenght + extensionLength;
+ }
+
+
+// -----------------------------------------------------------------------------
+// InternalizeVersionL()
+// -----------------------------------------------------------------------------
+//
+void InternalizeVersionL( MIMPSSapObject& aObj,
+ TInt aVersionID,
+ RReadStream& aStream )
+ {
+ //Three cases:
+ // 1. Stream has same versions than implementaion.
+ // 2. Stream is missing data version compared to the implementation.
+ // 3. Stream has higher data version than implementation supports.
+
+ aObj.InternalizeVersionDataL( aVersionID, aStream );
+
+ TInt extensionLength = ReadExtensionMarkL( aStream );
+
+ //Proceed if stream has subsequent extensions
+ if ( extensionLength > 0 )
+ {
+ if ( ImplementationVersionsLeft( aObj, aVersionID ) )
+ {
+ //Current implementation is capable to read more versions
+ //==> recurse to next one
+ InternalizeVersionL( aObj, ++aVersionID, aStream );
+ }
+ else
+ {
+ //Implementation isn't capable to read more version
+ //==> consume remaining extension blocks
+ aStream.ReadL( extensionLength );
+ }
+ }
+ }
+
+
+
+
+
+
+
+// ================= MEMBER FUNCTIONS =======================
+
+
+
+
+// -----------------------------------------------------------------------------
+// IMPSSAPObjectHandler::DataSize()
+// -----------------------------------------------------------------------------
+//
+TInt IMPSSAPObjectHandler::DataSize( const MIMPSSapObject& aObj )
+ {
+ // Object id: 4 bytes
+ // Object version: 4 bytes
+ TInt dataSize = 8;
+
+
+ //For each version: version extension mark, 4 bytes
+ TInt versionCount = aObj.ObjectVersion() - KIMPSSapObjVersionInitial;
+ dataSize += ( versionCount * 4 );
+
+
+ //and actual data size
+ dataSize += aObj.DataSize();
+
+
+ return dataSize;
+ }
+
+
+
+// -----------------------------------------------------------------------------
+// IMPSSAPObjectHandler::ExternalizeL()
+// -----------------------------------------------------------------------------
+//
+void IMPSSAPObjectHandler::ExternalizeL( const MIMPSSapObject& aObj,
+ RWriteStream& aStream )
+ {
+ //Externalize object ID's
+ aStream.WriteInt32L( aObj.ObjectID() );
+ aStream.WriteInt32L( aObj.ObjectVersion() );
+
+
+ TStreamPos pos = aStream.Sink()->TellL( MStreamBuf::EWrite );
+
+ //Recursively go through all data versions
+ TInt length = ExternalizeVersionL( aObj, KIMPSSapObjVersionInitial, aStream );
+
+ //And correct the stream write point
+ aStream.Sink()->SeekL( MStreamBuf::EWrite, ( pos + length ) );
+ }
+
+
+// -----------------------------------------------------------------------------
+// IMPSSAPObjectHandler::InternalizeL()
+// -----------------------------------------------------------------------------
+//
+void IMPSSAPObjectHandler::InternalizeL( MIMPSSapObject& aObj, RReadStream& aStream )
+ {
+ aObj.Reset();
+
+ //Object ID
+ TIMPSSapObjectID id = static_cast<TIMPSSapObjectID> ( aStream.ReadInt32L() );
+ if ( id != aObj.ObjectID() )
+ {
+ User::Leave( KErrCorrupt );
+ }
+
+ //Object version
+ aStream.ReadInt32L();
+
+ //and recursively go through all available version datas
+ InternalizeVersionL( aObj, KIMPSSapObjVersionInitial, aStream );
+ }
+
+
+// -----------------------------------------------------------------------------
+// IMPSSAPObjectHandler::CopyL()
+// -----------------------------------------------------------------------------
+//
+void IMPSSAPObjectHandler::CopyL( const MIMPSSapObject& aSource, MIMPSSapObject& aTarget )
+ {
+ //Don't check here object ID's because underlying stream
+ //implementations might be capable to convert objects to another
+
+ TInt objectSize = IMPSSAPObjectHandler::DataSize( aSource );
+ if ( objectSize == 0 )
+ {
+ objectSize = KTargetObjectSize;
+ }
+
+ CBufSeg* buffer = CBufSeg::NewL( objectSize );
+ CleanupStack::PushL( buffer );
+
+ RBufWriteStream wstream;
+ wstream.Open( *buffer );
+ CleanupClosePushL( wstream );
+
+ IMPSSAPObjectHandler::ExternalizeL( aSource, wstream );
+ CleanupStack::PopAndDestroy(); //wstream
+
+ RBufReadStream rstream;
+ rstream.Open( *buffer );
+ CleanupClosePushL( rstream );
+
+ IMPSSAPObjectHandler::InternalizeL( aTarget, rstream );
+
+ CleanupStack::PopAndDestroy( 2 ); //rstream, buffer
+ }
+
+
+
+// End of File