examples/ForumNokia/DescriptorExample/src/OtherBuffers.cpp

00001 /*
00002  * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
00003  *    
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *    
00007  *  * Redistributions of source code must retain the above copyright notice, this
00008  *    list of conditions and the following disclaimer.
00009  *  * Redistributions in binary form must reproduce the above copyright notice,
00010  *    this list of conditions and the following disclaimer in the documentation
00011  *    and/or other materials provided with the distribution.
00012  *  * Neither the name of Nokia Corporation nor the names of its contributors
00013  *    may be used to endorse or promote products derived from this software
00014  *    without specific prior written permission.
00015  *    
00016  *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  *    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  *    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00019  *    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00020  *    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00021  *    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00022  *    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00023  *    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00024  *    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00025  *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026  *    
00027  *    Description:  
00028  */
00029 
00030 
00031 #include <e32std.h>
00032 #include <e32base.h>
00033 #include "DescriptorExamples.h"
00034 #include "StringRenderer.h"
00035 
00036 // -----------------------------------------------------------------------------
00037 // The example class above and helper functions are used by examples.
00038 // -----------------------------------------------------------------------------
00039     class TExample
00040         {
00041         public:
00042             TExample() : iNumber(0), iText() {}
00043             TExample(TInt aNumber, const TDesC &aText);
00044         public:
00045             TInt iNumber;
00046             TBuf<16> iText;
00047         };
00048 
00049     // render message and characteristics of TExample class
00050     // e.g. 'message: 10, "abcd"'
00051     LOCAL_C void ShowContents(const TDesC &aMsg,
00052                               const TExample aExample,
00053                               TPtr &aOutput );
00054 
00055     // render message and contents of given descriptor character data,
00056     // e.g. 'message: "abcd"'
00057     LOCAL_C void ShowContents(const TDesC &aMsg,
00058                               const TDesC &aTxt,
00059                               TPtr &aOutput);
00060 
00061     // render message and contents of given descriptor character data,
00062     // e.g. 'message: "abcd"'
00063     LOCAL_C void ShowContents(const TDesC &aMsg,
00064                               const TDesC8 &aTxt,
00065                               TPtr &aOutput);
00066 
00067     // render number of items in fifo and maximum number of
00068     // items the given fifo can store. e.g. 'fifo: size=1, max=5'.
00069     template <class T>
00070     LOCAL_C void ShowContents(CCirBuf<T> *aFIFO, TPtr &aOutput);
00071 
00072     // Render characteristics of flat dynamic buffer storing 8 bit characters.
00073     // The result is similar to this example:
00074     //
00075     //   CBufFlat: size=8, data @13984184=
00076     //   "abcdefgh"
00077     //
00078     LOCAL_C void ShowBuf(CBufFlat &aBuf, TDes &aOutput);
00079 
00080     // Render characteristics of segmented dynamic buffer storing 8 bit
00081     // characters. The result is similar to this example:
00082     //
00083     // CBufSeg: size=28, segments=
00084     //   "abcdefghij" @13984212
00085     //   "klmnopqrst" @13984248
00086     //   "uvwxyz01" @13984284
00087     //
00088     LOCAL_C void ShowBuf(CBufSeg &aBuf, TDes &aOutput);
00089 
00090     // Render characteristics of package buffer storing TExample object.
00091     // The result is similar to this example:
00092     //
00093     //  TPckgBuf @309000944, sizeof=52, storing
00094     //    TExample @309000952, sizeof=44, iNumber=1234567, iText="Hello!"
00095     //
00096     LOCAL_C void ShowContents(TPckgBuf<TExample> &aPackageBuf, TPtr &aOutput);
00097 
00098     // Render characteristics of package buffer pointer referring to TExample
00099     // object. The result is similar to this example:
00100     //
00101     //  TPckg @309000932, sizeof=12, referring to
00102     //    TExample @309001012, sizeof=44, iNumber=12345, iText="Hello!"
00103     //
00104     LOCAL_C void ShowContents(TPckg<TExample> &aPackage, TPtr &aOutput);
00105 
00106 // Texts for adding and removing operations
00107 _LIT( KAddedMsg, "\nAdded" );
00108 _LIT( KRemovedMsg, "\nRemoved" );
00109 _LIT8( KChars8, "abcdefghijklmnopqrstuvwxyz0123456789" );
00110 
00111 // -----------------------------------------------------------------------------
00112 // This example method is documented in header file "DescriptorExamples.h"
00113 // -----------------------------------------------------------------------------
00114 void CDescriptorExamples::CircularBuffersL()
00115     {
00116     TPtr output( iViewer->GetViewBuffer() );
00117     RenderHeader( _L( "CircularBuffers:TText" ), output );
00118 
00119     // -------------------------------------------------------------------------
00120     // This first example demonstrates how circular buffers can be used to
00121     // buffer character data.
00122     TBuf<10> deletedChars; // stores characters removed from fifo
00123     _LIT( KNumbersTxt, "0123456789" );
00124     // point to first character in character array stored in TLitC
00125     TText *charPtr = (TText*)KNumbersTxt().Ptr();
00126     CCirBuf<TText> *textFIFO;
00127 
00128     // construct fifo able to store up to ten characters:
00129     // contents of fifo is shown below (H=head, T=Tail).
00130     // fifo: data= "__________", count = 0
00131     //              ^
00132     //             H&T
00133     textFIFO = new (ELeave) CCirBuf<TText>();
00134     CleanupStack::PushL( textFIFO );
00135     textFIFO->SetLengthL( 10 ); // can store up to ten characters
00136 
00137     // Copy first 5 items (characters) to fifo
00138     // fifo: data= "01234_____", count = 5
00139     //              ^    ^
00140     //              T    H
00141     textFIFO->Add( charPtr, 5 ); // 01234
00142     ShowContents( KAddedMsg, KNumbersTxt().Left(5), output );
00143     ShowContents( textFIFO, output ); // size=5, max=10
00144 
00145     // remove three items from fifo (first three characters) and
00146     // store copies of them to deletedChars buffer.
00147     // fifo: data= "___34_____", count = 2
00148     //                 ^ ^
00149     //                 T H
00150     textFIFO->Remove( (TText*)deletedChars.Ptr(), 3 ); // chars "012"
00151     deletedChars.SetLength(3);
00152     ShowContents( KRemovedMsg, deletedChars, output );
00153     ShowContents( textFIFO, output ); // size=5, max=10
00154 
00155     // add 6 characters so the head rounds to the beginning.
00156     // fifo: data= "5__3401234", count = 8
00157     //               ^ ^
00158     //               H T
00159     textFIFO->Add( charPtr, 6 ); // 012345
00160     ShowContents( KAddedMsg, KNumbersTxt().Left(6), output );
00161     ShowContents( textFIFO, output ); // size=8, max=10
00162 
00163     // try to add 4 characters. Since there isn't enough space
00164     // only two characters are added since no more room available.
00165     // fifo: data= "5013401234", count = 10
00166     //                 ^
00167     //                H&T
00168     TInt charsAdded = textFIFO->Add( charPtr, 4 ); // 0123
00169     ShowContents( KAddedMsg, KNumbersTxt().Left(4), output );
00170     output.AppendFormat( _L("But only %d characters was really added\n"),
00171                          charsAdded );
00172     ShowContents( textFIFO, output ); // size=10, max=10
00173 
00174     // remove eight items from fifo (now tail rounds to beginning)
00175     // fifo: data= "_01_______", count = 2
00176     //               ^ ^
00177     //               T H
00178     textFIFO->Remove( (TText*)deletedChars.Ptr(), 8 ); // chars "34012345"
00179     deletedChars.SetLength(8);
00180     ShowContents( KRemovedMsg, deletedChars, output );
00181     ShowContents( textFIFO, output ); // size=2, max=10
00182 
00183     // -------------------------------------------------------------------------
00184     // This example introduces how CCirBuf is used to store complex data types.
00185     // Since CCirBuf is templated its items can be any type.
00186     RenderHeader( _L( "CircularBuffers:TExample" ), output );
00187 
00188     // declare pointer to circular buffer (FIFO) that is able
00189     // to store TExample items.
00190     CCirBuf<TExample> *exampleFIFO;
00191     // when items are removed one by one, the copy of deleted item
00192     // is copied to this instance
00193     TExample removedItem;
00194 
00195     // Construct an instance of FIFO that can store up to
00196     // five Example class instances.
00197     exampleFIFO = new (ELeave) CCirBuf<TExample>();
00198     CleanupStack::PushL( exampleFIFO );
00199     exampleFIFO->SetLengthL( 5 );
00200 
00201     // Populate FIFO with three items and show contents
00202     // of added item and state of FIFO.
00203     TExample one(1, _L("one"));
00204     exampleFIFO->Add( &one );
00205     ShowContents( KAddedMsg, one, output );
00206     ShowContents( exampleFIFO, output ); // size=1, max=5
00207 
00208     TExample two(2, _L("two"));
00209     exampleFIFO->Add( &two );
00210     ShowContents( KAddedMsg, two, output );
00211     ShowContents( exampleFIFO, output ); // size=2, max=5
00212 
00213     TExample three(3, _L("three"));
00214     exampleFIFO->Add( &three );
00215     ShowContents( KAddedMsg, three, output );
00216     ShowContents( exampleFIFO, output ); // size=3, max=5
00217 
00218     // Remove item by item from FIFO and show contents of
00219     // removed item and the state of FIFO.
00220     // Remove() method takes a pointer to object where contents
00221     // of removed item is copied (binary copy)
00222     while( exampleFIFO->Count() > 0 )
00223         {
00224         exampleFIFO->Remove( &removedItem );
00225         ShowContents( KRemovedMsg, removedItem, output );
00226         ShowContents( exampleFIFO, output );
00227         }
00228 
00229     iViewer->UpdateView();
00230     CleanupStack::PopAndDestroy(2); // exampleFIFO, textFIFO
00231     }
00232 
00233 // -----------------------------------------------------------------------------
00234 // This example method is documented in header file "DescriptorExamples.h" and
00235 // implementation specific documentation can be read below.
00236 // -----------------------------------------------------------------------------
00237 void CDescriptorExamples::FlatDynamicBuffersL()
00238     {
00239     TPtr output( iViewer->GetViewBuffer() );
00240     RenderHeader( _L( "FlatDynamicBuffers" ), output );
00241 
00242     // -------------------------------------------------------------------------
00243     // When content (8 bit characters) are added to container, it allocates the
00244     // memory automatically. In the first steps it can extend the existing heap
00245     // cell when more space is needed.
00246     //
00247     // However, later in the example a HBufC is allocated from heap to prevent
00248     // heap cell extending. When more data is appended to buffer, a new heap
00249     // cell is allocated from somewhere else, existing content is copied to new
00250     // cell, new content to be appended is added after it and finally the
00251     // existing heap cell is deallocated.
00252     //
00253     // The contents of buffer is shown after each character insertion. The
00254     // location of data (memory address of heap cell) doesn't change until the
00255     // fourth insertion because heap cell can't extend anymore.
00256 
00257     // construct a flat dynamic buffer that will automatically extend its heap
00258     // cell size with 10 bytes when more space is needed.
00259     CBufFlat *buf = CBufFlat::NewL( 10 );
00260     CleanupStack::PushL(buf);
00261 
00262     // this variable is used to refer a portion of characters in KChars8
00263     TPtrC8 charsToInsert(NULL, 0);
00264 
00265     charsToInsert.Set( KChars8().Mid( 0, 8 ) ); // "abcdefgh"
00266     buf->InsertL( 0, charsToInsert );
00267     ShowContents( KAddedMsg, charsToInsert, output );
00268     ShowBuf( *buf, output );
00269 
00270     charsToInsert.Set( KChars8().Mid( 8, 8 ) ); // "ijklmnop"
00271     buf->InsertL( 8, charsToInsert );
00272     ShowContents( KAddedMsg, charsToInsert, output );
00273     ShowBuf( *buf, output );
00274 
00275     charsToInsert.Set( KChars8().Mid( 16, 12 ) ); // "ijklmnop"
00276     buf->InsertL( 16, charsToInsert );
00277     ShowContents( KAddedMsg, charsToInsert, output );
00278     ShowBuf( *buf, output );
00279 
00280     // this object is allocated just after the flat dynamic buffers heap
00281     // cell preventing it to extend its cell size when more space is needed.
00282     HBufC *tmpBuf = HBufC::NewL( 50 );
00283     CleanupStack::PushL( tmpBuf );
00284     tmpBuf->Length(); // remove compiler warning that variable is not used
00285 
00286     // appending this data to buffer requires heap cell to extend.
00287     // tmpBuf prevents heap cell to extend so new cell has to be
00288     // allocated, original data copied to there and existing cell
00289     // to be freed.
00290     charsToInsert.Set( KChars8().Mid( 4, 20 ) ); // "efghijklmnopqrstuvwx"
00291     buf->InsertL(28, charsToInsert );
00292     ShowContents( KAddedMsg, charsToInsert, output );
00293     ShowBuf( *buf, output );
00294 
00295     iViewer->UpdateView();
00296     CleanupStack::PopAndDestroy(2); // tmpBuf, buf
00297     }
00298 
00299 // -----------------------------------------------------------------------------
00300 // This example method is documented in header file "DescriptorExamples.h"
00301 // -----------------------------------------------------------------------------
00302 void CDescriptorExamples::SegmentedDynamicBuffersL()
00303     {
00304     TPtr output( iViewer->GetViewBuffer() );
00305     RenderHeader( _L( "SegmentedDynamicBuffers" ), output );
00306 
00307     // Allocate a empty buffer with granularity of 10
00308     CBufSeg* buf = CBufSeg::NewL(10);
00309     CleanupStack::PushL( buf );
00310 
00311     TPtrC8 charsToInsert(NULL, 0);
00312 
00313     // append "abcdefgh"
00314     // All eight characters fit to first segment
00315     charsToInsert.Set( KChars8().Mid(0, 8) );
00316     buf->InsertL(0, charsToInsert );
00317     ShowContents( KAddedMsg, charsToInsert, output );
00318     ShowBuf( *buf, output );
00319 
00320     // append "ijklmnop"
00321     // first two characters go to the first segment and
00322     // the rest six to second one.
00323     charsToInsert.Set( KChars8().Mid(8, 8) );
00324     buf->InsertL(8, charsToInsert );
00325     ShowContents( KAddedMsg, charsToInsert, output );
00326     ShowBuf( *buf, output );
00327 
00328     // append "qrstuvwxyz01"
00329     // first four characters go to the second segment and
00330     // the rest eight to third one.
00331     charsToInsert.Set( KChars8().Mid(16, 12) );
00332     buf->InsertL(16, charsToInsert );
00333     ShowContents( KAddedMsg, charsToInsert, output );
00334     ShowBuf( *buf, output );
00335 
00336     // append "efghijklmnopqrstuvwx"
00337     // first two characters go to the third segment. Next ten to
00338     // fourth segment and rest eight to fifth segment.
00339     charsToInsert.Set( KChars8().Mid(4, 20) );
00340     buf->InsertL(28, charsToInsert );
00341     ShowContents( KAddedMsg, charsToInsert, output );
00342     ShowBuf( *buf, output );
00343 
00344     // delete a portion from the segmented buffer.
00345     //
00346     // An exmaple run shows that segments before deletion are
00347     //
00348     // CBufSeg: size=48, segments=
00349     //   "abcdefghij" @13984212
00350     //   "klmnopqrst" @13984248
00351     //   "uvwxyz01ef" @13984284
00352     //   "ghijklmnop" @13984356
00353     //   "qrstuvwx" @13984320
00354     //
00355     // and after deletion there are segments:
00356     //
00357     // CBufSeg: size=24, segments=
00358     //   "abc" @13984212
00359     //   "1ef" @13984284
00360     //   "ghijklmnop" @13984356
00361     //   "qrstuvwx" @13984320
00362     //
00363     // From this example it can be seen that modifying segment
00364     // buffer can result segments not fully filled. That's why
00365     // direct access thought pointer is difficult since the
00366     // segment sizes varies.
00367     buf->Delete(3, 24);
00368     output.Append( _L("\nDeleted 24 bytes from index 4\n") );
00369     ShowBuf( *buf, output );
00370 
00371     // Replace character at even index with 'X'
00372     //
00373     // Since data is splitted to segments that may contain variable
00374     // number of character data it would be quite difficult to alter
00375     // data with pointer access. That's why the easiest way to alter
00376     // data is to copy it to fixed sized buffer, modify the copy and
00377     // write modified content over original data.
00378     //
00379     // Since the segmented buffer could be quite long in real problem
00380     // it is better to get used to modify the content in pieces.
00381     //
00382     // Example run produces:
00383     //
00384     // CBufSeg: size=24, segments=
00385     //   "aXc" @13984212
00386     //   "XeX" @13984284
00387     //   "gXiXkXmXoX" @13984356
00388     //   "qXsXuXwX" @13984320
00389     //
00390     TBuf8<20> tmpBuf;
00391     for( TInt i=0; i < buf->Size(); i += tmpBuf.MaxLength() )
00392     {
00393         TInt charsToCopy = buf->Size() - i; // Chars left
00394 
00395         // do not try to read more than tmpBuf can hold
00396         if( charsToCopy > tmpBuf.MaxLength() )
00397             {
00398             charsToCopy = tmpBuf.MaxLength();
00399             }
00400 
00401         // copy data from segmented buffer to descriptor
00402         buf->Read(i, tmpBuf, charsToCopy);
00403 
00404         // Change character in descriptor at even index
00405         for(TInt j=0; j<charsToCopy; j++)
00406             {
00407             if( j % 2 != 0 )
00408                 {
00409                     tmpBuf[j] = 'X';
00410                 }
00411             }
00412 
00413         // write modified content to the same location it was read
00414         buf->Write(i, tmpBuf, charsToCopy);
00415     }
00416     output.Append( _L("\nReplaced characters at even index with 'X'\n") );
00417     ShowBuf( *buf, output );
00418 
00419     // lets compress the data to minimize heap usage: partially
00420     // filled segments are fullfilled and segments no more
00421     // needed are deallocated.
00422     //
00423     // Example run produces:
00424     //
00425     // CBufSeg: size=24, segments=
00426     //   "aXcXeXgXiX" @13984212
00427     //   "kXmXoXqXsX" @13984356
00428     //   "uXwX" @13984320
00429     //
00430     // (first and second segments were fullfilled. There didn't
00431     //  exist any data in fourth segment so if was deleted)
00432     //
00433     buf->Compress();
00434     output.Append( _L("\nCompressed buffer\n") );
00435     ShowBuf( *buf, output );
00436 
00437     iViewer->UpdateView();
00438     CleanupStack::PopAndDestroy(1);
00439     }
00440 
00441 
00442 
00443 // -----------------------------------------------------------------------------
00444 // This example method is documented in header file "DescriptorExamples.h"
00445 // -----------------------------------------------------------------------------
00446 void CDescriptorExamples::PackageBuffers()
00447     {
00448     TPtr output( iViewer->GetViewBuffer() );
00449     // ------------------------------------------------------------
00450     // This first example demonstrates how package buffer is used to
00451     // pack a value class inside.
00452     RenderHeader( _L( "PackageBuffers:TPckgBuf" ), output );
00453 
00454     // construct package buffer that does store one instance of TExample
00455     // instance. The insnce inside is empty since constructor of package
00456     // buffer does call also the constructor of capsulated object
00457     // (constructor of TExample in that case that sets fields to empty).
00458     TPckgBuf<TExample> pckgBuf;
00459     output.Append( _L("\nCreated package buffer that stores an empty (by default) TExample object\n") );
00460 
00461     ShowContents( pckgBuf, output );
00462 
00463     // modify TExample inside package buffer.
00464     //
00465     // To get access to the instance, operator () is used to get
00466     // reference.
00467     TExample &exampleRef = pckgBuf();
00468     exampleRef.iNumber = 1234567;
00469     output.Append( _L("\nModified iNumber of TExample inside package buffer\n") );
00470     ShowContents( pckgBuf, output );
00471 
00472     // modify TExample inside package buffer - using existing reference
00473     exampleRef.iText.Copy( _L( "Hello!" ) );
00474     output.Append( _L("\nModified iText of TExample inside package buffer\n") );
00475     ShowContents( pckgBuf, output );
00476 
00477     // ------------------------------------------------------------
00478     // This second example demonstrates how package buffer pointer is
00479     // used to refer contenst of value class somewhere in memory.
00480     RenderHeader( _L( "PackageBuffers:TPckg" ), output );
00481 
00482     TExample example;
00483     TPckg<TExample> pckg( example );
00484     output.Append( _L("\nCreated package buffer that refers to an empty TExample object\n") );
00485     ShowContents(pckg, output);
00486 
00487     // modify contents the example object. Showing contents of package
00488     // buffer reveals that package buffer did refer to our external
00489     // instance.
00490     example.iNumber = 12345;
00491     example.iText.Copy( _L( "Hello!" ) );
00492     output.Append( _L("\nCreated package buffer that refers to an empty TExample object\n") );
00493     ShowContents(pckg, output);
00494 
00495     iViewer->UpdateView();
00496     }
00497 
00498 void CDescriptorExamples::RBufDemonstrations()
00499     {
00500     // RBuf::CreateL demo
00501     RBuf modifiableBuf;
00502     modifiableBuf.CreateL(12);
00503     ASSERT(modifiableBuf.Length()==0);
00504     ASSERT(modifiableBuf.MaxLength()==12);
00505     modifiableBuf.Close();
00506 
00507     // RBuf::CreateMaxL  demo
00508     modifiableBuf.CreateMaxL(12);
00509     ASSERT(modifiableBuf.Length()==12);
00510     ASSERT(modifiableBuf.MaxLength()==12);
00511     modifiableBuf.Close();
00512 
00513     // RBuf::CreateL passing in a descriptor
00514     _LIT(KHelloWorld, "Hello World");
00515     modifiableBuf.CreateL(KHelloWorld());
00516     ASSERT(modifiableBuf.Length()==11);
00517     ASSERT(modifiableBuf.MaxLength()==11);
00518     modifiableBuf.Close();
00519 
00520     // RBuf::CreateL passing in a descriptor and a maximum length
00521     modifiableBuf.CreateL(KHelloWorld(), 15);
00522     ASSERT(modifiableBuf.Length()==11);
00523     ASSERT(modifiableBuf.MaxLength()==15);
00524     modifiableBuf.Close();
00525 
00526     // RBuf::CreateL and ReAllocL & modifiable descriptor base class methods
00527     _LIT(KHello, "Hello");
00528     _LIT(KWorld, " World");
00529     modifiableBuf.CreateL(5);
00530     modifiableBuf.Copy(KHello());
00531     modifiableBuf.CleanupClosePushL(); // Push onto cleanup stack for leave safety
00532     modifiableBuf.ReAllocL(11);
00533     modifiableBuf.Append(KWorld);
00534     CleanupStack::PopAndDestroy(); // Calls modifiableBuf.Close()
00535 
00536     //RBuf::Assign leaks easily.
00537     //If you have memory allocated in the RBuf and you call Assign it leaks.
00538     //You should always call Close() before calling Assign()
00539     //The same goes with Create functions, if there's memory allocated it leaks.
00540     //modifiableBuf.CreateL(1);    
00541     //modifiableBuf.Close();
00542     HBufC* hBuf = KHello().AllocL();
00543     modifiableBuf.Assign(hBuf); //Take ownership of hBuf memory
00544     ASSERT(modifiableBuf.Length()==5);
00545     modifiableBuf.Close();
00546 
00547     //Assignments demo
00548     RBuf myRBuf1;
00549     RBuf myRBuf2;
00550     HBufC* myHBufC = HBufC::NewL(20);
00551     myRBuf1.Assign(myHBufC); //Take ownership of heap memory
00552     myRBuf2.Assign(myRBuf1); //Take ownership of another RBuf
00553     myRBuf2.Close();
00554     
00555     //Assign, ReAllocL and Append
00556     TUint16* ptr = static_cast<TUint16*> (User::AllocL(5*sizeof(TText)));    
00557     modifiableBuf.Assign(ptr,5);
00558     ASSERT(modifiableBuf.Length()==0);
00559     modifiableBuf.Copy(KHello()); //Copying any more would panic
00560     //modifiableBuf.Append(KWorld);//This  would cause a panic
00561 
00562     modifiableBuf.CleanupClosePushL(); //Push onto cleanup stack for leave safety
00563     modifiableBuf.ReAllocL(12);
00564     modifiableBuf.Append(KWorld);
00565     CleanupStack::PopAndDestroy(); //Calls modifiableBuf.Close() 
00566     }
00567 
00568 // -----------------------------------------------------------------------------
00569 // Implementation of the example class
00570 // -----------------------------------------------------------------------------
00571 TExample::TExample(TInt aNumber, const TDesC &aText)
00572     {
00573         iNumber = aNumber;
00574         iText.Copy(aText.Left( iText.MaxLength() ) );
00575     }
00576 
00577 // -----------------------------------------------------------------------------
00578 // Implementation of the helper functions
00579 // -----------------------------------------------------------------------------
00580 LOCAL_C void ShowContents(const TDesC& aMsg,
00581                           const TExample aExample,
00582                           TPtr &aOutput)
00583     {
00584     _LIT( KFormat, "%S: %d, \"%S\"\n" );
00585     aOutput.AppendFormat( KFormat, &aMsg, aExample.iNumber, &aExample.iText );
00586     }
00587 
00588 LOCAL_C void ShowContents(const TDesC& aMsg, const TDesC &aTxt, TPtr &aOutput)
00589     {
00590     _LIT( KFormat, "%S: \"%S\"\n" );
00591     aOutput.AppendFormat( KFormat, &aMsg, &aTxt );
00592     }
00593 
00594 LOCAL_C void ShowContents(const TDesC& aMsg, const TDesC8 &aTxt, TPtr &aOutput)
00595     {
00596     TBuf<128> buf;
00597     buf.Copy(aTxt.Left(buf.MaxLength()));
00598     _LIT( KFormat, "%S: \"%S\"\n" );
00599     aOutput.AppendFormat( KFormat, &aMsg, &buf );
00600     }
00601 
00602 template <class T>
00603 LOCAL_C void ShowContents(CCirBuf<T> *aFIFO, TPtr &aOutput)
00604     {
00605     _LIT( KFIFOFormat, "fifo: size=%d, max=%d\n" );
00606     aOutput.AppendFormat( KFIFOFormat, aFIFO->Count(), aFIFO->Length() );
00607     }
00608 
00609 LOCAL_C void ShowBuf(CBufFlat &aBuf, TDes &aOutput)
00610     {
00611     TPtrC8 data = aBuf.Ptr(0);
00612     aOutput.AppendFormat( _L("CBufFlat: size=%d, data @%d=\n\""), aBuf.Size(), data.Ptr() );
00613     Append(data, aOutput);
00614     aOutput.Append(_L("\"\n"));
00615     }
00616 
00617 LOCAL_C void ShowBuf(CBufSeg &aBuf, TDes &aOutput)
00618     {
00619     aOutput.AppendFormat( _L("CBufSeg: size=%d, segments=\n"), aBuf.Size() );
00620     TInt pos = 0;
00621     while( pos < aBuf.Size() )
00622         {
00623         TPtrC8 ptr = aBuf.Ptr(pos);
00624         aOutput.Append( _L("  \"") );
00625         Append(ptr, aOutput);
00626         aOutput.AppendFormat( _L("\" @%d\n"), ptr.Ptr() );
00627         pos += ptr.Length();
00628         }
00629     }
00630 
00631 LOCAL_C void ShowContents(TPckgBuf<TExample> &aPackageBuf, TPtr &aOutput)
00632     {
00633     aOutput.AppendFormat( _L( "TPckgBuf @%d, sizeof=%d, storing\n  TExample @%d, sizeof=%d, iNumber=%d, iText=\"%S\"\n" ),
00634         &aPackageBuf, sizeof(aPackageBuf), &aPackageBuf(), sizeof(aPackageBuf()), aPackageBuf().iNumber, &aPackageBuf().iText );
00635     }
00636 
00637 LOCAL_C void ShowContents(TPckg<TExample> &aPackage, TPtr &aOutput)
00638     {
00639     aOutput.AppendFormat( _L( "TPckg @%d, sizeof=%d, referring to\n  TExample @%d, sizeof=%d, iNumber=%d, iText=\"%S\"\n" ),
00640         &aPackage, sizeof(aPackage), &aPackage(), sizeof(aPackage()), aPackage().iNumber, &aPackage().iText );
00641     }
00642 

Generated by  doxygen 1.6.2