examples/ForumNokia/DescriptorExample/src/OtherBuffers.cpp

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

Generated by  doxygen 1.6.2