wvsettings20/IMPSSrc/IMPSSAPObjectHandler.cpp
changeset 0 094583676ce7
--- /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