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
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.