appfw/apparchitecture/apparc/APAMDR.CPP
changeset 0 2e3d3ce01487
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/appfw/apparchitecture/apparc/APAMDR.CPP	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,468 @@
+// Copyright (c) 1997-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:
+// apamdr.cpp
+//
+
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#if !defined(__APA_INTERNAL_H__)
+#include "apainternal.h"
+#endif
+#endif //SYMBIAN_ENABLE_SPLIT_HEADERS
+#include "APASTD.H" // Panics etc.
+
+#include <apamdr.h>
+
+#include <apgdoor.h>
+#include <s32mem.h>		// class TBufBuf
+
+const TInt KHugeGranularity = 4096; // 4k granularity for the door's host buffer
+
+//
+// HBufBuf
+//
+
+class HBufBuf : public TBufBuf
+	{
+public:
+	static HBufBuf* NewL(CBufBase& aBuf,TInt aPos,TInt aMode=ERead|EWrite);
+private:
+	void DoRelease();
+	};
+
+HBufBuf* HBufBuf::NewL(CBufBase& aBuf,TInt aPos,TInt aMode)
+//
+// Create a pre-set buffer stream buffer.
+//
+	{
+	HBufBuf* buf=new(ELeave) HBufBuf;
+	buf->Set(aBuf,aPos,aMode);
+	return buf;
+	}
+
+void HBufBuf::DoRelease()
+//
+// Finished with this stream buffer.
+//
+	{
+	delete this;
+	}
+
+//
+// TApaModelDoorFactory
+//
+
+EXPORT_C TApaModelDoorFactory::TApaModelDoorFactory(const MApaModelHeaderFactory* aFactory)
+	:iHeaderFactory(aFactory)
+/** Constructs a door factory object.
+
+@param aFactory A pointer to a factory object for constructing the application 
+model wrapper object, also known as the application model header, a CApaModelHeader 
+type. The application model wrapper is provided by the application model (not 
+the application UI), and supplies the knowledge for internalizing the application 
+model data from an embedded store.
+@see CApaModelHeader
+@see MApaModelHeaderFactory */
+	{}
+
+
+EXPORT_C void TApaModelDoorFactory::NewPictureL(TPictureHeader& aPictureHeader,const CStreamStore& aPictureStore)const
+/** Constructs and restores an application's door (picture) from a stream in the 
+specified store.
+
+The restored door is a CApaModelDoor type object.
+
+@param aPictureHeader The header identifying the door to be restored. The 
+UID identifying the door must be KUidPictureTypeDoor, otherwise the function 
+leaves with KErrNotSupported. On entry, the door picture must be represented 
+by a stream ID, otherwise the function leaves with KErrBadHandle; on return, 
+the door picture is represented by a pointer to an internalized CApaModelDoor 
+object.
+@param aPictureStore The store from which the door will be restored.
+@see TPictureHeader::iPicture */
+	{
+	if (aPictureHeader.iPictureType!=KUidPictureTypeDoor)
+		User::Leave(KErrNotSupported); // wrong type
+	if (!aPictureHeader.iPicture.IsId())
+		User::Leave(KErrBadHandle); // not an id - can't restore
+	//
+	// create and restore the door
+	TStreamId id = aPictureHeader.iPicture.AsId();
+	aPictureHeader.iPicture = CApaModelDoor::NewL(aPictureStore,id,iHeaderFactory);
+	}
+
+
+//
+// CApaModelDoor
+//
+
+
+EXPORT_C CApaModelDoor* CApaModelDoor::NewL(CApaModelHeader* aHeader)
+/** Creates a model door object.
+
+@param aHeader A pointer to an existing concrete application model wrapper 
+object.
+@return A pointer to the new model door object. */
+	{
+	CApaModelDoor* self = new(ELeave) CApaModelDoor(aHeader);
+	return self;
+	}
+
+
+EXPORT_C CApaModelDoor* CApaModelDoor::NewLC(CApaModelHeader* aHeader)
+/** Creates a model door object, and puts a pointer to it onto the cleanup stack.
+
+@param aHeader A pointer to an existing concrete application model wrapper 
+object.
+@return A pointer to the new model door object. */
+	{
+	CApaModelDoor* self = CApaModelDoor::NewL(aHeader);
+	CleanupStack::PushL(self);
+	return self;
+	}
+
+
+EXPORT_C CApaModelDoor* CApaModelDoor::NewL(const CStreamStore& aStore,TStreamId aHeadStreamId,const MApaModelHeaderFactory* aFactory)
+/** Creates a model door object and restores it from an embedded store within the 
+specified store.
+
+@param aStore The store from which the model door is to be restored.
+@param aHeadStreamId The head stream ID. This is the ID of the stream containing 
+the stream dictionary which is restored as part of the process of creating 
+this model door object. The stream dictionary contains the ID of the stream 
+hosting the embedded store.
+@param aFactory A pointer to a factory object for constructing the application 
+model wrapper object, also known as the application model header, a CApaModelHeader 
+type.
+@return A pointer to the new model door object.
+@see MApaModelHeaderFactory */
+	{
+	CApaModelDoor* self = new(ELeave) CApaModelDoor();
+	CleanupStack::PushL(self);
+	self->RestoreL(aStore,aHeadStreamId,aFactory);
+	CleanupStack::Pop();
+	return self;
+	}
+
+
+CApaModelDoor::CApaModelDoor()
+	{}
+
+
+CApaModelDoor::CApaModelDoor(CApaModelHeader* aHeader)
+	:iModelHeader(aHeader)
+	{}
+
+
+EXPORT_C CApaModelDoor::~CApaModelDoor()
+/** Destructor.
+
+Frees all resources owned by the object, prior to its destruction. */
+	{
+	delete iModelHeader;
+	delete iStore;
+	delete iStoreHost;
+	}
+
+
+EXPORT_C TStreamId CApaModelDoor::StoreL(CStreamStore& aTargetStore)const
+/** Stores the model data in the specified store as an embedded store.
+
+The function stores the model data, if the model exists in memory, otherwise, 
+it simply copies the stream containing the embedded document into the specified 
+store.
+
+@param aStore The store in which the model data is to be stored.
+@return The stream ID of the head stream for the embedded model data. This 
+stream contains the stream dictionary through which the embedded data and 
+its door can be restored. */
+	{
+	// create stream dictionary
+	CStreamDictionary* streamDic = CStreamDictionary::NewLC();
+	//
+	// stream out door's state
+	ExternalizeBaseStreamL(aTargetStore,*streamDic);
+	//
+	// store the model 
+	TStreamId id;
+	RStoreWriteStream stream;
+	if (iModelHeader)
+		{
+		// create an embedded store in a new write stream
+		id = stream.CreateL(aTargetStore);
+		CEmbeddedStore* target=CEmbeddedStore::NewLC(stream); // takes ownership of stream
+		streamDic->AssignL(KUidApaDoorDocStream,id);
+		// store the model
+		CStreamDictionary* rootDict=CStreamDictionary::NewLC();
+		iModelHeader->StoreL(*target,*rootDict);
+		CApaProcess::WriteRootStreamL(*target,*rootDict,iModelHeader->AppId());
+		CleanupStack::PopAndDestroy(); // rootDict
+		// close the new embedded store
+		target->CommitL();
+		CleanupStack::PopAndDestroy(); // target
+		}
+	else if (iStore)
+		{
+		RStoreWriteStream trg;
+		id = trg.CreateLC(aTargetStore);
+		CopyStoreL(*iStore,trg);
+		CleanupStack::PopAndDestroy(); // trg
+		streamDic->AssignL(KUidApaDoorDocStream,id);
+		}
+	else 
+		Panic(EPanicNoModelHeaderWhenStoring); // impossible situation
+	//
+	// store the stream dictionary and return its stream id
+	id = stream.CreateLC(aTargetStore);
+	stream<< *streamDic;
+	stream.CommitL();
+	CleanupStack::PopAndDestroy(2); // stream,streamDic
+	return id;
+	}
+
+
+void CApaModelDoor::CopyStoreL(const CEmbeddedStore& aSourceStore,RWriteStream& aTargetStream)
+// static method
+// copies an embedded store containing a doc to aTargetStream
+//
+	{
+	// read the contents of aSourceStore's rootstream (so I can write it out in a mo')
+	CStreamDictionary* root=ReadStreamDictionaryLC(aSourceStore,aSourceStore.Root());
+	//
+	// copy the source store directly
+	MStreamBuf* host=aSourceStore.Host();
+	TStreamPos pos=aSourceStore.Position(aSourceStore.Root());
+	host->SeekL(host->ERead,EStreamBeginning);
+	RReadStream stream(host);
+	aTargetStream.WriteL(stream,pos.Offset());
+	//
+	// write the root stream
+	aTargetStream<< *root;
+	aTargetStream.CommitL();
+	CleanupStack::PopAndDestroy(); // root
+	}
+
+
+EXPORT_C void CApaModelDoor::RestoreL(const CStreamStore& aSourceStore,TStreamId aHeadStreamId,const MApaModelHeaderFactory* aFactory)
+/** Restores the embedded model data from the specified store.
+
+@param aStore The store from which the embedded model data is to be restored.
+@param aHeadStreamId The stream ID of the head stream for the embedded model 
+data. This stream contains the stream dictionary through which the embedded 
+model data and its door can be restored.
+@param aFactory A pointer to a factory object for constructing the application 
+model wrapper object, also known as the application model header, a CApaModelHeader 
+type. The application model wrapper is provided by the application model (not 
+the application UI), and supplies the knowledge for internalizing the application 
+model data from an embedded store. The pointer must not be null, otherwise 
+the function raises an APPARC 22 panic. */
+	{
+	__ASSERT_ALWAYS(aFactory,Panic(EPanicNoFactory));
+	//
+	delete iStore;
+	delete iStoreHost;
+	iStore=NULL;
+	iStoreHost = NULL;
+	//
+	// internalize the streamDic from the headstream
+	CStreamDictionary* streamDic=ReadStreamDictionaryLC(aSourceStore,aHeadStreamId);
+	//
+	// internalize the door's state
+	TSize size=InternalizeBaseStreamL(aSourceStore,*streamDic);
+	SetSizeInTwips(size);
+	//
+	// internalize the embedded store
+	RStoreReadStream src;
+	src.OpenL(aSourceStore,streamDic->At(KUidApaDoorDocStream));
+	CleanupStack::PopAndDestroy(); // streamDic
+	streamDic = NULL;
+	iStore = CEmbeddedStore::FromL(src);
+	//
+	// check for a security stream, then internalize the model
+	TRAP_IGNORE(InternalizeModelL(*aFactory)); //lint !e613 Possible use of null pointer - Asserted above
+	// ignore any leave, we still have the data in the store to fall back on
+	}
+
+
+void CApaModelDoor::InternalizeModelL(const MApaModelHeaderFactory& aFactory)
+// internalizes the model if the data is not encrypted
+// if the factory does not recognize the doc type, NewHeaderL() will leave (probably KErrNotSupported)
+	{	
+	CStreamDictionary* streamDic = ReadStreamDictionaryLC(*iStore,iStore->Root());
+	if (streamDic->At(KUidSecurityStream)==KNullStreamId)
+		{// not encrypted, so internalize the model
+		TApaAppIdentifier appId = CApaProcess::ReadAppIdentifierL(*iStore,*streamDic);
+		iModelHeader = aFactory.NewHeaderL(*iStore,*streamDic,appId);
+		}
+	CleanupStack::PopAndDestroy(); // streamDic
+	}
+
+
+CStreamDictionary* CApaModelDoor::ReadStreamDictionaryLC(const CStreamStore& aSourceStore,TStreamId aStreamId)
+// static method
+//
+	{
+	// read the stream dic from the doc's root stream
+	CStreamDictionary* streamDic=CStreamDictionary::NewLC();
+	RStoreReadStream stream;
+	stream.OpenLC(aSourceStore,aStreamId);
+	stream>> *streamDic;
+	CleanupStack::PopAndDestroy(); // root
+	return streamDic;
+	}
+
+
+TSize CApaModelDoor::GlassDoorSize()const
+	{
+	TSize size;
+	GetSizeInTwips(size);
+	return size;
+	}
+
+
+EXPORT_C void CApaModelDoor::DetachFromStoreL(TDetach aDegree)
+/** Restores the model to the specified degree.
+
+@param aDegree The degree to which restoration is needed. */
+	{
+	if (iModelHeader)
+		{
+		iModelHeader->DetachFromStoreL(aDegree);
+		if (!iStoreHost)
+			{
+			delete iStore;
+			iStore = NULL;
+			}
+		}
+	else if (!iStoreHost)
+		{
+		if (aDegree==EDetachDraw)
+			{
+			delete iStore;
+			iStore = NULL;
+			// now all I can do is draw as I am, any attempt to change me will result in a panic
+			}
+		else
+			{
+			__ASSERT_ALWAYS(iStore,Panic(EPanicNoStoreOnDetach));
+			// instantiate the mem buffer, and a stream to write to it
+			CBufSeg* bufSeg = CBufSeg::NewL(KHugeGranularity);
+			CleanupStack::PushL(bufSeg);
+			HBufBuf* buf=HBufBuf::NewL(*bufSeg,0);
+			RWriteStream writeStream(buf);
+			writeStream.PushL();
+			// write the store to the mem buffer
+			CopyStoreL(*iStore,writeStream);
+			CleanupStack::Pop(2); // bufSeg,writeStream
+			//
+			// set iStoreHost as host for the embedded store
+			MStreamBuf* host=iStore->Host();
+			__ASSERT_ALWAYS(host!=NULL,Panic(EDPanicNoHostForStore));
+			iStore->Detach();
+			host->Release(); //lint !e613 Possible use of null pointer - Asserted above
+			iStore->Reattach(buf);
+			iStoreHost = bufSeg;
+			}
+		}
+	}
+
+
+
+EXPORT_C void CApaModelDoor::Draw(CGraphicsContext& /*aGc*/,const TPoint& /*aTopLeft*/,const TRect& /*aClipRect*/,
+						MGraphicsDeviceMap* /*aMap*/)const
+/**
+Not supported; if called, raises an APPARC 17 panic.
+@removed
+*/
+	{
+	Panic(EPanicNotSupported);
+	}
+
+
+
+
+EXPORT_C void CApaModelDoor::ExternalizeL(RWriteStream& /*aStream*/)const
+/**
+Not supported; if called, raises an APPARC 17 panic. 
+@removed
+*/
+	{
+	Panic(EPanicNotSupported);
+	}
+
+
+EXPORT_C void CApaModelDoor::GetOriginalSizeInTwips(TSize& aSize)const
+/** Gets the door's original size, in twips.
+
+@param aSize This size, in twips. */
+	{
+	aSize = TSize(500,500); // ?
+	}
+
+
+EXPORT_C void CApaModelDoor::SetScaleFactor(TInt aScaleFactorWidth,TInt aScaleFactorHeight)
+/** Sets the door's scale factors.
+
+@param aScaleFactorWidth The width scale factor, in percent.
+@param aScaleFactorHeight The height scale factor, in percent. */
+	{
+	iScaleFactor.iWidth = aScaleFactorWidth;
+	iScaleFactor.iHeight = aScaleFactorHeight;
+	}
+
+
+EXPORT_C TInt CApaModelDoor::ScaleFactorWidth()const
+/** Gets the door's width scale factor.
+
+@return The width scale factor, in percent. */
+	{
+	return iScaleFactor.iWidth;
+	}
+
+
+EXPORT_C TInt CApaModelDoor::ScaleFactorHeight()const
+/** Gets the door's height scale factor.
+
+@return The height scale factor, in percent. */
+	{
+	return iScaleFactor.iHeight;
+	}
+
+// CApaModelHeader
+
+/** Constructor for CApaModelHeader */
+EXPORT_C CApaModelHeader::CApaModelHeader()
+	{
+	}
+
+/** Reserved for future use */
+EXPORT_C void CApaModelHeader::Reserved_1()
+	{}
+
+/** Reserved for future use */	
+EXPORT_C void CApaModelHeader::Reserved_2()
+	{}
+
+// MApaModelHeaderFactory
+
+/** Constructor for MApaModelHeaderFactory */
+EXPORT_C MApaModelHeaderFactory::MApaModelHeaderFactory()
+	{}
+
+/** Reserved for future use */
+EXPORT_C void MApaModelHeaderFactory::MApaModelHeaderFactory_Reserved1()
+	{}
+
+/** Reserved for future use */
+EXPORT_C void MApaModelHeaderFactory::MApaModelHeaderFactory_Reserved2()
+	{}