|
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 |