--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/skins/AknSkins/srvsrc/AknsSrvChunkMaintainer2.cpp Thu Dec 17 09:14:12 2009 +0200
@@ -0,0 +1,560 @@
+/*
+* Copyright (c) 2005-2008 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: Extension to chunk maintainer.
+*
+*/
+
+
+#include "AknsSrvChunkMaintainer.h"
+
+#include "AknsSrvUtils.h"
+#include "AknsSrvDescriptorFileLayout.h"
+
+#include "AknsDebug.h"
+
+// CONSTANTS
+
+// Max of 32 effects per queue and 64 params per effect should be enough
+static const TInt KAknsSrvMaxEffectCount = 0x20;
+static const TInt KAknsSrvMaxParamGroupCount = 0x20;
+static const TInt KAknsSrvMaxEffectParamCount = 0x40;
+
+/**
+* A wrapper class for RPointerArray cleanup.
+*/
+NONSHARABLE_CLASS( CAknsSrvArrayStore ): public CBase
+ {
+ public:
+ CAknsSrvArrayStore()
+ {}
+
+ ~CAknsSrvArrayStore()
+ {
+ while( iArray.Count() )
+ {
+ delete [] iArray[0];
+ iArray.Remove(0);
+ }
+ iArray.Reset();
+ }
+
+ public:
+ RPointerArray<TUint8> iArray;
+ };
+
+// -----------------------------------------------------------------------------
+// CAknsSrvChunkMaintainer::DoMergeEffectQueueL
+// -----------------------------------------------------------------------------
+//
+void CAknsSrvChunkMaintainer::DoMergeEffectQueueL(
+ CAknsSrvFileBuffer& aFile, const TUint aOffset,
+ const TAknsItemDefClass /*aClass*/,
+ const TAknsSrvExclusionQuery& aExclQuery, const TBool /*aAhOverride*/ )
+ {
+ TAknsSrvDef itemDef;
+ TInt32 major = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueMajor );
+ TInt32 minor = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueMinor );
+ TInt32 refmajor = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueRefMajor );
+ TInt32 refminor = AknsSrvUtils::GetInt32L( aFile, aOffset+EAknsSrvDFOEffectQueueRefMinor );
+ TUint8 inputlayerindex = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueInputLayerIndex);
+ TUint8 inputlayermode = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueInputLayerMode);
+ TUint8 outputlayerindex = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueOutputLayerIndex);
+ TUint8 outputlayermode = AknsSrvUtils::GetUInt8L( aFile, aOffset + EAknsSrvDFOEffectQueueOutputLayerMode);
+
+ TUint16 effectcount = AknsSrvUtils::GetUInt16L( aFile, aOffset + EAknsSrvDFOEffectQueueEffectCount);
+
+ if( inputlayermode > 0x08 ||
+ outputlayermode > 0x08 ||
+ effectcount > KAknsSrvMaxEffectCount )
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ TUint32 size = 0;
+ itemDef.iID.Set(major,minor);
+
+ if( aExclQuery.IsExcluded( itemDef.iID ) )
+ {
+ return;
+ }
+
+ CheckAndModifyIID( itemDef.iID, aExclQuery );
+
+ itemDef.iType = EAknsITEffectQueue;
+
+ if (refmajor && refminor)
+ {
+ TAknsSrvEffectQueueDef eq;
+ eq.iEffectQueueSize = sizeof(TAknsSrvEffectQueueDef);
+ eq.iEffectCount = 0;
+ eq.iRefMajor = refmajor;
+ eq.iRefMinor = refminor;
+ UpdateDef(&itemDef,&eq,sizeof(TAknsSrvEffectQueueDef),-1);
+ return;
+ }
+
+ CAknsSrvArrayStore* effectArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( effectArray );
+
+ TUint32 eqBase = EAknsSrvDFOEffectQueueEffects;
+ TUint32 totalEffectSize = 0;
+
+ // process all effect chunks inside
+ totalEffectSize = DoMergeEffectCommandsL( aFile, aOffset, eqBase, effectArray->iArray, effectcount );
+
+ // All effects collected, add them to the queue
+ TUint8* eqBlock = new (ELeave) TUint8[sizeof(TAknsSrvEffectQueueDef)+totalEffectSize];
+ // No leaves after this
+
+ TAknsSrvEffectQueueDef* eqDef = (TAknsSrvEffectQueueDef*)eqBlock;
+ eqDef->iEffectCount = effectcount;
+ eqDef->iRefMinor = 0;
+ eqDef->iRefMajor = 0;
+ eqDef->iInputLayerIndex = inputlayerindex;
+ eqDef->iInputLayerMode = inputlayermode;
+ eqDef->iOutputLayerIndex = outputlayerindex;
+ eqDef->iOutputLayerMode = outputlayermode;
+ TUint32 base = sizeof(TAknsSrvEffectQueueDef);
+
+ for (TInt ecount = 0; ecount < effectcount; ecount++)
+ {
+ TAknsSrvEffectDef* effectDef = (TAknsSrvEffectDef*)(effectArray->iArray[ecount]);
+ size = effectDef->iEffectSize;
+ Mem::Copy(eqBlock+base, effectDef, size);
+ base+=size;
+ }
+ eqDef->iEffectQueueSize = sizeof(TAknsSrvEffectQueueDef)+totalEffectSize;
+
+ CleanupStack::PopAndDestroy( effectArray ); // effectArray
+
+ UpdateDef( &itemDef, eqDef, sizeof(TAknsSrvEffectQueueDef)+totalEffectSize, -1 );
+ delete [] eqBlock;
+
+ // Leaves ok as eqBlock has been deleted
+ }
+
+// -----------------------------------------------------------------------------
+// CAknsSrvChunkMaintainer::DoMergeParamL
+// -----------------------------------------------------------------------------
+//
+TUint32 CAknsSrvChunkMaintainer::DoMergeParamsL(
+ CAknsSrvFileBuffer& aFile, const TUint aOffset, TUint32& aEqBase,
+ RPointerArray<TUint8>& aParamArray, const TUint16 aParamCount )
+ {
+ TUint32 totalparamsize = 0; // total size of all parameters
+ for( TInt i = 0; i < aParamCount; i++ )
+ {
+ TUint16 totalparamlen = AknsSrvUtils::GetUInt16L( aFile, aOffset + aEqBase);
+ TUint32 datasize = totalparamlen-4; //ParamLength(TUint16)-Reserved(TUint8)-ParamType(TUint8)
+
+ // lets assume that one effect cannot be larger than 32kb (should be more than enough)
+ if (datasize >= 0x8000)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ TUint8 ptype = AknsSrvUtils::GetUInt8L(aFile,aOffset+aEqBase+3);
+
+ TUint8* paramBlock = NULL;
+ TAknsSrvEffectParameterDef* paramDef = NULL;
+
+ TUint8* data = AknsSrvUtils::ReadSkinDescL(aFile, aOffset+aEqBase+4, datasize);
+ CleanupStack::PushL(data);
+ if (ptype == 2) // graphics param
+ {
+ TUint32 filenameid = *((TUint32*)(data+datasize-4)) + iCurrentFilenameID;
+ TInt filenameoffset = GetFilenameOffsetByID(filenameid);
+
+ paramBlock = new (ELeave) TUint8[sizeof(TAknsSrvEffectParameterDef)+datasize-4+KAknsSrvMaxFileNameLen-4];
+ CleanupStack::PushL( paramBlock );
+ paramDef = (TAknsSrvEffectParameterDef*)paramBlock;
+ Mem::Copy(paramBlock+sizeof(TAknsSrvEffectParameterDef), data, datasize-4);
+ // Convert filenameid to offset and replace the id with offset
+ Mem::Copy(paramBlock+sizeof(TAknsSrvEffectParameterDef)+datasize-4,&filenameoffset, sizeof(TInt));
+ paramDef->iParameterType = ptype;
+ paramDef->iParameterLength = AlignToFour(sizeof(TAknsSrvEffectParameterDef)+datasize);
+ }
+ else // string or int param or namedref (similar to int, used in animations)
+ {
+ paramBlock = new (ELeave) TUint8[sizeof(TAknsSrvEffectParameterDef)+datasize];
+ CleanupStack::PushL( paramBlock );
+ paramDef = (TAknsSrvEffectParameterDef*)paramBlock;
+ paramDef->iParameterType = ptype;
+ paramDef->iParameterLength = AlignToFour(sizeof(TAknsSrvEffectParameterDef)+datasize);
+ Mem::Copy(paramBlock+sizeof(TAknsSrvEffectParameterDef), data, datasize);
+ }
+
+ totalparamsize += paramDef->iParameterLength;
+ User::LeaveIfError( aParamArray.Append(paramBlock) );
+ CleanupStack::Pop( paramBlock ); // paramBlock
+
+ CleanupStack::PopAndDestroy( data ); // data
+
+ aEqBase += totalparamlen;
+ }
+
+ return totalparamsize;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknsSrvChunkMaintainer::DoMergeParamGroupL
+// -----------------------------------------------------------------------------
+//
+TUint32 CAknsSrvChunkMaintainer::DoMergeParamGroupsL(
+ CAknsSrvFileBuffer& aFile, const TUint aOffset, TUint32& aBase,
+ RPointerArray<TUint8>& aGroupArray, const TUint16 aGroupCount )
+ {
+ TUint32 totalGroupsSize = 0;
+ for( TInt i = 0; i < aGroupCount; i++ )
+ {
+ // Fetch param group header
+ TUint32 valueA = AknsSrvUtils::GetInt32L( aFile, aOffset + aBase + EAknsSrvDFOAnimationParamGroupValueA );
+ TUint32 valueB = AknsSrvUtils::GetInt32L( aFile, aOffset + aBase + EAknsSrvDFOAnimationParamGroupValueB );
+ TUint16 pcount = AknsSrvUtils::GetUInt16L( aFile, aOffset + aBase + EAknsSrvDFOAnimationParamGroupParameterCount );
+
+ if( pcount > KAknsSrvMaxEffectParamCount )
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ // Fetch parameters
+ aBase = aBase + EAknsSrvDFOAnimationParamGroupParameters;
+
+ CAknsSrvArrayStore* paramArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( paramArray );
+ TUint32 totalParamSize = DoMergeParamsL( aFile, aOffset, aBase, paramArray->iArray, pcount );
+
+ // Construct group array block
+ TUint8* block = new(ELeave) TUint8[sizeof(TAknsSrvParamGroupDef) + totalParamSize];
+ CleanupStack::PushL( block );
+ TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)block;
+ def->iValueA = valueA;
+ def->iValueB = valueB;
+
+ // Copy all parameters to the param group
+ TUint32 base = sizeof(TAknsSrvParamGroupDef);
+ for (TInt j = 0; j < pcount; j++)
+ {
+ TAknsSrvEffectParameterDef* paramDef = (TAknsSrvEffectParameterDef*)(paramArray->iArray[j]);
+ TUint32 size = paramDef->iParameterLength;
+ Mem::Copy(block + base, paramDef, size);
+ base+=size;
+ }
+
+ def->iGroupSize = base;
+ def->iParameterCount = pcount;
+ User::LeaveIfError( aGroupArray.Append(block) );
+ CleanupStack::Pop( block );
+
+ CleanupStack::PopAndDestroy( paramArray );
+
+ totalGroupsSize+=base;
+ aBase+=1; // GODDAMN END
+ }
+
+ return totalGroupsSize;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknsSrvChunkMaintainer::DoMergeEffectCommandL
+// -----------------------------------------------------------------------------
+//
+TUint32 CAknsSrvChunkMaintainer::DoMergeEffectCommandsL(
+ CAknsSrvFileBuffer& aFile, const TUint aOffset, TUint32& aBase,
+ RPointerArray<TUint8>& aEffectArray, const TUint16 aEffectCount )
+ {
+ TUint32 totalSize = 0;
+ for( TInt i = 0; i < aEffectCount; i++)
+ {
+ TInt32 effectuid = AknsSrvUtils::GetInt32L( aFile, aOffset+aBase + 8 );
+ TUint8 inAindex = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 12);
+ TUint8 inAmode = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 13);
+ TUint8 inBindex = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 14);
+ TUint8 inBmode = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 15);
+ TUint8 outIndex = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 16);
+ TUint8 outMode = AknsSrvUtils::GetUInt8L( aFile, aOffset+ aBase+ 17);
+
+ // Check that at least some values are meaningful
+ if (inAmode > 0x08 || inBmode > 0x08 || outMode > 0x08 )
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ TUint16 paramcount = AknsSrvUtils::GetUInt16L( aFile, aOffset+ aBase+ 18);
+ if (paramcount > KAknsSrvMaxEffectParamCount)
+ {
+ User::Leave(KErrCorrupt);
+ }
+ aBase+=20;
+
+ // process all parameters inside single effect
+ CAknsSrvArrayStore* paramArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( paramArray );
+ TUint32 totalparamsize = DoMergeParamsL( aFile, aOffset, aBase, paramArray->iArray, paramcount );
+
+ // All data collected
+ TUint8* effectBlock= new (ELeave) TUint8[sizeof(TAknsSrvEffectDef)+totalparamsize];
+ CleanupStack::PushL( effectBlock );
+
+ TAknsSrvEffectDef* effectdef = (TAknsSrvEffectDef*)effectBlock;
+ effectdef->iEffectUid.iUid = effectuid;
+ effectdef->iEffectParameterCount = paramcount;
+ effectdef->iInputLayerAIndex = inAindex;
+ effectdef->iInputLayerAMode = inAmode;
+ effectdef->iInputLayerBIndex = inBindex;
+ effectdef->iInputLayerBMode = inBmode;
+ effectdef->iOutputLayerIndex = outIndex;
+ effectdef->iOutputLayerMode = outMode;
+
+ TUint32 base = sizeof(TAknsSrvEffectDef);
+ TInt pcount;
+ // copy all parameters to the effect
+ for (pcount = 0; pcount < paramArray->iArray.Count(); pcount++)
+ {
+ TAknsSrvEffectParameterDef* paramDef = (TAknsSrvEffectParameterDef*)(paramArray->iArray[pcount]);
+ TUint32 size = paramDef->iParameterLength;
+ Mem::Copy(effectBlock+base, paramDef, size);
+ base+=size;
+ }
+
+ effectdef->iEffectSize = base;
+ User::LeaveIfError( aEffectArray.Append(effectBlock) );
+ CleanupStack::Pop( effectBlock );
+
+ CleanupStack::PopAndDestroy( paramArray );
+
+ totalSize+=base;
+ aBase+=1;// End of commands.
+ }
+
+ return totalSize;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknsSrvChunkMaintainer::DoMergeAnimationL
+// -----------------------------------------------------------------------------
+//
+void CAknsSrvChunkMaintainer::DoMergeAnimationL(
+ CAknsSrvFileBuffer& aFile, const TUint aOffset,
+ const TAknsItemDefClass /*aClass*/,
+ const TAknsSrvExclusionQuery& aExclQuery, const TBool /*aAhOverride*/ )
+ {
+ TAknsSrvDef itemDef;
+ TUint32 size = 0;
+ TUint32 totalSize = 0;
+
+ //---------------------------------
+ // Step 1: Process animation header information
+
+ // Fetch animation header
+ TInt32 major = AknsSrvUtils::GetInt32L(aFile, aOffset+EAknsSrvDFOAnimationMajor);
+ TInt32 minor = AknsSrvUtils::GetInt32L(aFile, aOffset+EAknsSrvDFOAnimationMinor);
+ TUint8 type = AknsSrvUtils::GetUInt8L(aFile, aOffset+EAknsSrvDFOAnimationType);
+ // Reserved0 and Reserved1 skipped
+ TUint8 inIndex = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationInputLayerIndex);
+ TUint8 inMode = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationInputLayerMode);
+ TUint8 outIndex = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationOutputLayerIndex);
+ TUint8 outMode = AknsSrvUtils::GetUInt8L(aFile, aOffset + EAknsSrvDFOAnimationOutputLayerMode);
+ TInt32 minInterval = AknsSrvUtils::GetInt32L(aFile, aOffset+EAknsSrvDFOAnimationMinInterval);
+
+ if( inMode > 0x08 || outMode > 0x08 )
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ itemDef.iID.Set(major,minor);
+ if( aExclQuery.IsExcluded( itemDef.iID ) )
+ {
+ return;
+ }
+ CheckAndModifyIID( itemDef.iID, aExclQuery );
+ itemDef.iType = EAknsITAnimation;
+
+ // Morphing interval is MIN(all intervals)
+ TBool isMorphing(EFalse);
+ isMorphing = (TBool)type;
+ if (isMorphing)
+ {
+ if (iMorphingMinInterval < 0)
+ {
+ if (minInterval > 0)
+ {
+ iMorphingMinInterval = minInterval;
+ }
+ }
+ else if (iMorphingMinInterval > minInterval)
+ {
+ iMorphingMinInterval = minInterval;
+ }
+ }
+ else // The definition is for highlight animation
+ {
+ // If product variant has disabled highlight animation we simply skip
+ // non-morphing animation definitions.
+ if( !aExclQuery.IsHighlightAnimEnabled() )
+ {
+ return;
+ }
+ }
+
+ //---------------------------------
+ // Step 2: Process animation content
+
+ // Because named reference is stored as parameter, effect commands and
+ // animation commands can be processed with the same function. When parsing
+ // animation data and creating animation definition ChunkLookup will
+ // convert named reference parameters to named reference structures ->
+ // named references as parameters are not visible to animation framework.
+ CAknsSrvArrayStore* preprocessArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( preprocessArray );
+ CAknsSrvArrayStore* commandArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( commandArray );
+ CAknsSrvArrayStore* valueArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( valueArray );
+ CAknsSrvArrayStore* timingArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( timingArray );
+ CAknsSrvArrayStore* sizeBoundArray = new(ELeave) CAknsSrvArrayStore();
+ CleanupStack::PushL( sizeBoundArray );
+
+ TUint16 preprocessCount = 0;
+ TUint16 commandCount = 0;
+ TUint16 valueCount = 0;
+ TUint16 timingCount = 0;
+ TUint16 sizeBoundCount = 0;
+
+ // Process preprocess chunks
+ preprocessCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + EAknsSrvDFOAnimationPreprocessCount );
+ if( preprocessCount > KAknsSrvMaxEffectCount )
+ {
+ User::Leave(KErrCorrupt);
+ }
+
+ TUint32 animBase = EAknsSrvDFOAnimationContentBegin; // Skip header data
+ totalSize += DoMergeEffectCommandsL( aFile, aOffset, animBase, preprocessArray->iArray, preprocessCount );
+
+ // Process animation command chunks
+ commandCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
+ if( commandCount > KAknsSrvMaxEffectCount )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ animBase += sizeof(TUint16); // Skip commandCount
+ totalSize += DoMergeEffectCommandsL( aFile, aOffset, animBase, commandArray->iArray, commandCount );
+
+ // Animation values, timing models and size bound parameters are stored in
+ // similar data structure -> process with the same function.
+
+ // Process animation value chunks
+ valueCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
+ if( valueCount > KAknsSrvMaxParamGroupCount )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ animBase += sizeof(TUint16); // Skip valueCount
+ totalSize += DoMergeParamGroupsL( aFile, aOffset, animBase, valueArray->iArray, valueCount );
+
+ // Process timing model chunks
+ timingCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
+ if( timingCount > KAknsSrvMaxParamGroupCount )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ animBase += sizeof(TUint16); // Skip timingCount
+ totalSize += DoMergeParamGroupsL( aFile, aOffset, animBase, timingArray->iArray, timingCount );
+
+ // Process size bound parameter chunks
+ sizeBoundCount = AknsSrvUtils::GetUInt16L( aFile, aOffset + animBase );
+ if( sizeBoundCount > KAknsSrvMaxParamGroupCount )
+ {
+ User::Leave(KErrCorrupt);
+ }
+ animBase += sizeof(TUint16); // Skip sizeBoundCount
+ totalSize += DoMergeParamGroupsL( aFile, aOffset, animBase, sizeBoundArray->iArray, sizeBoundCount );
+
+ //---------------------------------
+ // Step 3: All items collected, add them to the animation
+ TUint8* block = new(ELeave) TUint8[sizeof(TAknsSrvEffectAnimDef)+totalSize];
+ // No leaves after this
+
+ TAknsSrvEffectAnimDef* eqDef = (TAknsSrvEffectAnimDef*)block;
+ eqDef->iPreprocessCount = preprocessCount;
+ eqDef->iAnimCommandCount = commandCount;
+ eqDef->iAnimValueCount = valueCount;
+ eqDef->iTimingModelCount = timingCount;
+ eqDef->iSizeBoundCount = sizeBoundCount;
+ eqDef->iInputLayerIndex = inIndex;
+ eqDef->iInputLayerMode = inMode;
+ eqDef->iOutputLayerIndex = outIndex;
+ eqDef->iOutputLayerMode = outMode;
+ eqDef->iMinInterval = minInterval;
+ eqDef->iAnimType = isMorphing;
+
+ TUint32 base = sizeof(TAknsSrvEffectAnimDef);
+
+ // Add preprocess commands
+ TInt i;
+ for (i = 0; i < preprocessCount; i++)
+ {
+ TAknsSrvEffectDef* def = (TAknsSrvEffectDef*)(preprocessArray->iArray[i]);
+ size = def->iEffectSize;
+ Mem::Copy( block + base, def, size);
+ base += size;
+ }
+
+ // Add animation commands
+ for (i = 0; i < commandCount; i++)
+ {
+ TAknsSrvEffectDef* def = (TAknsSrvEffectDef*)(commandArray->iArray[i]);
+ size = def->iEffectSize;
+ Mem::Copy( block + base, def, size);
+ base += size;
+ }
+
+ // Add animation values
+ for (i = 0; i < valueCount; i++)
+ {
+ TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)(valueArray->iArray[i]);
+ size = def->iGroupSize;
+ Mem::Copy( block + base, def, size);
+ base += size;
+ }
+
+ // Add timing models
+ for (i = 0; i < timingCount; i++)
+ {
+ TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)(timingArray->iArray[i]);
+ size = def->iGroupSize;
+ Mem::Copy( block + base, def, size);
+ base += size;
+ }
+
+ // Add size bound parameters
+ for (i = 0; i < sizeBoundCount; i++)
+ {
+ TAknsSrvParamGroupDef* def = (TAknsSrvParamGroupDef*)(sizeBoundArray->iArray[i]);
+ size = def->iGroupSize;
+ Mem::Copy( block + base, def, size);
+ base += size;
+ }
+
+ eqDef->iEffectAnimSize = sizeof(TAknsSrvEffectAnimDef)+totalSize;
+
+ CleanupStack::PopAndDestroy( 5 ); // All arrays
+
+ UpdateDef( &itemDef, eqDef, sizeof(TAknsSrvEffectAnimDef)+totalSize, -1 );
+ delete [] block;
+ // Leaves ok after this, block deleted
+ }
+
+// End of file.
+