os/kernelhwsrv/kerneltest/e32test/misc/t_bytepair.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\misc\t_bytepair.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#define __E32TEST_EXTENSION__
sl@0
    19
#include <e32test.h>
sl@0
    20
#include <e32math.h>
sl@0
    21
#include <e32rom.h>
sl@0
    22
#include <e32svr.h>
sl@0
    23
#include "decompress.h"
sl@0
    24
sl@0
    25
#define BYTE_PAIR_COMPRESS_INCLUDE_IMPLEMENTATION
sl@0
    26
#include <byte_pair_compress.h>
sl@0
    27
sl@0
    28
const TInt KMaxSize = 0x1000;
sl@0
    29
const TInt KPageSize = 0x1000;
sl@0
    30
sl@0
    31
RTest test(_L("T_BYTEPAIR"));
sl@0
    32
TUint8 InputBuffer[KMaxSize];
sl@0
    33
TUint8 CompressedBuffer[4*KMaxSize];
sl@0
    34
TUint8 OutputBuffer[KMaxSize+1];
sl@0
    35
TRomHeader* RomHeader = NULL;
sl@0
    36
TInt RomOffset = 0;
sl@0
    37
TInt FailCount = 0;
sl@0
    38
TUint32 RandomState;
sl@0
    39
sl@0
    40
void PrintHex(TUint8* aBuffer, TInt aSize)
sl@0
    41
	{
sl@0
    42
	const TInt KBytesPerLine = 38;
sl@0
    43
	TBuf<KBytesPerLine * 2 + 3> buf;
sl@0
    44
	for (TInt i = 0 ; i < aSize ; )
sl@0
    45
		{
sl@0
    46
		buf.Zero();
sl@0
    47
		buf.Append(_L("  "));
sl@0
    48
		TInt nextChunk = Min(aSize - i, KBytesPerLine);
sl@0
    49
		for (TInt j = 0 ; j < nextChunk ; ++j, ++i)
sl@0
    50
			buf.AppendFormat(_L("%02x"), aBuffer[i]);
sl@0
    51
		buf.Append(_L("\n"));
sl@0
    52
		RDebug::RawPrint(buf);
sl@0
    53
		}
sl@0
    54
	}
sl@0
    55
sl@0
    56
TUint32 Random()
sl@0
    57
	{
sl@0
    58
	RandomState = RandomState * 69069 + 1;
sl@0
    59
	return RandomState;
sl@0
    60
	}
sl@0
    61
sl@0
    62
typedef void (*TGenerator)(TUint8* aDest, TInt aSize);
sl@0
    63
sl@0
    64
void GenerateUniform(TUint8* aDest, TInt aSize)
sl@0
    65
	{
sl@0
    66
	TInt value = aSize & 255;
sl@0
    67
	Mem::Fill(aDest, aSize, value);
sl@0
    68
	}
sl@0
    69
sl@0
    70
void GenerateUniformRandom(TUint8* aDest, TInt aSize)
sl@0
    71
	{
sl@0
    72
	for (TInt i = 0 ; i < aSize ; ++i)
sl@0
    73
		aDest[i] = TUint8(Random());
sl@0
    74
	}
sl@0
    75
sl@0
    76
void GenerateZipfRandom(TUint8* aDest, TInt aSize)
sl@0
    77
	{
sl@0
    78
	// Some details from http://www.cs.hut.fi/Opinnot/T-106.4000/K2007/Ohjeet/Zipf.html
sl@0
    79
	const TInt max = 255;
sl@0
    80
	TReal c;
sl@0
    81
	test_KErrNone(Math::Log(c, max + 1.0));
sl@0
    82
	for (TInt i = 0 ; i < aSize ; ++i)
sl@0
    83
		{
sl@0
    84
		int r;
sl@0
    85
		do
sl@0
    86
			{
sl@0
    87
			TReal x = Random() / TReal(KMaxTUint32);
sl@0
    88
			test_KErrNone(Math::Exp(x, x * c));
sl@0
    89
			r = (int)x - 1;
sl@0
    90
			}
sl@0
    91
		while (r > max);
sl@0
    92
		aDest[i] = TUint8(r);
sl@0
    93
		}
sl@0
    94
	}
sl@0
    95
sl@0
    96
void GenerateRomPage(TUint8* aDest, TInt aSize)
sl@0
    97
	{
sl@0
    98
	if (TUint(RomOffset + aSize) > RomHeader->iUncompressedSize)
sl@0
    99
		RomOffset = 0;
sl@0
   100
	Mem::Copy(aDest, ((TUint8*)RomHeader) + RomOffset, aSize);
sl@0
   101
	RomOffset += KPageSize;
sl@0
   102
	}
sl@0
   103
sl@0
   104
enum TTestMode
sl@0
   105
	{
sl@0
   106
	ENormal,
sl@0
   107
	EOutputBufferTooLong,
sl@0
   108
	EOutputBufferTooShort,
sl@0
   109
	ETruncatedCompressedData,
sl@0
   110
	ECorruptCompressedData,
sl@0
   111
	ERandomCompressedData
sl@0
   112
	};
sl@0
   113
sl@0
   114
void TestCompressDecompress(TGenerator aGenFunc, TInt aSize, TTestMode aMode = ENormal)
sl@0
   115
	{
sl@0
   116
	ASSERT(aSize <= KMaxSize);
sl@0
   117
	
sl@0
   118
	TInt compressedSize;
sl@0
   119
	if (aMode != ERandomCompressedData)
sl@0
   120
		{
sl@0
   121
		// Prepare intput data
sl@0
   122
		aGenFunc(InputBuffer, aSize);
sl@0
   123
	
sl@0
   124
		// Compress input data
sl@0
   125
		compressedSize = BytePairCompress(CompressedBuffer, InputBuffer, aSize);
sl@0
   126
		ASSERT(compressedSize <= KMaxSize+1);
sl@0
   127
		}
sl@0
   128
	else
sl@0
   129
		{
sl@0
   130
		// Generate random compressed data
sl@0
   131
		compressedSize = aSize;
sl@0
   132
		GenerateUniformRandom(CompressedBuffer, compressedSize);
sl@0
   133
		}
sl@0
   134
sl@0
   135
	if (aMode == ETruncatedCompressedData)
sl@0
   136
		{
sl@0
   137
		// Truncate compressed data by up to half its length
sl@0
   138
		compressedSize -= Math::Random() % (compressedSize / 2);
sl@0
   139
		}
sl@0
   140
	else if (aMode == ECorruptCompressedData)
sl@0
   141
		{
sl@0
   142
		// Corrupt a random byte of the compressed data
sl@0
   143
		TInt pos = Random() % compressedSize;
sl@0
   144
		CompressedBuffer[pos] = TUint8(Random());
sl@0
   145
		}
sl@0
   146
	
sl@0
   147
	// Decomress compressed data
sl@0
   148
	Mem::Fill(OutputBuffer, KMaxSize+1, 0);
sl@0
   149
	TUint8* srcNext = NULL;
sl@0
   150
	TInt outputBufferSize = aSize;
sl@0
   151
	if (aMode == EOutputBufferTooLong || aMode == ERandomCompressedData)
sl@0
   152
		outputBufferSize = KMaxSize+1;
sl@0
   153
	else if (aMode == EOutputBufferTooShort)
sl@0
   154
		outputBufferSize = aSize / 2 + 1;
sl@0
   155
	TInt decompressedSize = BytePairDecompress(OutputBuffer, outputBufferSize, CompressedBuffer, compressedSize, srcNext);
sl@0
   156
	TInt srcUsed = srcNext ? srcNext - CompressedBuffer : 0;
sl@0
   157
sl@0
   158
	// Print stats
sl@0
   159
	RDebug::Printf("%d -> %d -> %d, %d, %d", aSize, compressedSize, outputBufferSize, srcUsed, decompressedSize);
sl@0
   160
	
sl@0
   161
	TBool ok = ETrue;
sl@0
   162
sl@0
   163
	// Check decompressed data not larger than output buffer
sl@0
   164
	if (decompressedSize > outputBufferSize)
sl@0
   165
		ok = EFalse;
sl@0
   166
	
sl@0
   167
	// Check output buffer not written beyond what was reported
sl@0
   168
	if (decompressedSize >= 0 && OutputBuffer[decompressedSize] != 0)
sl@0
   169
		ok = EFalse;
sl@0
   170
sl@0
   171
	if (aMode == ETruncatedCompressedData || aMode == ECorruptCompressedData || aMode == ERandomCompressedData)
sl@0
   172
		{
sl@0
   173
		// Input corrupt, expect error or partial sucess
sl@0
   174
		
sl@0
   175
		// If there was an error, check it was KErrCorrupt and srcNext was set to NULL
sl@0
   176
		if (decompressedSize < 0 && (decompressedSize != KErrCorrupt || srcNext != NULL))
sl@0
   177
			ok = EFalse;	
sl@0
   178
		}
sl@0
   179
	else if (aMode == EOutputBufferTooShort)
sl@0
   180
		{
sl@0
   181
		// Input consistent, output buffer too short
sl@0
   182
sl@0
   183
		// Expect error, or initial part correctly decompressed
sl@0
   184
		if (decompressedSize < 0)
sl@0
   185
			{
sl@0
   186
			if (decompressedSize != KErrCorrupt || srcNext != NULL)
sl@0
   187
				ok = EFalse;
sl@0
   188
			}
sl@0
   189
		else
sl@0
   190
			{
sl@0
   191
			if (decompressedSize > aSize  ||
sl@0
   192
				srcUsed > compressedSize ||
sl@0
   193
				Mem::Compare(InputBuffer, decompressedSize, OutputBuffer, decompressedSize) != 0)
sl@0
   194
				ok = EFalse;
sl@0
   195
			}
sl@0
   196
		}
sl@0
   197
	else
sl@0
   198
		{
sl@0
   199
		// Input consistent, expect success
sl@0
   200
sl@0
   201
		// Check no error, correct size, all compressed input used, and output same as orignal data
sl@0
   202
		if (decompressedSize < 0 ||
sl@0
   203
			aSize != decompressedSize ||
sl@0
   204
			srcUsed != compressedSize ||
sl@0
   205
			Mem::Compare(InputBuffer, decompressedSize, OutputBuffer, decompressedSize) != 0)
sl@0
   206
			ok = EFalse;		
sl@0
   207
		}
sl@0
   208
sl@0
   209
	if (!ok)
sl@0
   210
		{
sl@0
   211
		RDebug::Printf("Failure:");
sl@0
   212
		RDebug::Printf("Input");
sl@0
   213
		PrintHex(InputBuffer, aSize);
sl@0
   214
		RDebug::Printf("Compressed");
sl@0
   215
		PrintHex(CompressedBuffer, compressedSize);
sl@0
   216
		RDebug::Printf("Output");
sl@0
   217
		PrintHex(OutputBuffer, decompressedSize);
sl@0
   218
		++FailCount;
sl@0
   219
		}
sl@0
   220
	}
sl@0
   221
sl@0
   222
TInt E32Main()
sl@0
   223
//
sl@0
   224
// Benchmark for Mem functions
sl@0
   225
//
sl@0
   226
    {
sl@0
   227
	TInt i;
sl@0
   228
    test.Title();
sl@0
   229
    test.Start(_L("T_BYTEPAIR"));
sl@0
   230
sl@0
   231
	RandomState = User::FastCounter();
sl@0
   232
	RDebug::Printf("RandomState == %08x", RandomState);
sl@0
   233
	
sl@0
   234
	test_Equal(0, FailCount);
sl@0
   235
sl@0
   236
	const TInt KStartSize = KMaxSize / 2;
sl@0
   237
sl@0
   238
	// Test correct operation
sl@0
   239
sl@0
   240
	test.Next(_L("Test compressing uniform data"));	
sl@0
   241
	for (i = KStartSize ; i < KMaxSize ; i += 19)
sl@0
   242
		TestCompressDecompress(GenerateUniform, i);
sl@0
   243
sl@0
   244
	test.Next(_L("Test compressing uniformly distributed random data"));				
sl@0
   245
	for (i = KStartSize + 2 ; i < KMaxSize ; i += 19)
sl@0
   246
		TestCompressDecompress(GenerateUniformRandom, i);
sl@0
   247
	
sl@0
   248
	test.Next(_L("Test compressing zipf-distributed random data"));				
sl@0
   249
	for (i = KStartSize + 3 ; i < KMaxSize ; i += 19)
sl@0
   250
		TestCompressDecompress(GenerateZipfRandom, i);
sl@0
   251
	
sl@0
   252
#ifdef __EPOC32__
sl@0
   253
	RomHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
sl@0
   254
	TGenerator pageGen = GenerateRomPage;
sl@0
   255
#else
sl@0
   256
	TGenerator pageGen = GenerateZipfRandom;
sl@0
   257
#endif
sl@0
   258
	
sl@0
   259
	test.Next(_L("Test compressing pages"));				
sl@0
   260
	for (i = 0 ; i < 100 ; ++i)
sl@0
   261
		TestCompressDecompress(pageGen, KPageSize);
sl@0
   262
sl@0
   263
	// Test failure modes
sl@0
   264
sl@0
   265
	test.Next(_L("Test output buffer too short"));				
sl@0
   266
	for (i = KStartSize ; i < KMaxSize ; i += 19)
sl@0
   267
		TestCompressDecompress(pageGen, i, EOutputBufferTooShort);
sl@0
   268
sl@0
   269
	test.Next(_L("Test output buffer too long"));				
sl@0
   270
	for (i = KStartSize + 1 ; i < KMaxSize ; i += 19)
sl@0
   271
		TestCompressDecompress(pageGen, i, EOutputBufferTooLong);
sl@0
   272
	
sl@0
   273
	test.Next(_L("Test truncated compressed data"));				
sl@0
   274
	for (i = KStartSize + 2 ; i < KMaxSize ; i += 19)
sl@0
   275
		TestCompressDecompress(pageGen, i, ETruncatedCompressedData);
sl@0
   276
	
sl@0
   277
	test.Next(_L("Test corrupt compressed data "));				
sl@0
   278
	for (i = KStartSize + 3 ; i < KMaxSize ; i += 19)
sl@0
   279
		TestCompressDecompress(pageGen, i, ECorruptCompressedData);
sl@0
   280
	
sl@0
   281
	test.Next(_L("Test random compressed data"));				
sl@0
   282
	for (i = KStartSize + 4 ; i < KMaxSize ; i += 19)
sl@0
   283
		TestCompressDecompress(GenerateUniformRandom, i, ERandomCompressedData);
sl@0
   284
sl@0
   285
	test_Equal(0, FailCount);
sl@0
   286
	
sl@0
   287
    test.End();
sl@0
   288
	return(KErrNone);
sl@0
   289
    }