--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mtpfws/mtpfw/src/cmtpreferencemgr.cpp Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,407 @@
+// 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:
+//
+
+#include <mtp/cmtptypearray.h>
+#include <mtp/mtpdatatypeconstants.h>
+#include <mtp/mtpprotocolconstants.h>
+#include <mtp/mtptypessimple.h>
+
+#include "cmtpobjectstore.h"
+#include "cmtpreferencemgr.h"
+#include "dbutility.h"
+
+
+_LIT(KSQLReferenceTableName, "ReferenceStore");
+_LIT(KSQLReferenceIndexName, "ReferenceIndex");
+_LIT(KSQLCreateReferenceTableText,"CREATE TABLE ReferenceStore (HandleId UNSIGNED INTEGER, References LONG VARBINARY)");
+_LIT(KSQLCreateReferenceIndexText,"CREATE UNIQUE INDEX ReferenceIndex on ReferenceStore (HandleId)");
+
+
+static const TInt KMTPReferenceGranularity = 5;
+// Maximum value to use for granularity
+// This will result in 4KB of memory used (1024 * 4bytes) for reference SUID array
+static const TInt KMTPMaxGranularity = 1024;
+
+/**
+Two phase construction
+@param aObjectMgr Reference to the object manager
+@return a pointer to the reference manager instance
+*/
+CMTPReferenceMgr* CMTPReferenceMgr::NewL(CMTPObjectStore& aObjectStore)
+ {
+ CMTPReferenceMgr* self = new (ELeave) CMTPReferenceMgr(aObjectStore);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+/**
+Destructor
+*/
+CMTPReferenceMgr::~CMTPReferenceMgr()
+ {
+ iBatched.Close();
+ }
+
+/**
+Provides an MTP array of the target object handles which are referenced
+by the specified source object handle. A pointer to the MTP array is
+placed on the cleanup stack.
+@param aFromHandle The MTP object handle of the source object from which
+the references originate.
+@return The MTP reference target object handle array. Ownership IS transferred.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+CMTPTypeArray* CMTPReferenceMgr::ReferencesLC(const TMTPTypeUint32& aFromHandle) const
+ {
+ return GetReferencesLC(aFromHandle.Value());
+ }
+
+/**
+Provides an SUID array of the target object SUIDs which are referenced by
+the specified source object SUID. A pointer to the SUID array is
+placed on the cleanup stack.
+@param aFromSuid The SUID of the source object from which the references
+originate.
+@return The reference target object SUID array. Ownership IS transferred.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+CDesCArray* CMTPReferenceMgr::ReferencesLC(const TDesC& aParentSuid) const
+ {
+ TUint32 handle = iObjectStore.HandleL(aParentSuid);
+ return GetReferencesInDesLC(handle);
+ }
+
+/**
+Removes all object reference links in which the specified SUID represents
+either the source or target reference object.
+@param aSuid The object SUID.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::RemoveReferencesL(const TDesC& aSuid)
+ {
+ TUint32 handle = iObjectStore.HandleL(aSuid);
+ RemoveReferencesL(handle);
+ }
+
+/**
+Creates an abstract reference linkage between the specified source and
+target object SUIDs.
+@param aFromSuid The SUID of the source object from which the reference
+originates.
+param aToSuid The SUID of the target object to which the reference is
+made.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::SetReferenceL(const TDesC& aFromSuid, const TDesC& aToSuid)
+ {
+ TUint32 fromHandle = iObjectStore.HandleL(aFromSuid);
+ TUint32 toHandle = iObjectStore.HandleL(aToSuid);
+ SetReferenceL(fromHandle, toHandle);
+ }
+
+/**
+Replaces the abstract reference links originating from the specified
+source object handle with the specified set of target object SUIDs.
+@param aFromHandle The SUID of the source object from which the references
+originate.
+@param aToSuids The reference target MTP object SUID array.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::SetReferencesL(const TDesC& aParentSuid, const CDesCArray& aToSuids)
+ {
+ TInt count = aToSuids.Count();
+
+ if (count > 0)
+ {
+ TUint32 fromHandle = iObjectStore.HandleL(aParentSuid);
+
+ // Limit granularity to something less or equal to KMTPMaxGranularity items
+ RArray<TUint> toHandles(Min(count, KMTPMaxGranularity));
+ CleanupClosePushL(toHandles);
+
+ for(TInt i = 0; i < count; i++)
+ {
+ TUint32 toHandle = iObjectStore.HandleL(aToSuids[i]);
+ toHandles.Append(toHandle);
+ }
+
+ SetReferencesL(fromHandle, toHandles);
+ CleanupStack::PopAndDestroy(&toHandles);
+ }
+ }
+
+
+/**
+Constructor/.
+*/
+CMTPReferenceMgr::CMTPReferenceMgr(CMTPObjectStore& aObjectStore):
+ iObjectStore(aObjectStore)
+ {
+
+ }
+
+/**
+second-phase construction
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::ConstructL()
+ {
+ iDatabase = &iObjectStore.Database();
+
+ if(!DBUtility::IsTableExistsL(*iDatabase, KSQLReferenceTableName))
+ {
+ CreateTableL();
+ }
+ if(!DBUtility::IsIndexExistsL(*iDatabase, KSQLReferenceTableName, KSQLReferenceIndexName))
+ {
+ CreateIndexL();
+ }
+ iBatched.Open(*iDatabase, KSQLReferenceTableName, RDbRowSet::EUpdatable);
+ iBatched.SetIndex( KSQLReferenceIndexName );
+ }
+
+/**
+Create the reference table in the database
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::CreateTableL()
+ {
+ User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceTableText));
+ }
+
+/**
+Create the index in the reference table
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::CreateIndexL()
+ {
+ User::LeaveIfError(iDatabase->Execute(KSQLCreateReferenceIndexText));
+ }
+
+/**
+Get reference on the object identified by aIdentifier
+@param aIdentifier The 64bit internal object identifier
+@return The array containing the handles of the references
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+CMTPTypeArray* CMTPReferenceMgr::GetReferencesLC(TUint aHandle) const
+ {
+ RArray<TUint> toHandles;
+ CleanupClosePushL(toHandles);
+ GetReferencesL(aHandle, toHandles);
+
+ CMTPTypeArray* mtpReferenceArray = CMTPTypeArray::NewLC(EMTPTypeAUINT32);
+ mtpReferenceArray->AppendL(toHandles);
+ CleanupStack::Pop(mtpReferenceArray);
+ CleanupStack::PopAndDestroy(&toHandles);
+ CleanupStack::PushL(mtpReferenceArray);
+ return mtpReferenceArray;
+ }
+
+/**
+Get reference on the object identified by aIdentifier
+@param aIdentifier The 64bit internal object identifier
+@return The array containing the suids of the references
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+CDesCArray* CMTPReferenceMgr::GetReferencesInDesLC(TUint aHandle) const
+ {
+ RArray<TUint> toHandles(KMTPReferenceGranularity);
+ CleanupClosePushL(toHandles);
+ GetReferencesL(aHandle, toHandles);
+ const TInt count = toHandles.Count();
+ CDesCArray* mtpReferenceArray = new (ELeave) CDesCArrayFlat((count==0) ? 1 : count);
+ CleanupStack::PushL(mtpReferenceArray);
+
+ for(TInt i = 0; i < count; i++)
+ {
+ const TDesC& suid = iObjectStore.ObjectSuidL(toHandles[i]);
+ if(suid.Length())
+ {
+ mtpReferenceArray->AppendL(suid);
+ }
+ }
+ CleanupStack::Pop(mtpReferenceArray);
+ CleanupStack::PopAndDestroy(&toHandles);
+ CleanupStack::PushL(mtpReferenceArray);
+ return mtpReferenceArray;
+
+ }
+
+/**
+Get references on the object identified by aIdentifier
+@param aIdentifier The 64bit internal object identifier
+@param aReferences The reference array, on return, containing the 64bit internal identifiers of the references
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::GetReferencesL(TUint aHandle, RArray<TUint>& aToHandles) const
+ {
+ TUint32 temp = 0;
+ TBool needToUpdate = EFalse;
+ aToHandles.Reset();
+ if(iBatched.SeekL(aHandle))
+ {
+ iBatched.GetL();
+ RDbColReadStream readStream;
+ readStream.OpenLC(iBatched,2);
+ TInt count = readStream.ReadInt32L();
+ while(count--)
+ {
+ temp = readStream.ReadUint32L();
+ if(iObjectStore.ObjectExistsL(temp))
+ aToHandles.AppendL(temp);
+ else
+ needToUpdate = ETrue;
+ }
+ CleanupStack::PopAndDestroy(&readStream);
+
+
+ if(needToUpdate)
+ {//Something has been deleted. Write it back to Reference list
+ iBatched.UpdateL();
+ RDbColWriteStream writeStream;
+ writeStream.OpenLC(iBatched,2);
+
+ count = aToHandles.Count();
+ writeStream.WriteInt32L(count);
+ for(TInt i = 0; i < count; i++)
+ {
+ writeStream.WriteUint32L(aToHandles[i]);
+ }
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(&writeStream);
+ iBatched.PutL();
+ }
+
+ }
+ return;
+
+ }
+
+
+/**
+Remove reference on the object identified by aIdentifier
+@param aIdentifier The 64bit internal object identifier
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::RemoveReferencesL(TUint aHandle)
+ {
+ if(iBatched.SeekL(aHandle))
+ {
+ iBatched.DeleteL();
+ IncTranOpsNumL();
+ }
+ }
+/**
+Set reference on the object identified by aFromIdentifier
+@param aFromIdentifier The 64bit internal object identifier of the source object
+@param aToIdentifier The 64bit internal object identifier of the referenced object
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::SetReferenceL(TUint aFromHandle, TUint aToHandle)
+ {
+ RArray<TUint> aToHandleArray(1);
+ CleanupClosePushL(aToHandleArray);
+ aToHandleArray.AppendL(aToHandle);
+ SetReferencesL(aFromHandle, aToHandleArray);
+ CleanupStack::PopAndDestroy(&aToHandleArray);
+ }
+
+/**
+Replaces the abstract reference links originating from the specified
+source object handle with the specified set of target object handles.
+@param aFromHandle The handle of the source object from which the references
+originate.
+@param aToHandles The reference target object handle array.
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::SetReferencesL(const TMTPTypeUint32& aFromHandle, const CMTPTypeArray& aToHandles)
+{
+ RArray<TUint> tempArray;
+ CleanupClosePushL(tempArray);
+ TInt count = aToHandles.NumElements();
+ for(TInt i = 0; i < count; i++)
+ {
+ tempArray.Append(aToHandles.ElementUint(i));
+ }
+ SetReferencesL(aFromHandle.Value(), tempArray);
+ CleanupStack::PopAndDestroy(&tempArray);
+}
+
+
+
+/**
+Set references on the object identified by aFromIdentifier
+@param aFromIdentifier The 64bit internal object identifier of the source object
+@param aToIdentifiers The 64bit internal object identifiers of the referenced objects
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+void CMTPReferenceMgr::SetReferencesL(TUint aHandle, const RArray<TUint>& aToHandles)
+ {
+ if(iBatched.SeekL(aHandle))
+ {
+ iBatched.UpdateL();
+ }
+ else
+ {
+ iBatched.InsertL();
+ }
+
+ iBatched.SetColL(1, aHandle);
+
+ RDbColWriteStream writeStream;
+ writeStream.OpenLC(iBatched,2);
+
+ const TInt count = aToHandles.Count();
+ writeStream.WriteInt32L(count);
+ for(TInt i = 0; i < count; i++)
+ {
+ writeStream.WriteUint32L(aToHandles[i]);
+ }
+ writeStream.CommitL();
+ CleanupStack::PopAndDestroy(&writeStream);
+ iBatched.PutL();
+ IncTranOpsNumL();
+ }
+
+
+void CMTPReferenceMgr::IncTranOpsNumL()
+ {
+ iObjectStore.IncTranOpsNumL();
+ }
+
+
+/**
+Verify if every reference is pointing to a valid object. If the referenced object does not exist,
+delete the object from the reference array.
+@param aReference The 64bit internal object identifiers of the referenced objects
+@leave One of the system wide error codes, if a processing failure occurs.
+*/
+/*
+void CMTPReferenceMgr::AdjustReferencesL(RArray<TUint32>&aHandles) const
+ {
+ TInt count = aHandles.Count();
+ while(count--)
+ {
+ if(!iObjectStore.ObjectExistsL(aHandles[count]))
+ {
+ aHandles.Remove(count);
+ }
+ }
+ }
+ */
+