diff -r 000000000000 -r d0791faffa3f mtpfws/mtpfw/datatypes/src/cmtptypeserviceobjpropextnform.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mtpfws/mtpfw/datatypes/src/cmtptypeserviceobjpropextnform.cpp Tue Feb 02 01:11:40 2010 +0200 @@ -0,0 +1,353 @@ +// Copyright (c) 2006-2009 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: +// + +/** +@file +@internalComponent +*/ + +#include +#include +#include +#include + +#include "mtpdatatypespanic.h" + +// Dataset constants +const TUint CMTPTypeServiceObjPropExtnForm::KFlat1ChunkSize(20); +const TUint CMTPTypeServiceObjPropExtnForm::KFlat2ChunkSize(1); +const TUint CMTPTypeServiceObjPropExtnForm::KNumChunksWithoutForm(EIdFlat2Chunk + 1); +const TUint CMTPTypeServiceObjPropExtnForm::KNumChunksWithForm(EIdFormChunk + 1); + +//Dataset element metadata +const CMTPTypeCompoundBase::TElementInfo CMTPTypeServiceObjPropExtnForm::iElementMetaData[CMTPTypeServiceObjPropExtnForm::ENumElements] = + { + {EIdFlat1Chunk, EMTPTypeFlat, {EMTPTypeUINT128, 0, KMTPTypeUINT128Size}}, // EPKNamespace + {EIdFlat1Chunk, EMTPTypeFlat, {EMTPTypeUINT32, 16, KMTPTypeUINT32Size}}, // EPKeyID + {EIdNameChunk, EMTPTypeString, {EMTPTypeString, KMTPNotApplicable, KMTPNotApplicable}}, // EPropertyName + {EIdFlat2Chunk, EMTPTypeFlat, {EMTPTypeUINT8, 0, KMTPTypeUINT8Size}}, // EFormFlag + {EIdFormChunk, EMTPTypeReference, {EMTPTypeUndefined, KMTPNotApplicable, KMTPNotApplicable}}, // EForm + }; + + +/** +MTP Service Object Property Extension FORM dataset factory method. This method is used to +create an empty MTP Service Object Property Extension FORM of the specified Datatype. +@param aDataType The data type identifier datacode of the object property. +@return A pointer to the form type. Ownership IS +transfered. +@leave One of the system wide error codes, if unsuccessful. +*/ +EXPORT_C CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewL( const TUint aDataType ) + { + CMTPTypeServiceObjPropExtnForm* self = CMTPTypeServiceObjPropExtnForm::NewLC( aDataType ); + CleanupStack::Pop(self); + return self; + } +/** +MTP DevicePropDesc Service Object Property Extension FORM factory method. This method is used to +create an empty MTP Service Object Property Extension FORM of the specified Datatype. +@param aDataType The data type identifier datacode of the the object property. +@return A pointer to the form type. Ownership IS +transfered. +@leave One of the system wide error codes, if unsuccessful. +*/ +EXPORT_C CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewLC( const TUint aDataType ) + { + CMTPTypeServiceObjPropExtnForm* self = new(ELeave) CMTPTypeServiceObjPropExtnForm( aDataType ); + CleanupStack::PushL(self); + TMTPTypeGuid KUndefinedNamespace(0,0); + TUint KPKeyID(0); + TBuf<1> KName; + self->ConstructL( KUndefinedNamespace, KPKeyID, KName, CMTPTypeObjectPropDesc::ENone, NULL ); + + return self; + } + + +EXPORT_C CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewL( const TUint aDataType, const TMTPTypeGuid aPKNamespace, const TUint aPKID, const TDesC& aName, const TUint8 aFormFlag, const MMTPType* aForm) + { + CMTPTypeServiceObjPropExtnForm* self = CMTPTypeServiceObjPropExtnForm::NewLC( aDataType, aPKNamespace, aPKID, aName, aFormFlag, aForm ); + CleanupStack::Pop(self); + return self; + } + + +EXPORT_C CMTPTypeServiceObjPropExtnForm* CMTPTypeServiceObjPropExtnForm::NewLC( const TUint aDataType, const TMTPTypeGuid aPKNamespace, const TUint aPKID, const TDesC& aName, const TUint8 aFormFlag, const MMTPType* aForm) + { + CMTPTypeServiceObjPropExtnForm* self = new(ELeave) CMTPTypeServiceObjPropExtnForm(aDataType); + CleanupStack::PushL(self); + self->ConstructL( aPKNamespace, aPKID, aName, aFormFlag, aForm ); + return self; + } + + +/** +Destructor. +*/ +EXPORT_C CMTPTypeServiceObjPropExtnForm::~CMTPTypeServiceObjPropExtnForm() + { + iChunkFlat1.Close(); + delete iChunkName; + iChunkFlat2.Close(); + iChunkForm.Close(); + } + +CMTPTypeServiceObjPropExtnForm::CMTPTypeServiceObjPropExtnForm(const TUint aDataType) : + CMTPTypeCompoundBase((KJustInTimeConstruction), KNumChunksWithoutForm), + iElementInfo(iElementMetaData, ENumElements), + iChunkFlat1(KFlat1ChunkSize, *this), + iChunkFlat2(KFlat2ChunkSize, *this), + iDataType(aDataType), + iInitialised(EFalse) + { + + } + +EXPORT_C TUint CMTPTypeServiceObjPropExtnForm::Type() const + { + return EMTPTypeServiceObjPropExtnFormDataset; + } + + + +EXPORT_C TInt CMTPTypeServiceObjPropExtnForm::FirstWriteChunk(TPtr8& aChunk) + { + /* + Reset the type in preparation for the data stream, by deleting all + except the first chunk. + */ + for (TUint i(ChunkCount() - 1); i > EIdFlat1Chunk ; i--) + { + ChunkRemove(i); + } + + // Setup the write chunk pointer. + TInt err(UpdateWriteSequenceErr(CMTPTypeCompoundBase::FirstWriteChunk(aChunk))); + switch (err) + { + case KMTPChunkSequenceCompletion: + err = KErrNone; + // Don't break, fall through to set the write sequence state. + + case KErrNone: + // Set the write sequence state. + iWriteSequenceState = EFlat1Chunk; + + /* + Set the write sequence completion state. Initially assume that the + extension form has a FORM field. If no FORM field is subsequently + detected in the write data stream then the completion state is + adjusted accordingly. + */ + iWriteSequenceCompletionState = EFormChunk; + break; + + default: + break; + } + + return err; + } + +EXPORT_C TInt CMTPTypeServiceObjPropExtnForm::NextWriteChunk(TPtr8& aChunk) + { + TInt err(KMTPChunkSequenceCompletion); + + if (iWriteSequenceState != EIdle) + { + err = UpdateWriteSequenceErr(CMTPTypeCompoundBase::NextWriteChunk(aChunk)); + if ((iWriteSequenceErr == KMTPChunkSequenceCompletion) && (iWriteSequenceState != EIdle)) + { + err = KErrNone; + } + } + return err; + } + +EXPORT_C TBool CMTPTypeServiceObjPropExtnForm::CommitRequired() const + { + return ETrue; + } + +EXPORT_C MMTPType* CMTPTypeServiceObjPropExtnForm::CommitChunkL(TPtr8& aChunk) + { + if (iWriteSequenceErr == KMTPChunkSequenceCompletion) + { + switch (iWriteSequenceState) + { + case EFlat1Chunk: + delete iChunkName; + iChunkName = CMTPTypeString::NewL(); + ChunkAppendL(*iChunkName); + break; + + case ENameChunk: + ChunkAppendL(iChunkFlat2); + break; + + case EFlat2Chunk: + { + iChunkForm.Close(); + TUint8 flag(Uint8L(EFormFlag)); + iChunkForm.SetMeta(flag, iDataType); + if (HasFormField(flag)) + { + iChunkForm.OpenL(iElementInfo[EForm].iType); + ChunkAppendL(iChunkForm); + SetExpectedChunkCount(KNumChunksWithForm); + } + else + { + // Adjust the write sequence completion state. + iWriteSequenceCompletionState = EFlat2Chunk; + } + } + break; + + case EFormChunk: + case EIdle: + default: + break; + } + + if ( (iWriteSequenceState != EIdle ) && (iWriteSequenceState < iWriteSequenceCompletionState) ) + { + iWriteSequenceState++; + } + else + { + iWriteSequenceState = EIdle; + } + } + + if (CMTPTypeCompoundBase::CommitRequired()) + { + CMTPTypeCompoundBase::CommitChunkL(aChunk); + } + return NULL; + } + +TBool CMTPTypeServiceObjPropExtnForm::HasFormField(TUint8 aFormFlag) const + { + return ((aFormFlag != CMTPTypeObjectPropDesc::EDateTimeForm) && (aFormFlag != CMTPTypeObjectPropDesc::ENone) && (aFormFlag != CMTPTypeObjectPropDesc::EObjectIDForm) ); + } + +TInt CMTPTypeServiceObjPropExtnForm::UpdateWriteSequenceErr(TInt aErr) + { + iWriteSequenceErr = aErr; + return iWriteSequenceErr; + } + +TBool CMTPTypeServiceObjPropExtnForm::ReadableElementL(TInt aElementId) const + { + __ASSERT_ALWAYS((aElementId < ENumElements), Panic(EMTPTypeBoundsError)); + + TBool ret(ETrue); + if (aElementId == EForm) + { + ret = HasFormField(Uint8L(EFormFlag)); + } + return ret; + } + +TBool CMTPTypeServiceObjPropExtnForm::WriteableElementL(TInt aElementId) const + { + __ASSERT_ALWAYS((aElementId < ENumElements), Panic(EMTPTypeBoundsError)); + + if (!iInitialised) + { + return ETrue; + } + + if (aElementId == EForm) + return EFalse; + + return ETrue; + } + +const CMTPTypeCompoundBase::TElementInfo& CMTPTypeServiceObjPropExtnForm::ElementInfo(TInt aElementId) const + { + __ASSERT_ALWAYS((aElementId < ENumElements), Panic(EMTPTypeBoundsError)); + + return iElementInfo[aElementId]; + } + +void CMTPTypeServiceObjPropExtnForm::ConstructL( const TMTPTypeGuid aPKNamespace, const TUint aPKID, const TDesC& aName, const TUint8 aFormFlag, const MMTPType* aForm ) + { + for (TUint i(0); (i < ENumElements); i++) + { + const TElementInfo& element(iElementInfo[i]); + if (ChunkCount() <= element.iChunkId) + { + MMTPType* chunk(NULL); + switch (element.iChunkId) + { + case EIdFlat1Chunk: + iChunkFlat1.OpenL(); + chunk = &iChunkFlat1; + break; + + case EIdNameChunk: + iChunkName = CMTPTypeString::NewL(); + chunk = iChunkName; + break; + + case EIdFlat2Chunk: + iChunkFlat2.OpenL(); + chunk = &iChunkFlat2; + break; + + case EIdFormChunk: + iChunkForm.SetMeta(aFormFlag, iDataType); + if (HasFormField(aFormFlag)) + { + iChunkForm.OpenL(element.iType); + chunk = &iChunkForm; + SetExpectedChunkCount(KNumChunksWithForm); + } + break; + + default: + Panic(EMTPTypeBoundsError); + break; + } + + if (chunk) + { + ChunkAppendL(*chunk); + } + } + } + // Set the construction values. + SetL( EPKeyNamespace, aPKNamespace ); + SetUint32L( EPKeyID, aPKID ); + SetStringL( EPropertyName, aName ); + SetUint8L(EFormFlag, aFormFlag); + + if (aForm) + { + if (!HasFormField(aFormFlag)) + { + User::Leave(KMTPDataTypeInvalid); + } + else + { + SetL(EForm, *aForm); + } + } + + iInitialised = ETrue; + }