Symbian3/SDK/Source/GUID-38A656D3-F830-5E26-8167-3638B6BC5DF6.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Tue, 20 Jul 2010 12:00:49 +0100
changeset 13 48780e181b38
parent 0 89d6a7a84779
permissions -rw-r--r--
Week 28 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 1897 and Bug 1522.

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
<!-- This component and the accompanying materials are made available under the terms of the License 
"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: 
-->
<!DOCTYPE concept
  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
<concept xml:lang="en" id="GUID-38A656D3-F830-5E26-8167-3638B6BC5DF6"><title>How to restore a compound object</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>The protocol for restoring a compound object is the <codeph>RestoreL()</codeph> function. This is true whether the object has been stored in-line or out-of-line, and should be prototyped as:</p> <codeblock id="GUID-AA727C46-3D5E-53D2-8697-721ED1F0D05C" xml:space="preserve">void RestoreL(CStreamStore&amp; aStore,TStreamId anId);</codeblock> <p>The function takes a reference to the store in which streams are stored and a stream ID. In some cases, the design of a class may be such that it maintains a pointer or reference to the store. In this event, the <codeph>CStreamStore</codeph> argument would be redundant.</p> <section><title>Restoring components stored in-line</title> <p>If an object's components have been stored in-line, then all of these components have been written to the same single stream.</p> <p>For the example class <codeph>CCompound</codeph>, defined as:</p> <codeblock id="GUID-1BB27256-2ADE-516E-8213-4B901A64BB30" xml:space="preserve">CCompound class : public CBase
    {
    ...
    TInt         iDdata;
    CComponentA* iCompA;
    CComponentB* iCompB;
    ...
    }</codeblock> <p>RestoreL() is implemented as: </p> <codeblock id="GUID-AD51C522-3734-5827-938A-0595DD012A79" xml:space="preserve">void CCompound::RestoreL(CStreamStore&amp; aStore,TStreamId anId)
    {
    RStoreReadStream instream;
    instream.OpenLC(aStore,anId);
    InternalizeL(instream);
    CleanupStack::PopAndDestroy();
    }</codeblock> <p>where the stream ID passed to the function is the ID of the single stream containing the data.</p> </section> <section><title>Restoring components stored out-of-line</title> <p>If an object's components have been stored out-of-line, then all of these components have been written to separate streams.</p> <p>For the example class <codeph>CCompound</codeph>, defined as:</p> <codeblock id="GUID-345E2356-1AD3-5CF4-9847-7AE6C383448C" xml:space="preserve">CCompound class : public CBase
    {
    ...
    TInt                  iDdata;
    TSwizzle&lt;CComponentA&gt; iCompA;
    TSwizzle&lt;CComponentB&gt; iCompB;
    ...
    }</codeblock> <p>RestoreL() is implemented as:</p> <codeblock id="GUID-81FEC5E3-EDDE-5596-BE12-420CC5D19F91" xml:space="preserve">void CCompound::RestoreL(CStreamStore&amp; aStore,TStreamId anId)
    {
    RStoreReadStream stream;      // Construct a read stream.
    stream.OpenLC(aStore,anId);   // Open the head stream.
    InternalizeL(stream);         // Internalise top level stream containing CCompound
                                  // and the IDs of its components. 
    RestoreComponentsL(aStore);   // Restore components.
    CleanupStack::PopAndDestroy();
    }
</codeblock> <p>where the stream ID passed to the function is the ID of the head stream.</p> <p>InternalizeL() internalises CCompound's data members and the stream IDs of its components:</p> <codeblock id="GUID-36C860E3-9552-52C4-AD54-53B614DE7B8A" xml:space="preserve">void CCompound::InternalizeL(RReadStream&amp; aStream)
    {
    aStream &gt;&gt; iDataA;
    aStream &gt;&gt; iCompA;  
    aStream &gt;&gt; iCompB;
    }</codeblock> <p><codeph>RestoreComponentsL()</codeph> constructs each component object and restores them from their respective stream networks. </p> <codeblock id="GUID-FD539747-82E8-5EF1-ADF0-E5101AE8EDA3" xml:space="preserve">void CCompound::RestoreComponentsL(CStreamStore&amp; aStore)
    { 
    CComponentA* ptrA = new (ELeave) CComponentA;
    CleanupStack::PushL(ptrA);
    ptrA-&gt;RestoreL(aStore,iCompA.AsId());
    iCompA = ptrA;
    CleanupStack::Pop();
    CComponentB* ptrB = new (ELeave) CComponentB;
    CleanupStack::PushL(ptrB);
    ptrB-&gt;RestoreL(aStore,iCompB.AsId());
    iCompB = ptrB CleanupStack::Pop();
    }</codeblock> <p>In general, an application might want to defer the loading of some components. This would mean either changing the implementation of <codeph>RestoreComponents()</codeph> or adding new functionality to the class. The use of Swizzles is important here as they simplify the handling of the dual representation of an object as a pointer to an in-memory object or as an ID of a stream.</p> <p>Typically, an application might use code such as:</p> <codeblock id="GUID-E2D26E4E-02C0-5E89-8D82-0F628101011C" xml:space="preserve">if (iCompA.IsId())
    {
    iCompA = CComponentA::NewL(iStore,iCompA.AsId());
    }</codeblock> <p>to test whether the component is currently represented by a stream ID or by a pointer to an in-memory object. If a stream ID, then the component would be restored. In this small code fragment, an overloaded <codeph>NewL()</codeph> function is used both to construct and to restore the component object. Once this code has executed, the component is represented by a pointer.</p> <p><b>See also</b> </p> <p><xref href="GUID-C1AA34CB-D63D-57E3-87F6-28AD22537D21.dita">Store map</xref> </p> <p><xref href="GUID-53112730-5871-5920-8861-D2F6BF1595BC.dita">Swizzles and deferred loading</xref> </p> </section> </conbody></concept>