--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/buffer/t_bseg.cpp Thu Dec 17 09:24:54 2009 +0200
@@ -0,0 +1,468 @@
+// Copyright (c) 1994-2009 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:
+//
+// Description:
+// e32test\buffer\t_bseg.cpp
+// Overview:
+// Test all aspects of the CBufSeg class.
+// API Information:
+// CBufSeg.
+// Details:
+// - Create a segmented dynamic buffer of specified size.
+// - Test all operations of CBufSeg class and see if methods are implemented --
+// including NewL, Reset, Size, InsertL, Delete, Ptr, BackPtr, Read, Write and Compress.
+// - Test CBufSeg constructor is as expected.
+// - Insert data into the segmented dynamic buffer and verify that InsertL method
+// is as expected using the Read and Write methods.
+// - Delete all data using Reset method and check size is zero.
+// - Test InsertL, Read, Write and Length methods.
+// - Test Ptr, Free, Size, Backptr and SetReserveL methods are as expected.
+// - Check self consistancy of segment lengths, and check contents of segmented
+// buffer using Ptr() and BackPtr().
+// - Verify the size of the of the test buffers are correct.
+// - Insert data into the buffer, delete some data from the beginning, middle and end
+// then check for results as expected.
+// - Verify the data in the buffer before and after Compress method is as expected.
+// Platforms/Drives/Compatibility:
+// All
+// Assumptions/Requirement/Pre-requisites:
+// Failures and causes:
+// Base Port information:
+//
+//
+
+#include <e32test.h>
+
+class TBufSegLink : public TDblQueLink
+ {
+public:
+ inline TBufSegLink() : iLen(0) {}
+ inline TBufSegLink* Next() const {return((TBufSegLink*)iNext);}
+ inline TBufSegLink* Prev() const {return((TBufSegLink*)iPrev);}
+public:
+ TInt iLen;
+ };
+
+class TestCBufSeg
+ {
+public:
+ TestCBufSeg() : iDummy(0) {};
+ void Test1(); // Test all operations of the class.
+ void Test2(); // Inherited Methods
+ void Test3(); // Insert
+ void Test4(); // Delete
+ void Test5(); // Compress
+ void Test6L(); // borderlines
+protected:
+ TInt iDummy;
+ static const TInt SegLen;
+ void CheckSeg(const CBufSeg*);
+ void CheckContents1(CBufSeg* const);
+ void CheckContents2(CBufSeg* const);
+ };
+
+const TInt TestCBufSeg::SegLen=64;
+
+LOCAL_D RTest test(_L("T_BSEG"));
+
+class CSpy : public CBufBase
+ {
+public:
+ ~CSpy();
+protected:
+ CSpy(TInt anExpandSize);
+public:
+ TDblQue<TBufSegLink> iQue;
+ TBufSegLink* iSeg;
+ TInt iBase;
+ TInt iOffset;
+ };
+
+GLDEF_C void TestCBufSeg::CheckSeg(const CBufSeg* bf)
+//
+// Check Self consistancy of segment lengths
+//
+ {
+
+ if (bf->Size()==0)
+ return;
+ TInt sum=0;
+ TBufSegLink* p1=((CSpy*)bf)->iQue.First();
+ while (!((CSpy*)bf)->iQue.IsHead(p1))
+ {
+ test(p1->iLen<=bf->Size());
+ sum+=p1->iLen;
+ p1=p1->Next();
+ }
+ test(sum==bf->Size());
+ sum=0;
+ p1=((CSpy*)bf)->iQue.Last();
+ while (!((CSpy*)bf)->iQue.IsHead(p1))
+ {
+ test(p1->iLen<=bf->Size());
+ sum+=p1->iLen;
+ p1=p1->Prev();
+ }
+ test(sum==bf->Size());
+ }
+
+GLDEF_C void TestCBufSeg::CheckContents1(CBufSeg* const bf)
+//
+// Check contents of segmented buffer using Ptr()
+//
+ {
+
+ TInt sum=0;
+ TInt nbytes=bf->Size();
+ for (TInt pos=0;pos<nbytes;)
+ {
+ TPtr8 p=bf->Ptr(pos);
+ TInt len=p.Length();
+ TInt8* pT=(TInt8*)p.Ptr();
+ for (TInt i=0;i<len;i++)
+ sum+=*pT++;
+ test(sum==0);
+ pos+=len;
+ }
+ }
+
+GLDEF_C void TestCBufSeg::CheckContents2(CBufSeg* const bf)
+//
+// Check contents of segmented buffer using BackPtr()
+//
+ {
+
+ TInt sum=0;
+ TInt nbytes=bf->Size();
+ for(TInt pos=nbytes;pos>0;)
+ {
+ TPtr8 p=bf->BackPtr(pos);
+ TInt len=p.Length();
+ TInt8* pT=(TInt8*)p.Ptr();
+ for (TInt i=0;i<len;i++)
+ sum+=*pT++;
+ pos-=len;
+ }
+ test(sum==0);
+ }
+
+GLDEF_C void TestCBufSeg::Test1()
+//
+// Test all operations of BufSeg class
+//
+ {
+
+ test.Start(_L("Test all operations of CBufSeg"));
+ CBufSeg* bf=(CBufSeg*)CBufSeg::NewL(100);
+ bf->Reset();
+ bf->Size();
+ bf->InsertL(0,TPtrC8((TText8*)"Hello World"));
+ bf->Delete(0,5);
+ TText8* tp=(TText8*)bf->Ptr(3).Ptr();
+ tp=(TText8*)bf->BackPtr(3).Ptr();
+ TBuf8<0x20> txt;
+ bf->Read(2,txt,2);
+ bf->Write(2,txt,2);
+ bf->Compress();
+ delete bf;
+ test.End();
+ }
+
+GLDEF_C void TestCBufSeg::Test2()
+//
+// Test all inherited methods
+//
+ {
+
+ TBuf8<0x40> tb1=(TText8*)"Hello World";
+ TBuf8<0x40> tb2=(TText8*)"String number two";
+ TBuf8<0x40> tb3;
+ test.Start(_L("Free,Size,Read,Write,Reset"));
+ CBufSeg* bf=(CBufSeg*)CBufSeg::NewL(SegLen);
+ test(bf->Size()==0);
+ bf->InsertL(0,tb1);
+ test(bf->Size()==tb1.Length());
+ bf->Read(6,tb3,5);
+ test(tb3==tb1.Right(5));
+ bf->Write(1,tb2,6);
+ bf->Read(0,tb3,bf->Size());
+ test(tb3==TPtrC8((TText8*)"HStringorld"));
+ bf->Reset();
+ test(bf->Size()==0);
+ while (bf->Size()<400)
+ {
+ bf->InsertL(bf->Size(),tb1);
+ bf->InsertL(bf->Size(),tb2);
+ }
+ TInt i=0;
+ while (i<400)
+ {
+ bf->Read(i,tb3,tb1.Size());
+ test(tb3==tb1);
+ i+=tb1.Length();
+ bf->Read(i,tb3,tb2.Size());
+ test(tb3==tb2);
+ i+=tb2.Length();
+ }
+ i=0;
+ while (i<400)
+ {
+ bf->Write(i,tb2);
+ i+=tb2.Length();
+ bf->Write(i,tb1);
+ i+=tb1.Length();
+ }
+ i=0;
+ while (i<400)
+ {
+ bf->Read(i,tb3,tb2.Size());
+ test(tb3==tb2);
+ i+=tb2.Length();
+ bf->Read(i,tb3,tb1.Size());
+ test(tb3==tb1);
+ i+=tb1.Length();
+ }
+ delete bf;
+ test.End();
+ }
+
+GLDEF_C void TestCBufSeg::Test3()
+//
+// Test input methods
+//
+ {
+
+ TInt8 bb[1000];
+ TInt nbytes;
+ test.Start(_L("InsertL"));
+ CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen);
+ CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen);
+ CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen);
+ nbytes=0;
+ TInt k;
+ for(TInt j=0;j<20;j++)
+ {
+ for(TInt i=0;i<10*j;i+=2)
+ {
+ k=i%128;
+ bb[i]=(TInt8)k;
+ bb[i+1]=(TInt8)-k;
+ }
+ bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j);
+ CheckSeg(bf1);
+ CheckContents1(bf1);
+ CheckContents2(bf1);
+ bf2->InsertL(bf2->Size(),&bb[0],10*j);
+ CheckSeg(bf2);
+ CheckContents1(bf2);
+ CheckContents2(bf2);
+ bf3->InsertL(0,&bb[0],10*j);
+ CheckSeg(bf3);
+ CheckContents1(bf3);
+ CheckContents2(bf3);
+ nbytes+=10*j;
+ }
+ test(nbytes==bf1->Size());
+ test(nbytes==bf2->Size());
+ test(nbytes==bf3->Size());
+ delete bf1;
+ delete bf2;
+ delete bf3;
+ test.End();
+ }
+
+GLDEF_C void TestCBufSeg::Test4()
+//
+// Delete
+//
+ {
+ TInt8 bb[1000];
+
+ test.Start(_L("Delete"));
+ CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen);
+ CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen);
+ CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen);
+ TInt nbytes=0;
+ TInt k;
+ for(TInt j=0;j<20;j++)
+ {
+ for(TInt i=0;i<10*j;i+=2)
+ {
+ k=i%128;
+ bb[i]=(TInt8)k;
+ bb[i+1]=(TInt8)-k;
+ }
+ bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j);
+ bf2->InsertL(bf2->Size(),&bb[0],10*j);
+ bf3->InsertL(0,&bb[0],10*j);
+ nbytes+=10*j;
+ }
+ TInt len=34;
+ TInt aLength;
+ while (nbytes>len)
+ {
+ for (TInt pos=0;pos<nbytes;pos+=44)
+ {
+ len=((len+17)%23)*2;
+ if (len>nbytes-pos)
+ len=nbytes-pos;
+ bf1->Delete(pos,len);
+ CheckSeg(bf1);
+ CheckContents1(bf1);
+ CheckContents2(bf1);
+ aLength=bf2->Ptr(0).Length();
+ aLength=((aLength>len) ? aLength : len);
+ bf2->Delete(aLength-len,len);
+ CheckSeg(bf2);
+ CheckContents1(bf2);
+ CheckContents2(bf2);
+ bf3->Delete(0,len);
+ CheckSeg(bf3);
+ CheckContents1(bf3);
+ CheckContents2(bf3);
+ nbytes-=len;
+ test(nbytes==bf1->Size());
+ test(nbytes==bf2->Size());
+ test(nbytes==bf3->Size());
+ }
+ }
+ delete bf1;
+ delete bf2;
+ delete bf3;
+ test.End();
+ }
+
+GLDEF_C void TestCBufSeg::Test5()
+//
+// Compress
+//
+ {
+ TInt8 bb[1000];
+
+ test.Start(_L("Compress"));
+ CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen);
+ CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen);
+ CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen);
+ TInt nbytes=0;
+ TInt k;
+ for(TInt j=0;j<20;j++)
+ {
+ for(TInt i=0;i<10*j;i+=2)
+ {
+ k=i%128;
+ bb[i]=(TInt8)k;
+ bb[i+1]=(TInt8)-k;
+ }
+ bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j);
+ bf2->InsertL(bf2->Size(),&bb[0],10*j);
+ bf3->InsertL(0,&bb[0],10*j);
+ nbytes+=10*j;
+ }
+ TInt len=34;
+ TInt aLength;
+ while (nbytes>len)
+ {
+ for (TInt pos=0;pos<nbytes;pos+=44)
+ {
+ if (len>nbytes-pos)
+ len=nbytes-pos;
+ bf1->Delete(pos,len);
+ bf1->Compress();
+ CheckSeg(bf1);
+ CheckContents1(bf1);
+ CheckContents2(bf1);
+ aLength=bf2->Ptr(0).Length();
+ aLength=((aLength>len)? aLength : len);
+ bf2->Delete(aLength-len,len);
+ bf2->Compress();
+ CheckSeg(bf2);
+ CheckContents1(bf2);
+ CheckContents2(bf2);
+ bf3->Delete(0,len);
+ bf3->Compress();
+ CheckSeg(bf3);
+ CheckContents1(bf3);
+ CheckContents2(bf3);
+ nbytes-=len;
+ test(nbytes==bf1->Size());
+ test(nbytes==bf2->Size());
+ test(nbytes==bf3->Size());
+ }
+ }
+ delete bf1;
+ delete bf2;
+ delete bf3;
+ test.End();
+ }
+
+void TestCBufSeg::Test6L()
+ {
+ test.Start(_L("Test compress frees empty cells"));
+ __UHEAP_MARK;
+ TUint8 alphabet[27] = "abcdefghijklmnopqrstuvwxyz";
+ CBufSeg* buf = CBufSeg::NewL(10);
+ CleanupStack::PushL(buf);
+ buf->InsertL(0, alphabet, 16); // "abcdefghij" ++ "klmnop"
+ buf->Delete(5, 5); // "abcde" ++ "klmnop"
+ buf->Delete(10, 1); // "abcde" ++ "klmno"
+ buf->Compress(); // "abcdefklmno". i.e. empty cell should be freed.
+ CleanupStack::PopAndDestroy(buf);
+ __UHEAP_MARKEND;
+ test.End();
+ }
+
+LOCAL_C void test_CBufSeg()
+//
+// Test the BufSeg class
+//
+ {
+
+ TestCBufSeg b;
+ test.Start(_L("All operations"));
+ b.Test1();
+ test.Next(_L("Inherited Methods"));
+ b.Test2();
+ test.Next(_L("Insert"));
+ b.Test3();
+ test.Next(_L("Delete"));
+ b.Test4();
+ test.Next(_L("Compress"));
+ b.Test5();
+ test.Next(_L("Bordeline cases"));
+ TRAPD(r,b.Test6L());
+ test(r==KErrNone);
+ //
+ test.End();
+ }
+
+GLDEF_C TInt E32Main()
+//
+// Test the ADT segmented varray.
+//
+ {
+
+ test.Title();
+ __UHEAP_MARK;
+//
+// Install a trap handler
+//
+ CTrapCleanup* trapHandler=CTrapCleanup::New();
+ test(trapHandler!=NULL);
+// CleanupStack::NextLevel();
+ test.Start(_L("class CBufSeg"));
+ test_CBufSeg();
+ delete trapHandler;
+ __UHEAP_MARKEND;
+ test.End();
+ return(0);
+ }
+