Symbian3/SDK/Source/GUID-3690B530-BFFC-554E-9692-3D7C4C0BC803.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-3690B530-BFFC-554E-9692-3D7C4C0BC803"><title>Templated stream operators</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>There are two templated stream operators, <codeph>operator&lt;&lt;</codeph> and <codeph>operator&gt;&gt;</codeph> that can be used to externalise and internalise data of all types. They use a syntax that is familiar to users of C++ iostreams, or Java streams.</p> <p> An object can be externalised to a stream, using a write stream:</p> <codeblock id="GUID-825246E2-9EFF-5D34-9B89-62B0AE8419E8" xml:space="preserve">writeStream &lt;&lt; object;</codeblock> <p>and later, assuming the operation starts from the appropriate place on the stream, the data can be internalised again, using a read stream:</p> <codeblock id="GUID-4D1E6CC5-06D1-5AA9-99A0-DDAC3793DEEA" xml:space="preserve">readStream &gt;&gt; object;</codeblock> <p>The implementation of the operators depends on the type of object on which they are called.</p> <section><title>Implementation for a class defining ExternalizeL() &amp; InternalizeL()</title> <p>For a class that defines and implements the <codeph>ExternalizeL()</codeph> and <codeph>InternalizeL()</codeph> functions, the Store framework:</p> <ul><li id="GUID-7000A711-4C8F-5522-9981-6975FD563D6B"><p>implements <codeph>operator&lt;&lt;</codeph> by calling the <codeph>ExternalizeL()</codeph> member function of that class.</p> </li> <li id="GUID-D62B7DE5-7179-56AB-A7BC-221459CA7E77"><p>implements <codeph>operator&gt;&gt;</codeph> by calling the <codeph>InternalizeL()</codeph> member function of that class.</p> </li> </ul> </section> <section><title>Implementation for standard types and classes</title> <p>The Store framework provides the necessary implementation for the operators to externalise and internalise the following:</p> <ul><li id="GUID-7FC174ED-C934-5AEA-9149-ED8CB7A9B4C4"><p>The basic types: <codeph>TInt8</codeph>, <codeph>TInt16</codeph>, <codeph>TInt32</codeph>, <codeph>TInt64</codeph>, <codeph>TUint8</codeph>, <codeph>TUint16</codeph>, <codeph>TUint32</codeph>, <codeph>TReal32</codeph> and <codeph>TReal64</codeph>.</p> </li> <li id="GUID-E03896E9-A375-55ED-A4A4-2BD9D39DACE2"><p>The graphics API classes: <codeph>TPoint</codeph>, <codeph>TSize</codeph> and <codeph>TRect</codeph>.</p> </li> <li id="GUID-2ABB347E-A8FD-5D7B-8D83-D15A489DA2A1"><p>The UID Manipulation API class: <codeph>TUid</codeph>.</p> </li> <li id="GUID-F49A0B41-09AB-5802-BECD-E4C855DAF809"><p>The Dynamic Buffers API classes: <codeph>CBufFlat</codeph> and <codeph>CBufSeg</codeph>.</p> </li> </ul> </section> <section><title>Implementation for non-class types</title> <p>For non-class types, for example enumerators, a <i>specialized</i> implementation of the operators must be defined and implemented for that specific non-class type. The definition of the operators must conform to the templated definitions.</p> <p>For example, for a class <codeph>TSimple</codeph> that contains an enumeration of type <codeph>TXxx</codeph> as a data member:</p> <codeblock id="GUID-5B40D0D2-DB8F-57BE-A6F4-C259BDC1190D" xml:space="preserve">    enum  TXxx {EX1,EX2,EX3};</codeblock> <codeblock id="GUID-F6F46E9F-4A96-51C9-B32C-99ACD1303F16" xml:space="preserve">    class TSimple
          {
    public :
          void ExternalizeL(RWriteStream&amp; aStream) const;
          void InternalizeL(RReadStream&amp; aStream);
    public :
          TXxx     iTheEnum;
          ...
          TUint    iUintValue;
          ...
          };</codeblock> <p>The <codeph>iTheEnum</codeph> data member is externalised using <codeph>operator&lt;&lt;</codeph> and internalised using <codeph>operator&gt;&gt;</codeph>:</p> <codeblock id="GUID-0B46A456-336B-5D97-AEF9-49B1043D9C4A" xml:space="preserve">void TSimple::ExternalizeL(RWriteStream&amp; aStream) const
          {
          aStream &lt;&lt; iTheEnum;
          ...
          }</codeblock> <codeblock id="GUID-5F1DC34C-9889-5111-AD53-DB58FE31D1B3" xml:space="preserve">void TSimple::InternalizeL(RReadStream&amp; aStream)
          {
          aStream &gt;&gt; iTheEnum;
          ...
          }</codeblock> <p>As <codeph>TXxx</codeph> is a non-class type, the operators are implemented:</p> <codeblock id="GUID-4A3A0ACC-D6AB-5438-9D73-687DC24F1CFE" xml:space="preserve">RWriteStream&amp; operator&lt;&lt;(RWriteStream&amp; aStream, const TXxx&amp; anXxx)
          {
          aStream.WriteInt8L(anXxx);
          return aStream;
          }</codeblock> <codeblock id="GUID-C1CE1913-1753-59C0-A192-8D79AE369ACD" xml:space="preserve">RReadStream&amp;  operator&gt;&gt;(RReadStream&amp;  aStream, TXxx&amp; anXxx)
          {
          anXxx = TXxx(aStream.ReadInt8L());
          return aStream;
          }</codeblock> <p>The enumerator value is written to the stream using <codeph>RWriteStream::WriteInt8L()</codeph>. Implicit here is the assumption that the enumeration can be represented by just 8 bits.</p> </section> <section><title>Implementation for a class without ExternalizeL() &amp; InternalizeL()</title> <p>The operators may be used on class types that do not define and implement <codeph>InternalizeL()</codeph> and <codeph>ExternalizeL()</codeph> functions. This is done by defining and implementing some extra global functions.</p> <p>In practice, it is much simpler to define and implement <codeph>InternlizeL()</codeph> and <codeph>ExternalizeL()</codeph> for a class, and all new classes should include these functions. However, there may be rare situations, for example, when porting classes, where it may be undesirable to define them.</p> <p>To support the use of the operators for such a class, for example, for the class <codeph>TNonStore</codeph> defined as:</p> <codeblock id="GUID-6ACB011D-36B4-5BDF-8866-9B3C8E33A0B4" xml:space="preserve">    class TNonStore
          {
    public :
          void  SetBuffer(const TDesC&amp; aData);
          TPtrC GetBuffer() const;
    private :
          TBuf&lt;32&gt; iBuffer;
    public :
          TInt     iIntValue;
          TUint    iUintValue;
          TReal    iRealValue;
          };</codeblock> <ul><li id="GUID-BED64035-9CE4-5EEC-93FB-4D71A9E94F99"><p><i>implement</i> the following <codeph>Externalization()</codeph> and <codeph>Internalization()</codeph> <i>global</i> functions:</p> <codeblock id="GUID-417BE16B-9A96-5A74-BDC0-8BD36226DD55" xml:space="preserve">inline Externalize::Function Externalization(const TNonstore*)
          {return Externalize::Function();}</codeblock> <codeblock id="GUID-B087C930-27F5-5A0A-BC77-C3AA41539959" xml:space="preserve">inline Internalize::Function Internalization(TNonstore*)
          {return Internalize::Function();}</codeblock> </li> <li id="GUID-B7ADAB29-0E0A-50F1-AB60-907F142699F5"><p><i>declare</i> the following <codeph>ExternalizeL()</codeph> and <codeph>InternalizeL()</codeph>  <i>global</i> functions:</p> <codeblock id="GUID-A28A8120-0D38-5A56-820A-41527F260523" xml:space="preserve">void ExternalizeL(const TNonstore&amp; aClass,RWriteStream&amp; aStream);</codeblock> <codeblock id="GUID-42046A8B-0DFD-540E-913E-F3D603D327D6" xml:space="preserve">void InternalizeL(TNonstore&amp; aClass,RReadStream&amp; aStream);</codeblock> </li> <li id="GUID-D34FEE7D-37C1-54D0-B9FB-0D9F86F09115"><p><i>implement</i> the <codeph>ExternalizeL()</codeph> and <codeph>InternalizeL()</codeph>  <i>global</i> functions to implement the streaming of <codeph>TNonstore</codeph>'s components. For this example class:</p> <codeblock id="GUID-A6D4AED2-6EA5-5345-B744-A79019470EF6" xml:space="preserve">    void ExternalizeL(const TNonStore&amp; aClass,RWriteStream&amp; aStream)
          {
          aStream.WriteInt32L(aClass.iIntValue);
          aStream.WriteUint32L(aClass.iUintValue);
          aStream.WriteReal64L(aClass.iRealValue);
          aStream &lt;&lt; aClass.GetBuffer();
          }

    void InternalizeL(TNonStore&amp; aClass,RReadStream&amp; aStream)
          {
          aClass.iIntValue  = aStream.ReadInt32L();
          aClass.iUintValue = aStream.ReadUint32L();
          aClass.iRealValue = aStream.ReadReal64L();
          TBuf&lt;32&gt; temp;
          aStream &gt;&gt; temp;
          aClass.SetBuffer(temp);
          }</codeblock> </li> </ul> </section> </conbody></concept>