sl@0: // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\buffer\t_bseg.cpp sl@0: // Overview: sl@0: // Test all aspects of the CBufSeg class. sl@0: // API Information: sl@0: // CBufSeg. sl@0: // Details: sl@0: // - Create a segmented dynamic buffer of specified size. sl@0: // - Test all operations of CBufSeg class and see if methods are implemented -- sl@0: // including NewL, Reset, Size, InsertL, Delete, Ptr, BackPtr, Read, Write and Compress. sl@0: // - Test CBufSeg constructor is as expected. sl@0: // - Insert data into the segmented dynamic buffer and verify that InsertL method sl@0: // is as expected using the Read and Write methods. sl@0: // - Delete all data using Reset method and check size is zero. sl@0: // - Test InsertL, Read, Write and Length methods. sl@0: // - Test Ptr, Free, Size, Backptr and SetReserveL methods are as expected. sl@0: // - Check self consistancy of segment lengths, and check contents of segmented sl@0: // buffer using Ptr() and BackPtr(). sl@0: // - Verify the size of the of the test buffers are correct. sl@0: // - Insert data into the buffer, delete some data from the beginning, middle and end sl@0: // then check for results as expected. sl@0: // - Verify the data in the buffer before and after Compress method is as expected. sl@0: // Platforms/Drives/Compatibility: sl@0: // All sl@0: // Assumptions/Requirement/Pre-requisites: sl@0: // Failures and causes: sl@0: // Base Port information: sl@0: // sl@0: // sl@0: sl@0: #include sl@0: sl@0: class TBufSegLink : public TDblQueLink sl@0: { sl@0: public: sl@0: inline TBufSegLink() : iLen(0) {} sl@0: inline TBufSegLink* Next() const {return((TBufSegLink*)iNext);} sl@0: inline TBufSegLink* Prev() const {return((TBufSegLink*)iPrev);} sl@0: public: sl@0: TInt iLen; sl@0: }; sl@0: sl@0: class TestCBufSeg sl@0: { sl@0: public: sl@0: TestCBufSeg() : iDummy(0) {}; sl@0: void Test1(); // Test all operations of the class. sl@0: void Test2(); // Inherited Methods sl@0: void Test3(); // Insert sl@0: void Test4(); // Delete sl@0: void Test5(); // Compress sl@0: void Test6L(); // borderlines sl@0: protected: sl@0: TInt iDummy; sl@0: static const TInt SegLen; sl@0: void CheckSeg(const CBufSeg*); sl@0: void CheckContents1(CBufSeg* const); sl@0: void CheckContents2(CBufSeg* const); sl@0: }; sl@0: sl@0: const TInt TestCBufSeg::SegLen=64; sl@0: sl@0: LOCAL_D RTest test(_L("T_BSEG")); sl@0: sl@0: class CSpy : public CBufBase sl@0: { sl@0: public: sl@0: ~CSpy(); sl@0: protected: sl@0: CSpy(TInt anExpandSize); sl@0: public: sl@0: TDblQue iQue; sl@0: TBufSegLink* iSeg; sl@0: TInt iBase; sl@0: TInt iOffset; sl@0: }; sl@0: sl@0: GLDEF_C void TestCBufSeg::CheckSeg(const CBufSeg* bf) sl@0: // sl@0: // Check Self consistancy of segment lengths sl@0: // sl@0: { sl@0: sl@0: if (bf->Size()==0) sl@0: return; sl@0: TInt sum=0; sl@0: TBufSegLink* p1=((CSpy*)bf)->iQue.First(); sl@0: while (!((CSpy*)bf)->iQue.IsHead(p1)) sl@0: { sl@0: test(p1->iLen<=bf->Size()); sl@0: sum+=p1->iLen; sl@0: p1=p1->Next(); sl@0: } sl@0: test(sum==bf->Size()); sl@0: sum=0; sl@0: p1=((CSpy*)bf)->iQue.Last(); sl@0: while (!((CSpy*)bf)->iQue.IsHead(p1)) sl@0: { sl@0: test(p1->iLen<=bf->Size()); sl@0: sum+=p1->iLen; sl@0: p1=p1->Prev(); sl@0: } sl@0: test(sum==bf->Size()); sl@0: } sl@0: sl@0: GLDEF_C void TestCBufSeg::CheckContents1(CBufSeg* const bf) sl@0: // sl@0: // Check contents of segmented buffer using Ptr() sl@0: // sl@0: { sl@0: sl@0: TInt sum=0; sl@0: TInt nbytes=bf->Size(); sl@0: for (TInt pos=0;posPtr(pos); sl@0: TInt len=p.Length(); sl@0: TInt8* pT=(TInt8*)p.Ptr(); sl@0: for (TInt i=0;iSize(); sl@0: for(TInt pos=nbytes;pos>0;) sl@0: { sl@0: TPtr8 p=bf->BackPtr(pos); sl@0: TInt len=p.Length(); sl@0: TInt8* pT=(TInt8*)p.Ptr(); sl@0: for (TInt i=0;iReset(); sl@0: bf->Size(); sl@0: bf->InsertL(0,TPtrC8((TText8*)"Hello World")); sl@0: bf->Delete(0,5); sl@0: TText8* tp=(TText8*)bf->Ptr(3).Ptr(); sl@0: tp=(TText8*)bf->BackPtr(3).Ptr(); sl@0: TBuf8<0x20> txt; sl@0: bf->Read(2,txt,2); sl@0: bf->Write(2,txt,2); sl@0: bf->Compress(); sl@0: delete bf; sl@0: test.End(); sl@0: } sl@0: sl@0: GLDEF_C void TestCBufSeg::Test2() sl@0: // sl@0: // Test all inherited methods sl@0: // sl@0: { sl@0: sl@0: TBuf8<0x40> tb1=(TText8*)"Hello World"; sl@0: TBuf8<0x40> tb2=(TText8*)"String number two"; sl@0: TBuf8<0x40> tb3; sl@0: test.Start(_L("Free,Size,Read,Write,Reset")); sl@0: CBufSeg* bf=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: test(bf->Size()==0); sl@0: bf->InsertL(0,tb1); sl@0: test(bf->Size()==tb1.Length()); sl@0: bf->Read(6,tb3,5); sl@0: test(tb3==tb1.Right(5)); sl@0: bf->Write(1,tb2,6); sl@0: bf->Read(0,tb3,bf->Size()); sl@0: test(tb3==TPtrC8((TText8*)"HStringorld")); sl@0: bf->Reset(); sl@0: test(bf->Size()==0); sl@0: while (bf->Size()<400) sl@0: { sl@0: bf->InsertL(bf->Size(),tb1); sl@0: bf->InsertL(bf->Size(),tb2); sl@0: } sl@0: TInt i=0; sl@0: while (i<400) sl@0: { sl@0: bf->Read(i,tb3,tb1.Size()); sl@0: test(tb3==tb1); sl@0: i+=tb1.Length(); sl@0: bf->Read(i,tb3,tb2.Size()); sl@0: test(tb3==tb2); sl@0: i+=tb2.Length(); sl@0: } sl@0: i=0; sl@0: while (i<400) sl@0: { sl@0: bf->Write(i,tb2); sl@0: i+=tb2.Length(); sl@0: bf->Write(i,tb1); sl@0: i+=tb1.Length(); sl@0: } sl@0: i=0; sl@0: while (i<400) sl@0: { sl@0: bf->Read(i,tb3,tb2.Size()); sl@0: test(tb3==tb2); sl@0: i+=tb2.Length(); sl@0: bf->Read(i,tb3,tb1.Size()); sl@0: test(tb3==tb1); sl@0: i+=tb1.Length(); sl@0: } sl@0: delete bf; sl@0: test.End(); sl@0: } sl@0: sl@0: GLDEF_C void TestCBufSeg::Test3() sl@0: // sl@0: // Test input methods sl@0: // sl@0: { sl@0: sl@0: TInt8 bb[1000]; sl@0: TInt nbytes; sl@0: test.Start(_L("InsertL")); sl@0: CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: nbytes=0; sl@0: TInt k; sl@0: for(TInt j=0;j<20;j++) sl@0: { sl@0: for(TInt i=0;i<10*j;i+=2) sl@0: { sl@0: k=i%128; sl@0: bb[i]=(TInt8)k; sl@0: bb[i+1]=(TInt8)-k; sl@0: } sl@0: bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j); sl@0: CheckSeg(bf1); sl@0: CheckContents1(bf1); sl@0: CheckContents2(bf1); sl@0: bf2->InsertL(bf2->Size(),&bb[0],10*j); sl@0: CheckSeg(bf2); sl@0: CheckContents1(bf2); sl@0: CheckContents2(bf2); sl@0: bf3->InsertL(0,&bb[0],10*j); sl@0: CheckSeg(bf3); sl@0: CheckContents1(bf3); sl@0: CheckContents2(bf3); sl@0: nbytes+=10*j; sl@0: } sl@0: test(nbytes==bf1->Size()); sl@0: test(nbytes==bf2->Size()); sl@0: test(nbytes==bf3->Size()); sl@0: delete bf1; sl@0: delete bf2; sl@0: delete bf3; sl@0: test.End(); sl@0: } sl@0: sl@0: GLDEF_C void TestCBufSeg::Test4() sl@0: // sl@0: // Delete sl@0: // sl@0: { sl@0: TInt8 bb[1000]; sl@0: sl@0: test.Start(_L("Delete")); sl@0: CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: TInt nbytes=0; sl@0: TInt k; sl@0: for(TInt j=0;j<20;j++) sl@0: { sl@0: for(TInt i=0;i<10*j;i+=2) sl@0: { sl@0: k=i%128; sl@0: bb[i]=(TInt8)k; sl@0: bb[i+1]=(TInt8)-k; sl@0: } sl@0: bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j); sl@0: bf2->InsertL(bf2->Size(),&bb[0],10*j); sl@0: bf3->InsertL(0,&bb[0],10*j); sl@0: nbytes+=10*j; sl@0: } sl@0: TInt len=34; sl@0: TInt aLength; sl@0: while (nbytes>len) sl@0: { sl@0: for (TInt pos=0;posnbytes-pos) sl@0: len=nbytes-pos; sl@0: bf1->Delete(pos,len); sl@0: CheckSeg(bf1); sl@0: CheckContents1(bf1); sl@0: CheckContents2(bf1); sl@0: aLength=bf2->Ptr(0).Length(); sl@0: aLength=((aLength>len) ? aLength : len); sl@0: bf2->Delete(aLength-len,len); sl@0: CheckSeg(bf2); sl@0: CheckContents1(bf2); sl@0: CheckContents2(bf2); sl@0: bf3->Delete(0,len); sl@0: CheckSeg(bf3); sl@0: CheckContents1(bf3); sl@0: CheckContents2(bf3); sl@0: nbytes-=len; sl@0: test(nbytes==bf1->Size()); sl@0: test(nbytes==bf2->Size()); sl@0: test(nbytes==bf3->Size()); sl@0: } sl@0: } sl@0: delete bf1; sl@0: delete bf2; sl@0: delete bf3; sl@0: test.End(); sl@0: } sl@0: sl@0: GLDEF_C void TestCBufSeg::Test5() sl@0: // sl@0: // Compress sl@0: // sl@0: { sl@0: TInt8 bb[1000]; sl@0: sl@0: test.Start(_L("Compress")); sl@0: CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen); sl@0: TInt nbytes=0; sl@0: TInt k; sl@0: for(TInt j=0;j<20;j++) sl@0: { sl@0: for(TInt i=0;i<10*j;i+=2) sl@0: { sl@0: k=i%128; sl@0: bb[i]=(TInt8)k; sl@0: bb[i+1]=(TInt8)-k; sl@0: } sl@0: bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j); sl@0: bf2->InsertL(bf2->Size(),&bb[0],10*j); sl@0: bf3->InsertL(0,&bb[0],10*j); sl@0: nbytes+=10*j; sl@0: } sl@0: TInt len=34; sl@0: TInt aLength; sl@0: while (nbytes>len) sl@0: { sl@0: for (TInt pos=0;posnbytes-pos) sl@0: len=nbytes-pos; sl@0: bf1->Delete(pos,len); sl@0: bf1->Compress(); sl@0: CheckSeg(bf1); sl@0: CheckContents1(bf1); sl@0: CheckContents2(bf1); sl@0: aLength=bf2->Ptr(0).Length(); sl@0: aLength=((aLength>len)? aLength : len); sl@0: bf2->Delete(aLength-len,len); sl@0: bf2->Compress(); sl@0: CheckSeg(bf2); sl@0: CheckContents1(bf2); sl@0: CheckContents2(bf2); sl@0: bf3->Delete(0,len); sl@0: bf3->Compress(); sl@0: CheckSeg(bf3); sl@0: CheckContents1(bf3); sl@0: CheckContents2(bf3); sl@0: nbytes-=len; sl@0: test(nbytes==bf1->Size()); sl@0: test(nbytes==bf2->Size()); sl@0: test(nbytes==bf3->Size()); sl@0: } sl@0: } sl@0: delete bf1; sl@0: delete bf2; sl@0: delete bf3; sl@0: test.End(); sl@0: } sl@0: sl@0: void TestCBufSeg::Test6L() sl@0: { sl@0: test.Start(_L("Test compress frees empty cells")); sl@0: __UHEAP_MARK; sl@0: TUint8 alphabet[27] = "abcdefghijklmnopqrstuvwxyz"; sl@0: CBufSeg* buf = CBufSeg::NewL(10); sl@0: CleanupStack::PushL(buf); sl@0: buf->InsertL(0, alphabet, 16); // "abcdefghij" ++ "klmnop" sl@0: buf->Delete(5, 5); // "abcde" ++ "klmnop" sl@0: buf->Delete(10, 1); // "abcde" ++ "klmno" sl@0: buf->Compress(); // "abcdefklmno". i.e. empty cell should be freed. sl@0: CleanupStack::PopAndDestroy(buf); sl@0: __UHEAP_MARKEND; sl@0: test.End(); sl@0: } sl@0: sl@0: LOCAL_C void test_CBufSeg() sl@0: // sl@0: // Test the BufSeg class sl@0: // sl@0: { sl@0: sl@0: TestCBufSeg b; sl@0: test.Start(_L("All operations")); sl@0: b.Test1(); sl@0: test.Next(_L("Inherited Methods")); sl@0: b.Test2(); sl@0: test.Next(_L("Insert")); sl@0: b.Test3(); sl@0: test.Next(_L("Delete")); sl@0: b.Test4(); sl@0: test.Next(_L("Compress")); sl@0: b.Test5(); sl@0: test.Next(_L("Bordeline cases")); sl@0: TRAPD(r,b.Test6L()); sl@0: test(r==KErrNone); sl@0: // sl@0: test.End(); sl@0: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: // sl@0: // Test the ADT segmented varray. sl@0: // sl@0: { sl@0: sl@0: test.Title(); sl@0: __UHEAP_MARK; sl@0: // sl@0: // Install a trap handler sl@0: // sl@0: CTrapCleanup* trapHandler=CTrapCleanup::New(); sl@0: test(trapHandler!=NULL); sl@0: // CleanupStack::NextLevel(); sl@0: test.Start(_L("class CBufSeg")); sl@0: test_CBufSeg(); sl@0: delete trapHandler; sl@0: __UHEAP_MARKEND; sl@0: test.End(); sl@0: return(0); sl@0: } sl@0: