Update contrib.
1 // Copyright (c) 2007-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\misc\t_bytepair.cpp
18 #define __E32TEST_EXTENSION__
23 #include "decompress.h"
25 #define BYTE_PAIR_COMPRESS_INCLUDE_IMPLEMENTATION
26 #include <byte_pair_compress.h>
28 const TInt KMaxSize = 0x1000;
29 const TInt KPageSize = 0x1000;
31 RTest test(_L("T_BYTEPAIR"));
32 TUint8 InputBuffer[KMaxSize];
33 TUint8 CompressedBuffer[4*KMaxSize];
34 TUint8 OutputBuffer[KMaxSize+1];
35 TRomHeader* RomHeader = NULL;
40 void PrintHex(TUint8* aBuffer, TInt aSize)
42 const TInt KBytesPerLine = 38;
43 TBuf<KBytesPerLine * 2 + 3> buf;
44 for (TInt i = 0 ; i < aSize ; )
48 TInt nextChunk = Min(aSize - i, KBytesPerLine);
49 for (TInt j = 0 ; j < nextChunk ; ++j, ++i)
50 buf.AppendFormat(_L("%02x"), aBuffer[i]);
52 RDebug::RawPrint(buf);
58 RandomState = RandomState * 69069 + 1;
62 typedef void (*TGenerator)(TUint8* aDest, TInt aSize);
64 void GenerateUniform(TUint8* aDest, TInt aSize)
66 TInt value = aSize & 255;
67 Mem::Fill(aDest, aSize, value);
70 void GenerateUniformRandom(TUint8* aDest, TInt aSize)
72 for (TInt i = 0 ; i < aSize ; ++i)
73 aDest[i] = TUint8(Random());
76 void GenerateZipfRandom(TUint8* aDest, TInt aSize)
78 // Some details from http://www.cs.hut.fi/Opinnot/T-106.4000/K2007/Ohjeet/Zipf.html
81 test_KErrNone(Math::Log(c, max + 1.0));
82 for (TInt i = 0 ; i < aSize ; ++i)
87 TReal x = Random() / TReal(KMaxTUint32);
88 test_KErrNone(Math::Exp(x, x * c));
96 void GenerateRomPage(TUint8* aDest, TInt aSize)
98 if (TUint(RomOffset + aSize) > RomHeader->iUncompressedSize)
100 Mem::Copy(aDest, ((TUint8*)RomHeader) + RomOffset, aSize);
101 RomOffset += KPageSize;
107 EOutputBufferTooLong,
108 EOutputBufferTooShort,
109 ETruncatedCompressedData,
110 ECorruptCompressedData,
111 ERandomCompressedData
114 void TestCompressDecompress(TGenerator aGenFunc, TInt aSize, TTestMode aMode = ENormal)
116 ASSERT(aSize <= KMaxSize);
119 if (aMode != ERandomCompressedData)
121 // Prepare intput data
122 aGenFunc(InputBuffer, aSize);
124 // Compress input data
125 compressedSize = BytePairCompress(CompressedBuffer, InputBuffer, aSize);
126 ASSERT(compressedSize <= KMaxSize+1);
130 // Generate random compressed data
131 compressedSize = aSize;
132 GenerateUniformRandom(CompressedBuffer, compressedSize);
135 if (aMode == ETruncatedCompressedData)
137 // Truncate compressed data by up to half its length
138 compressedSize -= Math::Random() % (compressedSize / 2);
140 else if (aMode == ECorruptCompressedData)
142 // Corrupt a random byte of the compressed data
143 TInt pos = Random() % compressedSize;
144 CompressedBuffer[pos] = TUint8(Random());
147 // Decomress compressed data
148 Mem::Fill(OutputBuffer, KMaxSize+1, 0);
149 TUint8* srcNext = NULL;
150 TInt outputBufferSize = aSize;
151 if (aMode == EOutputBufferTooLong || aMode == ERandomCompressedData)
152 outputBufferSize = KMaxSize+1;
153 else if (aMode == EOutputBufferTooShort)
154 outputBufferSize = aSize / 2 + 1;
155 TInt decompressedSize = BytePairDecompress(OutputBuffer, outputBufferSize, CompressedBuffer, compressedSize, srcNext);
156 TInt srcUsed = srcNext ? srcNext - CompressedBuffer : 0;
159 RDebug::Printf("%d -> %d -> %d, %d, %d", aSize, compressedSize, outputBufferSize, srcUsed, decompressedSize);
163 // Check decompressed data not larger than output buffer
164 if (decompressedSize > outputBufferSize)
167 // Check output buffer not written beyond what was reported
168 if (decompressedSize >= 0 && OutputBuffer[decompressedSize] != 0)
171 if (aMode == ETruncatedCompressedData || aMode == ECorruptCompressedData || aMode == ERandomCompressedData)
173 // Input corrupt, expect error or partial sucess
175 // If there was an error, check it was KErrCorrupt and srcNext was set to NULL
176 if (decompressedSize < 0 && (decompressedSize != KErrCorrupt || srcNext != NULL))
179 else if (aMode == EOutputBufferTooShort)
181 // Input consistent, output buffer too short
183 // Expect error, or initial part correctly decompressed
184 if (decompressedSize < 0)
186 if (decompressedSize != KErrCorrupt || srcNext != NULL)
191 if (decompressedSize > aSize ||
192 srcUsed > compressedSize ||
193 Mem::Compare(InputBuffer, decompressedSize, OutputBuffer, decompressedSize) != 0)
199 // Input consistent, expect success
201 // Check no error, correct size, all compressed input used, and output same as orignal data
202 if (decompressedSize < 0 ||
203 aSize != decompressedSize ||
204 srcUsed != compressedSize ||
205 Mem::Compare(InputBuffer, decompressedSize, OutputBuffer, decompressedSize) != 0)
211 RDebug::Printf("Failure:");
212 RDebug::Printf("Input");
213 PrintHex(InputBuffer, aSize);
214 RDebug::Printf("Compressed");
215 PrintHex(CompressedBuffer, compressedSize);
216 RDebug::Printf("Output");
217 PrintHex(OutputBuffer, decompressedSize);
224 // Benchmark for Mem functions
229 test.Start(_L("T_BYTEPAIR"));
231 RandomState = User::FastCounter();
232 RDebug::Printf("RandomState == %08x", RandomState);
234 test_Equal(0, FailCount);
236 const TInt KStartSize = KMaxSize / 2;
238 // Test correct operation
240 test.Next(_L("Test compressing uniform data"));
241 for (i = KStartSize ; i < KMaxSize ; i += 19)
242 TestCompressDecompress(GenerateUniform, i);
244 test.Next(_L("Test compressing uniformly distributed random data"));
245 for (i = KStartSize + 2 ; i < KMaxSize ; i += 19)
246 TestCompressDecompress(GenerateUniformRandom, i);
248 test.Next(_L("Test compressing zipf-distributed random data"));
249 for (i = KStartSize + 3 ; i < KMaxSize ; i += 19)
250 TestCompressDecompress(GenerateZipfRandom, i);
253 RomHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
254 TGenerator pageGen = GenerateRomPage;
256 TGenerator pageGen = GenerateZipfRandom;
259 test.Next(_L("Test compressing pages"));
260 for (i = 0 ; i < 100 ; ++i)
261 TestCompressDecompress(pageGen, KPageSize);
263 // Test failure modes
265 test.Next(_L("Test output buffer too short"));
266 for (i = KStartSize ; i < KMaxSize ; i += 19)
267 TestCompressDecompress(pageGen, i, EOutputBufferTooShort);
269 test.Next(_L("Test output buffer too long"));
270 for (i = KStartSize + 1 ; i < KMaxSize ; i += 19)
271 TestCompressDecompress(pageGen, i, EOutputBufferTooLong);
273 test.Next(_L("Test truncated compressed data"));
274 for (i = KStartSize + 2 ; i < KMaxSize ; i += 19)
275 TestCompressDecompress(pageGen, i, ETruncatedCompressedData);
277 test.Next(_L("Test corrupt compressed data "));
278 for (i = KStartSize + 3 ; i < KMaxSize ; i += 19)
279 TestCompressDecompress(pageGen, i, ECorruptCompressedData);
281 test.Next(_L("Test random compressed data"));
282 for (i = KStartSize + 4 ; i < KMaxSize ; i += 19)
283 TestCompressDecompress(GenerateUniformRandom, i, ERandomCompressedData);
285 test_Equal(0, FailCount);