os/kernelhwsrv/kerneltest/e32test/buffer/t_bseg.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\buffer\t_bseg.cpp
    15 // Overview:
    16 // Test all aspects of the CBufSeg class.
    17 // API Information:
    18 // CBufSeg.
    19 // Details:
    20 // - Create a segmented dynamic buffer of specified size.
    21 // - Test all operations of CBufSeg class and see if methods are implemented -- 
    22 // including NewL, Reset, Size, InsertL, Delete, Ptr, BackPtr, Read, Write and Compress.
    23 // - Test CBufSeg constructor is as expected.
    24 // - Insert data into the segmented dynamic buffer and verify that InsertL method
    25 // is as expected using the Read and Write methods.
    26 // - Delete all data using Reset method and check size is zero.
    27 // - Test InsertL, Read, Write and Length methods.
    28 // - Test Ptr, Free, Size, Backptr and SetReserveL methods are as expected.
    29 // - Check self consistancy of segment lengths, and check contents of segmented 
    30 // buffer using Ptr() and BackPtr().
    31 // - Verify the size of the of the test buffers are correct.
    32 // - Insert data into the buffer, delete some data from the beginning, middle and end
    33 // then check for results as expected. 
    34 // - Verify the data in the buffer before and after Compress method is as expected.
    35 // Platforms/Drives/Compatibility:
    36 // All 
    37 // Assumptions/Requirement/Pre-requisites:
    38 // Failures and causes:
    39 // Base Port information:
    40 // 
    41 //
    42 
    43 #include <e32test.h>
    44 
    45 class TBufSegLink : public TDblQueLink
    46 	{
    47 public:
    48 	inline TBufSegLink() : iLen(0) {}
    49 	inline TBufSegLink* Next() const {return((TBufSegLink*)iNext);}
    50 	inline TBufSegLink* Prev() const {return((TBufSegLink*)iPrev);}
    51 public:
    52 	TInt iLen;
    53 	};
    54 
    55 class TestCBufSeg
    56 	{
    57 public:
    58 	TestCBufSeg() : iDummy(0) {};
    59 	void Test1(); 	// Test all operations of the class.
    60 	void Test2();	// Inherited Methods
    61 	void Test3();	// Insert	
    62 	void Test4();	// Delete
    63 	void Test5();	// Compress
    64 	void Test6L();	// borderlines
    65 protected:
    66 	TInt iDummy;
    67 	static const TInt SegLen;
    68 	void CheckSeg(const CBufSeg*);
    69 	void CheckContents1(CBufSeg* const);
    70 	void CheckContents2(CBufSeg* const);
    71 	};
    72 
    73 const TInt TestCBufSeg::SegLen=64;
    74 
    75 LOCAL_D RTest test(_L("T_BSEG"));
    76 
    77 class CSpy : public CBufBase
    78 	{
    79 public:
    80 	~CSpy();
    81 protected:
    82 	CSpy(TInt anExpandSize);
    83 public:
    84     TDblQue<TBufSegLink> iQue;
    85 	TBufSegLink* iSeg;
    86 	TInt iBase;
    87 	TInt iOffset;
    88 	};
    89 
    90 GLDEF_C void TestCBufSeg::CheckSeg(const CBufSeg* bf)
    91 //
    92 // Check Self consistancy of segment lengths
    93 //
    94 	{
    95 
    96 	if (bf->Size()==0)
    97 		return;
    98 	TInt sum=0;
    99 	TBufSegLink* p1=((CSpy*)bf)->iQue.First();
   100 	while (!((CSpy*)bf)->iQue.IsHead(p1))
   101 		{
   102 		test(p1->iLen<=bf->Size());
   103 		sum+=p1->iLen;
   104 		p1=p1->Next();
   105 		} 
   106 	test(sum==bf->Size());
   107 	sum=0;
   108 	p1=((CSpy*)bf)->iQue.Last();
   109 	while (!((CSpy*)bf)->iQue.IsHead(p1))
   110 		{
   111 		test(p1->iLen<=bf->Size());
   112 		sum+=p1->iLen;
   113 		p1=p1->Prev();
   114 		}
   115 	test(sum==bf->Size());
   116 	}
   117 
   118 GLDEF_C void TestCBufSeg::CheckContents1(CBufSeg* const bf)
   119 //
   120 // Check contents of segmented buffer using Ptr()
   121 //
   122 	{
   123 
   124 	TInt sum=0;
   125 	TInt nbytes=bf->Size();
   126 	for (TInt pos=0;pos<nbytes;)
   127 		{
   128 		TPtr8 p=bf->Ptr(pos);
   129 		TInt len=p.Length();
   130 		TInt8* pT=(TInt8*)p.Ptr();
   131 		for (TInt i=0;i<len;i++)
   132 			sum+=*pT++;
   133 		test(sum==0);
   134 		pos+=len;
   135 		}
   136 	}
   137 
   138 GLDEF_C void TestCBufSeg::CheckContents2(CBufSeg* const bf)
   139 //
   140 // Check contents of segmented buffer using BackPtr()
   141 //
   142 	{
   143 
   144 	TInt sum=0;
   145 	TInt nbytes=bf->Size();
   146 	for(TInt pos=nbytes;pos>0;)
   147 		{
   148 		TPtr8 p=bf->BackPtr(pos);
   149 		TInt len=p.Length();
   150 		TInt8* pT=(TInt8*)p.Ptr();
   151 		for (TInt i=0;i<len;i++)
   152 			sum+=*pT++;
   153 		pos-=len;
   154 		}
   155 	test(sum==0);
   156 	}
   157 
   158 GLDEF_C void TestCBufSeg::Test1()
   159 //
   160 // Test all operations of BufSeg class
   161 //
   162 	{
   163 
   164 	test.Start(_L("Test all operations of CBufSeg"));
   165 	CBufSeg* bf=(CBufSeg*)CBufSeg::NewL(100);
   166 	bf->Reset();
   167 	bf->Size();
   168 	bf->InsertL(0,TPtrC8((TText8*)"Hello World"));
   169 	bf->Delete(0,5);
   170 	TText8* tp=(TText8*)bf->Ptr(3).Ptr();
   171 	tp=(TText8*)bf->BackPtr(3).Ptr();
   172 	TBuf8<0x20> txt;
   173 	bf->Read(2,txt,2);
   174 	bf->Write(2,txt,2);
   175 	bf->Compress();
   176 	delete bf;
   177 	test.End();
   178 	}
   179 			
   180 GLDEF_C void TestCBufSeg::Test2()
   181 //
   182 // Test all inherited methods
   183 //
   184 	{
   185 
   186 	TBuf8<0x40> tb1=(TText8*)"Hello World";
   187 	TBuf8<0x40> tb2=(TText8*)"String number two";
   188 	TBuf8<0x40> tb3;
   189 	test.Start(_L("Free,Size,Read,Write,Reset"));
   190 	CBufSeg* bf=(CBufSeg*)CBufSeg::NewL(SegLen);
   191 	test(bf->Size()==0);
   192 	bf->InsertL(0,tb1);
   193 	test(bf->Size()==tb1.Length());
   194 	bf->Read(6,tb3,5);
   195 	test(tb3==tb1.Right(5));
   196 	bf->Write(1,tb2,6);
   197 	bf->Read(0,tb3,bf->Size());
   198 	test(tb3==TPtrC8((TText8*)"HStringorld"));
   199 	bf->Reset();
   200 	test(bf->Size()==0);
   201 	while (bf->Size()<400)
   202 		{
   203 		bf->InsertL(bf->Size(),tb1);
   204 		bf->InsertL(bf->Size(),tb2);
   205 		}
   206 	TInt i=0;
   207 	while (i<400)
   208 		{
   209 		bf->Read(i,tb3,tb1.Size());
   210 		test(tb3==tb1);
   211 		i+=tb1.Length();
   212 		bf->Read(i,tb3,tb2.Size());
   213 		test(tb3==tb2);
   214 		i+=tb2.Length();
   215 		}
   216 	i=0;
   217 	while (i<400)
   218 		{
   219 		bf->Write(i,tb2);
   220 		i+=tb2.Length();
   221 		bf->Write(i,tb1);
   222 		i+=tb1.Length();
   223 		}
   224 	i=0;
   225 	while (i<400)
   226 		{
   227 		bf->Read(i,tb3,tb2.Size());
   228 		test(tb3==tb2);
   229 		i+=tb2.Length();
   230 		bf->Read(i,tb3,tb1.Size());
   231 		test(tb3==tb1);
   232 		i+=tb1.Length();
   233 		}
   234 	delete bf;
   235 	test.End();
   236 	}
   237 
   238 GLDEF_C void TestCBufSeg::Test3()
   239 //
   240 //	Test input methods
   241 //
   242 	{
   243 
   244 	TInt8 bb[1000];
   245 	TInt nbytes;
   246 	test.Start(_L("InsertL"));
   247 	CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen);
   248 	CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen);
   249 	CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen);
   250 	nbytes=0;
   251 	TInt k;
   252 	for(TInt j=0;j<20;j++)
   253 		{
   254 		for(TInt i=0;i<10*j;i+=2)
   255 			{
   256 			k=i%128;
   257 			bb[i]=(TInt8)k;
   258 			bb[i+1]=(TInt8)-k;
   259 			}
   260 		bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j);
   261 		CheckSeg(bf1);
   262 		CheckContents1(bf1);
   263 		CheckContents2(bf1);
   264 		bf2->InsertL(bf2->Size(),&bb[0],10*j);
   265 		CheckSeg(bf2);
   266 		CheckContents1(bf2);
   267 		CheckContents2(bf2);
   268 		bf3->InsertL(0,&bb[0],10*j);
   269 		CheckSeg(bf3);
   270 		CheckContents1(bf3);
   271 		CheckContents2(bf3);
   272 		nbytes+=10*j;
   273 		}
   274 	test(nbytes==bf1->Size());
   275 	test(nbytes==bf2->Size());
   276 	test(nbytes==bf3->Size());
   277 	delete bf1;
   278 	delete bf2;
   279 	delete bf3;
   280 	test.End();
   281 	}
   282 
   283 GLDEF_C void TestCBufSeg::Test4()
   284 //
   285 // Delete
   286 // 
   287 	{
   288 	TInt8 bb[1000];
   289 
   290 	test.Start(_L("Delete"));
   291 	CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen);
   292 	CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen);
   293 	CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen);
   294 	TInt nbytes=0;
   295 	TInt k;
   296 	for(TInt j=0;j<20;j++)
   297 		{
   298 		for(TInt i=0;i<10*j;i+=2)
   299 			{
   300 			k=i%128;
   301 			bb[i]=(TInt8)k;
   302 			bb[i+1]=(TInt8)-k;
   303 			}
   304 		bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j);
   305 		bf2->InsertL(bf2->Size(),&bb[0],10*j);
   306 		bf3->InsertL(0,&bb[0],10*j);
   307 		nbytes+=10*j;
   308 		}
   309 	TInt len=34;
   310 	TInt aLength;
   311 	while (nbytes>len)
   312 		{
   313 		for (TInt pos=0;pos<nbytes;pos+=44)
   314 		{
   315 			len=((len+17)%23)*2;
   316 			if (len>nbytes-pos)
   317 				len=nbytes-pos;
   318 			bf1->Delete(pos,len);
   319 			CheckSeg(bf1);
   320 			CheckContents1(bf1);
   321 			CheckContents2(bf1);
   322 			aLength=bf2->Ptr(0).Length();
   323 			aLength=((aLength>len) ? aLength : len);
   324 			bf2->Delete(aLength-len,len);
   325 			CheckSeg(bf2);
   326 			CheckContents1(bf2);
   327 			CheckContents2(bf2);
   328 			bf3->Delete(0,len);
   329 			CheckSeg(bf3);
   330 			CheckContents1(bf3);
   331 			CheckContents2(bf3);
   332 			nbytes-=len;
   333 			test(nbytes==bf1->Size());
   334 			test(nbytes==bf2->Size());
   335 			test(nbytes==bf3->Size());
   336 			}
   337 		}
   338 	delete bf1;
   339 	delete bf2;
   340 	delete bf3;
   341 	test.End();
   342 	}
   343 
   344 GLDEF_C void TestCBufSeg::Test5()
   345 //
   346 // Compress
   347 // 
   348 	{
   349 	TInt8 bb[1000];
   350 
   351 	test.Start(_L("Compress"));
   352 	CBufSeg* bf1=(CBufSeg*)CBufSeg::NewL(SegLen);
   353 	CBufSeg* bf2=(CBufSeg*)CBufSeg::NewL(SegLen);
   354 	CBufSeg* bf3=(CBufSeg*)CBufSeg::NewL(SegLen);
   355 	TInt nbytes=0;
   356 	TInt k;
   357 	for(TInt j=0;j<20;j++)
   358 		{
   359 		for(TInt i=0;i<10*j;i+=2)
   360 			{
   361 			k=i%128;
   362 			bb[i]=(TInt8)k;
   363 			bb[i+1]=(TInt8)-k;
   364 			}
   365 		bf1->InsertL(bf1->Size()/3*2,&bb[0],10*j);
   366 		bf2->InsertL(bf2->Size(),&bb[0],10*j);
   367 		bf3->InsertL(0,&bb[0],10*j);
   368 		nbytes+=10*j;
   369 		}
   370 	TInt len=34;
   371 	TInt aLength;
   372 	while (nbytes>len)
   373 		{
   374 		for (TInt pos=0;pos<nbytes;pos+=44)
   375 		{
   376 			if (len>nbytes-pos)
   377 				len=nbytes-pos;
   378 			bf1->Delete(pos,len);
   379 			bf1->Compress();
   380 			CheckSeg(bf1);
   381 			CheckContents1(bf1);
   382 			CheckContents2(bf1);
   383 			aLength=bf2->Ptr(0).Length();
   384 			aLength=((aLength>len)? aLength : len);
   385 			bf2->Delete(aLength-len,len);
   386 			bf2->Compress();
   387 			CheckSeg(bf2);
   388 			CheckContents1(bf2);
   389 			CheckContents2(bf2);
   390 			bf3->Delete(0,len);
   391 			bf3->Compress();
   392 			CheckSeg(bf3);
   393 			CheckContents1(bf3);
   394 			CheckContents2(bf3);
   395 			nbytes-=len;
   396 			test(nbytes==bf1->Size());
   397 			test(nbytes==bf2->Size());
   398 			test(nbytes==bf3->Size());
   399 			}
   400 		}
   401 	delete bf1;
   402 	delete bf2;
   403 	delete bf3;
   404 	test.End();
   405 	}
   406 
   407 void TestCBufSeg::Test6L()
   408 	{
   409 	test.Start(_L("Test compress frees empty cells"));
   410 	__UHEAP_MARK;
   411 	TUint8 alphabet[27] = "abcdefghijklmnopqrstuvwxyz";
   412 	CBufSeg* buf = CBufSeg::NewL(10);
   413 	CleanupStack::PushL(buf);
   414 	buf->InsertL(0, alphabet, 16);	// "abcdefghij" ++ "klmnop"
   415 	buf->Delete(5, 5);			// "abcde" ++ "klmnop"
   416 	buf->Delete(10, 1);			// "abcde" ++ "klmno"
   417 	buf->Compress();				// "abcdefklmno". i.e. empty cell should be freed.
   418 	CleanupStack::PopAndDestroy(buf);
   419 	__UHEAP_MARKEND;
   420 	test.End();
   421 	}
   422 
   423 LOCAL_C void test_CBufSeg()
   424 //
   425 // Test the BufSeg class
   426 //
   427 	{
   428 
   429 	TestCBufSeg b;
   430 	test.Start(_L("All operations"));
   431 	b.Test1();
   432 	test.Next(_L("Inherited Methods"));
   433 	b.Test2();
   434 	test.Next(_L("Insert"));
   435 	b.Test3();
   436 	test.Next(_L("Delete"));
   437 	b.Test4();
   438 	test.Next(_L("Compress"));
   439 	b.Test5();
   440 	test.Next(_L("Bordeline cases"));
   441 	TRAPD(r,b.Test6L());
   442 	test(r==KErrNone);
   443 	//
   444 	test.End();
   445 	}
   446 
   447 GLDEF_C TInt E32Main()
   448 //
   449 // Test the ADT segmented varray.
   450 //
   451 	{
   452 	
   453 	test.Title();
   454 	__UHEAP_MARK;
   455 //
   456 // Install a trap handler
   457 //
   458 	CTrapCleanup* trapHandler=CTrapCleanup::New();
   459 	test(trapHandler!=NULL);
   460 //	CleanupStack::NextLevel();
   461 	test.Start(_L("class CBufSeg"));
   462 	test_CBufSeg();
   463 	delete trapHandler;
   464 	__UHEAP_MARKEND;
   465 	test.End();
   466 	return(0);
   467 	}
   468