securityanddataprivacytools/securitytools/certapp/store--/us_ucmp.cpp
changeset 8 35751d3474b7
parent 0 2c201484c85f
--- a/securityanddataprivacytools/securitytools/certapp/store--/us_ucmp.cpp	Tue Jul 21 01:04:32 2009 +0100
+++ b/securityanddataprivacytools/securitytools/certapp/store--/us_ucmp.cpp	Thu Sep 10 14:01:51 2009 +0300
@@ -1,755 +1,753 @@
-/*
-* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the License "Eclipse Public License v1.0"
-* which accompanies this distribution, and is available
-* at the URL "http://www.eclipse.org/legal/epl-v10.html".
-*
-* Initial Contributors:
-* Nokia Corporation - initial contribution.
-*
-* Contributors:
-*
-* Description: 
-* Implementation of the Standard Compression Scheme for Unicode.
-* This code is compiled only in the Unicode build.
-*
-*/
-
-
-
-
-#ifdef _UNICODE
-
-#include <s32ucmp.h>
-#include <e32err.h>
-
-const TUint32 TUnicodeCompressionState::iStaticWindow[EStaticWindows] =
-	{
-	0x0000,		// tags
-	0x0080,		// Latin-1 supplement
-	0x0100,		// Latin Extended-A
-	0x0300,		// Combining Diacritics
-	0x2000,		// General Punctuation
-	0x2080,		// Currency Symbols
-	0x2100,		// Letterlike Symbols and Number Forms
-	0x3000		// CJK Symbols and Punctuation
-	};
-
-const TUint32 TUnicodeCompressionState::iDynamicWindowDefault[EDynamicWindows] =
-	{
-	0x0080,		// Latin-1 supplement
-	0x00C0,		// parts of Latin-1 supplement and Latin Extended-A
-	0x0400,		// Cyrillic
-	0x0600,		// Arabic
-	0x0900,		// Devanagari
-	0x3040,		// Hiragana
-	0x30A0,		// Katakana
-	0xFF00		// Fullwidth ASCII
-	};
-
-const TUint16 TUnicodeCompressionState::iSpecialBase[ESpecialBases] =
-	{
-	0x00C0,		// Latin 1 letters (not symbols) and some of Extended-A
-	0x0250,		// IPA extensions
-	0x0370,		// Greek
-	0x0530,		// Armenian
-	0x3040,		// Hiragana
-	0x30A0,		// Katakana
-	0xFF60		// Halfwidth katakana
-	};
-
-// Single-byte mode tag values
-const TUint8 SQ0 = 0x01;	// <byte>				quote from window 0
-const TUint8 SDX = 0x0B;	// <hbyte> <lbyte>		define window in expansion area
-const TUint8 SQU = 0x0E;	// <hbyte> <lbyte>		quote Unicode value
-const TUint8 SCU = 0x0F;	//						switch to Unicode mode
-const TUint8 SC0 = 0x10;	//						select dynamic window 0
-const TUint8 SD0 = 0x18;	// <byte>				set dynamic window 0 index to <byte> and select it
-
-// Unicode mode tag values
-const TUint8 UC0 = 0xE0;	//						select dynamic window 0 and switch to single-byte mode
-const TUint8 UD0 = 0xE8;	// <byte>				set dynamic window 0 index to <byte>, select it and switch to
-							//						single-byte mode
-const TUint8 UQU = 0xF0;	// <hbyte>, <lbyte>		quote Unicode value
-const TUint8 UDX = 0xF1;	// <hbyte>, <lbyte>		define window in expansion area and switch to single-byte mode
-	
-TUnicodeCompressionState::TUnicodeCompressionState():
-	iUnicodeWords(0),
-	iMaxUnicodeWords(0),
-	iCompressedBytes(0),
-	iMaxCompressedBytes(0)
-	{
-	Reset();
-	}
-
-void TUnicodeCompressionState::Reset()
-	{
-	iUnicodeMode = FALSE;
-	iActiveWindowBase = 0x0080;
-	for (int i = 0; i < EDynamicWindows; i++)
-		iDynamicWindow[i] = iDynamicWindowDefault[i];
-	}
-
-
-// Return the index of the static window that contains this code, if any, or -1 if there is none.
-TInt TUnicodeCompressionState::StaticWindowIndex(TUint16 aCode)
-	{
-	for (TInt i = 0; i < EStaticWindows; i++)
-		if (aCode >= iStaticWindow[i] && aCode < iStaticWindow[i] + 128)
-			return i;
-	return -1;
-	}
-
-/*
-If aCode can be accommodated in one of the legal dynamic windows, return the index of that window
-in the offset table. If not return KErrNotFound.
-*/
-TInt TUnicodeCompressionState::DynamicWindowOffsetIndex(TUint16 aCode)
-	{
-	if (aCode < 0x0080)
-		return KErrNotFound;
-	if (aCode >= 0x3400 && aCode <= 0xDFFF)
-		return KErrNotFound;
-
-	/*
-	Prefer sections that cross half-block boundaries. These are better adapted to actual text.
-	They are represented by offset indices 0xf9..0xff.
-	*/
-	for (int i = 0; i < ESpecialBases; i++)
-		if (aCode >= iSpecialBase[i] && aCode < iSpecialBase[i] + 128)
-			return 0xF9 + i;
-
-	/*
-	Offset indices 0x01..0x67 represent half blocks from 0x0080 to 0x3380 and
-	0x68..0xA7 represent half blocks from 0xE000 to 0xFF80.
-	*/
-	if (aCode >= 0xE000)
-		aCode -= 0xAC00;
-	return aCode / 0x80;
-	}
-
-// Return the base of the window represented by offset index <n>. Return 0 if the offset index is illegal.
-TUint32 TUnicodeCompressionState::DynamicWindowBase(TInt aOffsetIndex)
-	{
-	if (aOffsetIndex >= 0xF9 && aOffsetIndex <= 0xFF)
-		{
-		/*
-		WARNING: don't optimise the following two lines by replacing them with
-		'return iSpecialBase[aOffsetIndex - 0xF9];'. To do so would re-introduce an error
-		in ARM builds caused by optimisation and consequent erroneous fixing up
-		of the array base: see defect EDNGASR-4AGJQX in ER5U defects.
-		*/
-		int special_base_index = aOffsetIndex - 0xF9;
-		return iSpecialBase[special_base_index];
-		}
-	if (aOffsetIndex >= 0x01 && aOffsetIndex <= 0x67)
-		return aOffsetIndex * 0x80;
-	if (aOffsetIndex >= 0x68 && aOffsetIndex <= 0xA7)
-		return aOffsetIndex * 0x80 + 0xAC00;
-	return 0;
-	}
-
-TBool TUnicodeCompressionState::EncodeAsIs(TUint16 aCode)
-	{
-	return aCode == 0x0000 || aCode == 0x0009 || aCode == 0x000A || aCode == 0x000D ||
-		   (aCode >= 0x0020 && aCode <= 0x007F);
-	}
-
-void TUnicodeCompressionState::Panic(TPanic aPanic)
-	{
-		User::Panic(_L16("ucmp"),(TInt)aPanic);
-	}
-
-EXPORT_C TUnicodeCompressor::TUnicodeCompressor():
-	iInputBufferStart(0),
-	iInputBufferSize(0),
-	iOutputBufferStart(0),
-	iOutputBufferSize(0),
-	iDynamicWindowIndex(0),
-	iOutputStream(NULL),
-	iOutputPointer(NULL),
-	iInput(NULL)
-	{
-		// Clear coverity warning
-		memset(iOutputBuffer, 0, sizeof(iOutputBuffer));
-	}
-
-EXPORT_C void TUnicodeCompressor::CompressL(RWriteStream& aOutput,MUnicodeSource& aInput,
-											TInt aMaxOutputBytes,TInt aMaxInputWords,
-											TInt* aOutputBytes,TInt* aInputWords)
-	{
-	DoCompressL(&aOutput,NULL,&aInput,aMaxOutputBytes,aMaxInputWords,aOutputBytes,aInputWords);
-	}
-
-EXPORT_C void TUnicodeCompressor::CompressL(TUint8* aOutput,MUnicodeSource& aInput,
-											TInt aMaxOutputBytes,TInt aMaxInputWords,
-											TInt* aOutputBytes,TInt* aInputWords)
-	{
-	DoCompressL(NULL,aOutput,&aInput,aMaxOutputBytes,aMaxInputWords,aOutputBytes,aInputWords);
-	}
-
-EXPORT_C TInt TUnicodeCompressor::FlushL(RWriteStream& aOutput,TInt aMaxOutputBytes,TInt& aOutputBytes)
-	{
-	DoCompressL(&aOutput,NULL,NULL,aMaxOutputBytes,0,&aOutputBytes,NULL);
-	return iOutputBufferSize;
-	}
-
-EXPORT_C TInt TUnicodeCompressor::FlushL(TUint8* aOutput,TInt aMaxOutputBytes,TInt& aOutputBytes)
-	{
-	DoCompressL(NULL,aOutput,NULL,aMaxOutputBytes,0,&aOutputBytes,NULL);
-	return iOutputBufferSize;
-	}
-
-EXPORT_C TInt TUnicodeCompressor::CompressedSizeL(MUnicodeSource& aInput,TInt aInputWords)
-	{
-	TInt bytes;
-	TUnicodeCompressor c;
-	c.DoCompressL(NULL,NULL,&aInput,KMaxTInt,aInputWords,&bytes,NULL);
-	return bytes;
-	}
-
-// Compress until input or output is exhausted or an exception occurs.
-void TUnicodeCompressor::DoCompressL(RWriteStream* aOutputStream,TUint8* aOutputPointer,MUnicodeSource* aInput,
-									 TInt aMaxOutputBytes,TInt aMaxInputWords,
-									 TInt* aOutputBytes,TInt* aInputWords)
-	{
-	iOutputStream = aOutputStream;
-	iOutputPointer = aOutputPointer;
-	iInput = aInput;
-	iMaxCompressedBytes = aMaxOutputBytes;
-	iMaxUnicodeWords = aMaxInputWords;
-	iCompressedBytes = iUnicodeWords = 0;
-	FlushOutputBufferL();
-	if (iInput)
-		{
-		while (iUnicodeWords < iMaxUnicodeWords && iCompressedBytes < iMaxCompressedBytes)
-			{
-			TUint16 x = iInput->ReadUnicodeValueL();
-			TAction action(x);
-			iInputBuffer[(iInputBufferStart + iInputBufferSize) % EMaxInputBufferSize] = action;
-			iInputBufferSize++;
-			iUnicodeWords++;
-			if (iInputBufferSize == EMaxInputBufferSize)
-				WriteRunL();
-			}
-		}
-	FlushInputBufferL();
-	if (aOutputBytes)
-		*aOutputBytes = iCompressedBytes;
-	if (aInputWords)
-		*aInputWords = iUnicodeWords;
-	}
-
-TUnicodeCompressor::TAction::TAction(TUint16 aCode):
-	iCode(aCode)
-	{
-	if (TUnicodeCompressionState::EncodeAsIs(aCode))
-		iTreatment = EPlainASCII;
-	else
-		{
-		iTreatment = TUnicodeCompressionState::DynamicWindowOffsetIndex(aCode);
-		if (iTreatment == -1)
-			{
-			iTreatment = TUnicodeCompressionState::StaticWindowIndex(aCode);
-			if (iTreatment == -1)
-				iTreatment = EPlainUnicode;
-			else
-				iTreatment += EFirstStatic;
-			}
-		}
-	}
-
-void TUnicodeCompressor::WriteCharacterFromBuffer()
-	{
-	const TAction& action = iInputBuffer[iInputBufferStart];
-	iInputBufferSize--;
-	iInputBufferStart = (iInputBufferStart + 1) % EMaxInputBufferSize;
-	WriteCharacter(action);
-	}
-
-void TUnicodeCompressor::FlushInputBufferL()
-	{
-	while (iInputBufferSize > 0 && iCompressedBytes < iMaxCompressedBytes)
-		WriteRunL();
-	}
-
-void TUnicodeCompressor::WriteRunL()
-	{
-	// Write out any leading characters that can be passed through.
-	if (!iUnicodeMode)
-		while (iInputBufferSize > 0)
-			{
-			const TAction& action = iInputBuffer[iInputBufferStart];
-			if (action.iTreatment == TAction::EPlainASCII ||
-				(action.iCode >= iActiveWindowBase && action.iCode < iActiveWindowBase + 128))
-				WriteCharacterFromBuffer();
-			else
-				break;
-			}
-
-	// Write a run of characters that cannot be passed through.
-	int i;
-	if (iInputBufferSize > 0)
-		{
-		/*
-		Find a run of characters with the same treatment and select that treatment
-		if the run has more than one character.
-		*/
-		int treatment = iInputBuffer[iInputBufferStart].iTreatment;
-		int next_treatment = treatment;
-		int run_size = 1;
-		for (i = 1; i < iInputBufferSize; i++)
-			{
-			int index = (iInputBufferStart + i) % EMaxInputBufferSize;
-			next_treatment = iInputBuffer[index].iTreatment;
-			if (next_treatment != treatment)
-				break;
-			run_size++;
-			}
-		if (run_size > 1)
-			SelectTreatment(treatment);
-		for (i = 0; i < run_size; i++)
-			WriteCharacterFromBuffer();
-		}
-
-	FlushOutputBufferL();
-	}
-
-void TUnicodeCompressor::FlushOutputBufferL()
-	{
-	while (iOutputBufferSize > 0 &&	iCompressedBytes < iMaxCompressedBytes)
-		{
-		TUint8 byte = iOutputBuffer[iOutputBufferStart];
-		if (iOutputPointer)
-			*iOutputPointer++ = byte;
-		else if (iOutputStream)
-			iOutputStream->WriteUint8L(byte);
-		iCompressedBytes++;
-		iOutputBufferSize--;
-		iOutputBufferStart = (iOutputBufferStart + 1) % EMaxOutputBufferSize;
-		}
-	}
-
-void TUnicodeCompressor::SelectTreatment(TInt aTreatment)
-	{
-	if (aTreatment == TAction::EPlainUnicode)
-		{
-		// Switch to Unicode mode if not there already.
-		if (!iUnicodeMode)
-			{
-			WriteByte(SCU);
-			iUnicodeMode = TRUE;
-			}
-		return;
-		}
-
-	if (aTreatment == TAction::EPlainASCII)
-		{
-		// Switch to single-byte mode, using the current dynamic window, if not there already.
-		if (iUnicodeMode)
-			{
-			WriteByte(UC0 + iDynamicWindowIndex);
-			iUnicodeMode = FALSE;
-			}
-		return;
-		}
-
-	if (aTreatment >= TAction::EFirstDynamic && aTreatment <= TAction::ELastDynamic)
-		{
-		TUint32 base = DynamicWindowBase(aTreatment);
-
-		// Switch to the appropriate dynamic window if it is available; if not, redefine and select dynamic window 4.
-		for (int i = 0; i < EDynamicWindows; i++)
-			if (base == iDynamicWindow[i])
-				{
-				if (iUnicodeMode)
-					WriteByte(UC0 + i);
-				else if (i != iDynamicWindowIndex)
-					WriteByte(SC0 + i);
-				iUnicodeMode = FALSE;
-				iDynamicWindowIndex = i;
-				iActiveWindowBase = base;
-				return;
-				}
-		if (iUnicodeMode)
-			WriteByte(UD0 + 4);
-		else
-			WriteByte(SD0 + 4);
-		iDynamicWindowIndex = 4;
-		iUnicodeMode = FALSE;
-		WriteByte(aTreatment);
-		iDynamicWindow[4] = base;
-		iActiveWindowBase = base;
-		return;
-		}
-	}
-
-// Write a character without changing mode or window.
-void TUnicodeCompressor::WriteCharacter(const TAction& aAction)
-	{
-	if (iUnicodeMode)
-		WriteUCharacter(aAction.iCode);
-	else
-		WriteSCharacter(aAction);
-	}
-
-void TUnicodeCompressor::WriteUCharacter(TUint16 aCode)
-	{
-	// Emit the 'quote Unicode' tag if the character would conflict with a tag.
-	if (aCode >= 0xE000 && aCode <= 0xF2FF)
-		WriteByte(UQU);
-
-	// Write the Unicode value big-end first.
-	WriteByte((aCode >> 8) & 0xFF);
-	WriteByte(aCode & 0xFF);
-	}
-
-void TUnicodeCompressor::WriteByte(TUint aByte)
-	{
-	if (iOutputBufferSize >= EMaxOutputBufferSize)
-		Panic(EOutputBufferOverflow); //Panic here is ok as this is a programming error
-	iOutputBuffer[(iOutputBufferStart + iOutputBufferSize) % EMaxOutputBufferSize] = (TUint8)aByte;
-	iOutputBufferSize++;
-	}
-
-void TUnicodeCompressor::WriteSCharacter(const TAction& aAction)
-	{
-	// Characters in the range 0x0020..0x007F, plus nul, tab, cr, and lf, can be emitted as their low bytes.
-	if (aAction.iTreatment == TAction::EPlainASCII)
-		{
-		WriteByte(aAction.iCode);
-		return;
-		}
-
-	// Characters in a static window can be written using SQ<n> plus a byte in the range 0x00-0x7F
-	if (aAction.iTreatment >= TAction::EFirstStatic && aAction.iTreatment <= TAction::ELastStatic)
-		{
-		int window = aAction.iTreatment - TAction::EFirstStatic;
-		WriteByte(SQ0 + window);
-		WriteByte(aAction.iCode);
-		return;
-		}
-
-	// Characters in the current dynamic window can be written as a byte in the range 0x80-0xFF.
-	if (aAction.iCode >= iActiveWindowBase && aAction.iCode < iActiveWindowBase + 128)
-		{
-		WriteByte(aAction.iCode - iActiveWindowBase + 0x80);
-		return;
-		}
-
-	// Characters in another dynamic window can be written using SQ<n> plus a byte in the range 0x80-0xFF
-	int i;
-	for (i = 0; i < EDynamicWindows; i++)
-		if (aAction.iCode >= iDynamicWindow[i] && aAction.iCode < iDynamicWindow[i] + 128)
-			{
-			WriteByte(SQ0 + i);
-			WriteByte(aAction.iCode - iDynamicWindow[i] + 0x80);
-			return;
-			}
-
-	// Other characters can be quoted.
-	WriteByte(SQU);
-	WriteByte((aAction.iCode >> 8) & 0xFF);
-	WriteByte(aAction.iCode & 0xFF);
-	return;
-	}
-
-EXPORT_C TUnicodeExpander::TUnicodeExpander():
-	iInputBufferStart(0),
-	iInputBufferSize(0),
-	iOutputBufferStart(0),
-	iOutputBufferSize(0),
-	iOutput(NULL),
-	iInputStream(NULL),
-	iInputPointer(NULL)
-	{
-		// Clear coverity warnings
-		memset(iInputBuffer, 0, sizeof(iInputBuffer));
-		memset(iOutputBuffer, 0, sizeof(iOutputBuffer));
-	}
-
-EXPORT_C void TUnicodeExpander::ExpandL(MUnicodeSink& aOutput,RReadStream& aInput,
-										TInt aMaxOutputWords,TInt aMaxInputBytes,
-										TInt* aOutputWords,TInt* aInputBytes)
-	{
-	DoExpandL(&aOutput,&aInput,NULL,aMaxOutputWords,aMaxInputBytes,aOutputWords,aInputBytes);
-	}
-
-EXPORT_C void TUnicodeExpander::ExpandL(MUnicodeSink& aOutput,const TUint8* aInput,
-										TInt aMaxOutputWords,TInt aMaxInputBytes,
-										TInt* aOutputWords,TInt* aInputBytes)
-	{
-	DoExpandL(&aOutput,NULL,aInput,aMaxOutputWords,aMaxInputBytes,aOutputWords,aInputBytes);
-	}
-
-EXPORT_C TInt TUnicodeExpander::FlushL(MUnicodeSink& aOutput,TInt aMaxOutputWords,TInt& aOutputWords)
-	{
-	DoExpandL(&aOutput,NULL,NULL,aMaxOutputWords,0,&aOutputWords,NULL);
-	return iOutputBufferSize;
-	}
-
-EXPORT_C TInt TUnicodeExpander::ExpandedSizeL(RReadStream& aInput,TInt aInputBytes)
-	{
-	TInt words;
-	TUnicodeExpander e;
-	e.DoExpandL(NULL,&aInput,NULL,KMaxTInt,aInputBytes,&words,NULL);
-	return words;
-	}
-
-EXPORT_C TInt TUnicodeExpander::ExpandedSizeL(const TUint8* aInput,TInt aInputBytes)
-	{
-	TInt words;
-	TUnicodeExpander e;
-	e.DoExpandL(NULL,NULL,aInput,KMaxTInt,aInputBytes,&words,NULL);
-	return words;
-	}
-
-// Expand until input or output is exhausted or an exception occurs.
-void TUnicodeExpander::DoExpandL(MUnicodeSink* aOutput,RReadStream* aInputStream,const TUint8* aInputPointer,
-								 TInt aMaxOutputWords,TInt aMaxInputBytes,
-								 TInt* aOutputWords,TInt* aInputBytes)
-	{
-	iOutput = aOutput;
-	iInputStream = aInputStream;
-	iInputPointer = aInputPointer;
-	iMaxUnicodeWords = aMaxOutputWords;
-	iMaxCompressedBytes = aMaxInputBytes;
-	iUnicodeWords = iCompressedBytes = 0;
-	iInputBufferStart = 0;
-	FlushOutputBufferL();
-	if (iInputPointer || iInputStream)
-		{
-		while (iUnicodeWords + iOutputBufferSize < iMaxUnicodeWords && iCompressedBytes < iMaxCompressedBytes)
-			HandleByteL();
-		}
-	if (aOutputWords)
-		*aOutputWords = iUnicodeWords;
-	if (aInputBytes)
-		*aInputBytes = iCompressedBytes;
-	}
-
-void TUnicodeExpander::HandleByteL()
-	{
-	TUint8 byte;
-	TBool handled = FALSE;
-	if (ReadByteL(byte))
-		{
-		if (iUnicodeMode)
-			handled = HandleUByteL(byte);
-		else
-			handled = HandleSByteL(byte);
-		}
-	iInputBufferStart = 0;
-	if (handled)
-		iInputBufferSize = 0;
-	FlushOutputBufferL();
-	}
-
-void TUnicodeExpander::FlushOutputBufferL()
-	{
-	while (iOutputBufferSize > 0 &&	iUnicodeWords < iMaxUnicodeWords)
-		{
-		if (iOutput)
-			iOutput->WriteUnicodeValueL(iOutputBuffer[iOutputBufferStart]);
-		iUnicodeWords++;
-		iOutputBufferSize--;
-		iOutputBufferStart = (iOutputBufferStart + 1) % EMaxOutputBufferSize;
-		}
-	}
-
-TBool TUnicodeExpander::HandleSByteL(TUint8 aByte)
-	{
-	// 'Pass-through' codes.
-	if (TUnicodeCompressionState::EncodeAsIs(aByte))
-		{
-		WriteChar(aByte);
-		return TRUE;
-		}
-
-	// Codes 0x80-0xFF select a character from the active window.
-	if (aByte >= 0x80)
-		{
-		WriteChar32(iActiveWindowBase + aByte - 0x80);
-		return TRUE;
-		}
-
-	// SQU: quote a Unicode character.
-	if (aByte == SQU)
-		return QuoteUnicodeL();
-
-	// SCU: switch to Unicode mode.
-	if (aByte == SCU)
-		{
-		iUnicodeMode = TRUE;
-		return TRUE;
-		}
-
-	// SQn: quote from window n.
-	if (aByte >= SQ0 && aByte <= SQ0 + 7)
-		{
-		int window = aByte - SQ0;
-		TUint8 byte;
-		if (ReadByteL(byte))
-			{
-			TUint32 c = byte;
-			if (c <= 0x7F)
-				c += iStaticWindow[window];
-			else
-				c += iDynamicWindow[window] - 0x80;
-			WriteChar32(c);
-			return TRUE;
-			}
-		else
-			return FALSE;
-		}
-
-	// SCn: switch to dynamic window n.
-	if (aByte >= SC0 && aByte <= SC0 + 7)
-		{
-		iActiveWindowBase = iDynamicWindow[aByte - SC0];
-		return TRUE;
-		}
-
-	// SDn: define dynamic window n and switch to it.
-	if (aByte >= SD0 && aByte <= SD0 + 7)
-		return DefineWindowL(aByte - SD0);
-
-	// SDX: define window in the expansion space.
-	if (aByte == SDX)
-		return DefineExpansionWindowL();
-
-	User::Leave(KErrCorrupt);
-	return FALSE;
-	}
-
-TBool TUnicodeExpander::HandleUByteL(TUint8 aByte)
-	{
-	// Plain Unicode; get the low byte and emit the Unicode value.
-	if (aByte <= 0xDF || aByte >= 0xF3)
-		{
-		TUint8 lo;
-		if (ReadByteL(lo))
-			{
-			TUint16 c = (TUint16)((aByte << 8) | lo);
-			WriteChar(c);
-			return TRUE;
-			}
-		else
-			return FALSE;
-		}
-
-	// Quote a Unicode character that would otherwise conflict with a tag.
-	if (aByte == UQU)
-		return QuoteUnicodeL();
-
-	// UCn: change to single byte mode and select window n.
-	if (aByte >= UC0 && aByte <= UC0 + 7)
-		{
-		iUnicodeMode = FALSE;
-		iActiveWindowBase = iDynamicWindow[aByte - UC0];
-		return TRUE;
-		}
-
-	// UDn: define dynamic window n and switch to it.
-	if (aByte >= UD0 && aByte <= UD0 + 7)
-		return DefineWindowL(aByte - UD0);
-
-	// UDX: define window in the expansion space.
-	if (aByte == UDX)
-		return DefineExpansionWindowL();
-
-	User::Leave(KErrCorrupt);
-	return FALSE;
-	}
-
-TBool TUnicodeExpander::QuoteUnicodeL()
-	{
-	TUint8 hi, lo;
-	if (ReadByteL(hi) && ReadByteL(lo))
-		{
-		TUint16 c = (TUint16)((hi << 8) | lo);
-		WriteChar(c);
-		return TRUE;
-		}
-	else
-		return FALSE;
-	}
-
-TBool TUnicodeExpander::DefineWindowL(TInt aIndex)
-	{
-	TUint8 window;
-	if (ReadByteL(window))
-		{
-		iUnicodeMode = FALSE;
-		iActiveWindowBase = DynamicWindowBase(window);
-		iDynamicWindow[aIndex] = iActiveWindowBase;
-		return TRUE;
-		}
-	else
-		return FALSE;
-	}
-
-TBool TUnicodeExpander::DefineExpansionWindowL()
-	{
-	TUint8 hi, lo;
-	if (ReadByteL(hi) && ReadByteL(lo))
-		{
-		iUnicodeMode = FALSE;
-		iActiveWindowBase = 0x10000 + (0x80 * ((hi & 0x1F) * 0x100 + lo));
-		iDynamicWindow[hi >> 5] = iActiveWindowBase;
-		return TRUE;
-		}
-	else
-		return FALSE;
-	}
-
-// Read either from the buffer (in the case of restarting after source finished in mid-operation) or from the source.
-TBool TUnicodeExpander::ReadByteL(TUint8& aByte)
-	{
-	if (iInputBufferStart < iInputBufferSize)
-		{
-		aByte = iInputBuffer[iInputBufferStart++];
-		return TRUE;
-		}
-	else if (iCompressedBytes < iMaxCompressedBytes)
-		{
-		if (iInputPointer)
-			aByte = *iInputPointer++;
-		else
-			aByte = iInputStream->ReadUint8L();
-		iInputBuffer[iInputBufferStart++] = aByte;
-		iInputBufferSize = iInputBufferStart;
-		iCompressedBytes++;
-		return TRUE;
-		}
-	else
-		return FALSE;
-	}
-
-void TUnicodeExpander::WriteChar(TUint16 aChar)
-	{
-	if (iOutputBufferSize >= EMaxOutputBufferSize)
-		Panic(EOutputBufferOverflow); //Panic here is ok since this is a programming error
-	iOutputBuffer[(iOutputBufferStart + iOutputBufferSize) % EMaxOutputBufferSize] = aChar;
-	iOutputBufferSize++;
-	}
-
-// Write a Unicode character; write using surrogates if in the range 0x10000..0x10FFFF.
-void TUnicodeExpander::WriteChar32(TUint aChar)
-	{
-	if (aChar <= 0xFFFF)
-		WriteChar((TUint16)aChar);
-	else if (aChar <= 0x10FFFF)
-		{
-		aChar -= 0x10000;									// reduce to 20-bit value in the range 0x0..0xFFFFF
-		WriteChar((TUint16)(0xD800 + (aChar >> 10)));		// first high surrogate + high 10 bits
-		WriteChar((TUint16)(0xDC00 + (aChar & 0x03FF)));	// first low surrogate + low 10 bits
-		}
-	else
-		//Panic to be kept here as impossible to test this case (nor the one before). Biggest value that can be passed is 0xFFFFF 
-		Panic(ENotUnicode);
-	}
-
-#endif // _UNICODE
+/*
+* Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* Implementation of the Standard Compression Scheme for Unicode.
+* This code is compiled only in the Unicode build.
+*
+*/
+
+
+#ifdef _UNICODE
+
+#include <s32ucmp.h>
+#include <e32err.h>
+
+const TUint32 TUnicodeCompressionState::iStaticWindow[EStaticWindows] =
+	{
+	0x0000,		// tags
+	0x0080,		// Latin-1 supplement
+	0x0100,		// Latin Extended-A
+	0x0300,		// Combining Diacritics
+	0x2000,		// General Punctuation
+	0x2080,		// Currency Symbols
+	0x2100,		// Letterlike Symbols and Number Forms
+	0x3000		// CJK Symbols and Punctuation
+	};
+
+const TUint32 TUnicodeCompressionState::iDynamicWindowDefault[EDynamicWindows] =
+	{
+	0x0080,		// Latin-1 supplement
+	0x00C0,		// parts of Latin-1 supplement and Latin Extended-A
+	0x0400,		// Cyrillic
+	0x0600,		// Arabic
+	0x0900,		// Devanagari
+	0x3040,		// Hiragana
+	0x30A0,		// Katakana
+	0xFF00		// Fullwidth ASCII
+	};
+
+const TUint16 TUnicodeCompressionState::iSpecialBase[ESpecialBases] =
+	{
+	0x00C0,		// Latin 1 letters (not symbols) and some of Extended-A
+	0x0250,		// IPA extensions
+	0x0370,		// Greek
+	0x0530,		// Armenian
+	0x3040,		// Hiragana
+	0x30A0,		// Katakana
+	0xFF60		// Halfwidth katakana
+	};
+
+// Single-byte mode tag values
+const TUint8 SQ0 = 0x01;	// <byte>				quote from window 0
+const TUint8 SDX = 0x0B;	// <hbyte> <lbyte>		define window in expansion area
+const TUint8 SQU = 0x0E;	// <hbyte> <lbyte>		quote Unicode value
+const TUint8 SCU = 0x0F;	//						switch to Unicode mode
+const TUint8 SC0 = 0x10;	//						select dynamic window 0
+const TUint8 SD0 = 0x18;	// <byte>				set dynamic window 0 index to <byte> and select it
+
+// Unicode mode tag values
+const TUint8 UC0 = 0xE0;	//						select dynamic window 0 and switch to single-byte mode
+const TUint8 UD0 = 0xE8;	// <byte>				set dynamic window 0 index to <byte>, select it and switch to
+							//						single-byte mode
+const TUint8 UQU = 0xF0;	// <hbyte>, <lbyte>		quote Unicode value
+const TUint8 UDX = 0xF1;	// <hbyte>, <lbyte>		define window in expansion area and switch to single-byte mode
+	
+TUnicodeCompressionState::TUnicodeCompressionState():
+	iUnicodeWords(0),
+	iMaxUnicodeWords(0),
+	iCompressedBytes(0),
+	iMaxCompressedBytes(0)
+	{
+	Reset();
+	}
+
+void TUnicodeCompressionState::Reset()
+	{
+	iUnicodeMode = FALSE;
+	iActiveWindowBase = 0x0080;
+	for (int i = 0; i < EDynamicWindows; i++)
+		iDynamicWindow[i] = iDynamicWindowDefault[i];
+	}
+
+
+// Return the index of the static window that contains this code, if any, or -1 if there is none.
+TInt TUnicodeCompressionState::StaticWindowIndex(TUint16 aCode)
+	{
+	for (TInt i = 0; i < EStaticWindows; i++)
+		if (aCode >= iStaticWindow[i] && aCode < iStaticWindow[i] + 128)
+			return i;
+	return -1;
+	}
+
+/*
+If aCode can be accommodated in one of the legal dynamic windows, return the index of that window
+in the offset table. If not return KErrNotFound.
+*/
+TInt TUnicodeCompressionState::DynamicWindowOffsetIndex(TUint16 aCode)
+	{
+	if (aCode < 0x0080)
+		return KErrNotFound;
+	if (aCode >= 0x3400 && aCode <= 0xDFFF)
+		return KErrNotFound;
+
+	/*
+	Prefer sections that cross half-block boundaries. These are better adapted to actual text.
+	They are represented by offset indices 0xf9..0xff.
+	*/
+	for (int i = 0; i < ESpecialBases; i++)
+		if (aCode >= iSpecialBase[i] && aCode < iSpecialBase[i] + 128)
+			return 0xF9 + i;
+
+	/*
+	Offset indices 0x01..0x67 represent half blocks from 0x0080 to 0x3380 and
+	0x68..0xA7 represent half blocks from 0xE000 to 0xFF80.
+	*/
+	if (aCode >= 0xE000)
+		aCode -= 0xAC00;
+	return aCode / 0x80;
+	}
+
+// Return the base of the window represented by offset index <n>. Return 0 if the offset index is illegal.
+TUint32 TUnicodeCompressionState::DynamicWindowBase(TInt aOffsetIndex)
+	{
+	if (aOffsetIndex >= 0xF9 && aOffsetIndex <= 0xFF)
+		{
+		/*
+		WARNING: don't optimise the following two lines by replacing them with
+		'return iSpecialBase[aOffsetIndex - 0xF9];'. To do so would re-introduce an error
+		in ARM builds caused by optimisation and consequent erroneous fixing up
+		of the array base: see defect EDNGASR-4AGJQX in ER5U defects.
+		*/
+		int special_base_index = aOffsetIndex - 0xF9;
+		return iSpecialBase[special_base_index];
+		}
+	if (aOffsetIndex >= 0x01 && aOffsetIndex <= 0x67)
+		return aOffsetIndex * 0x80;
+	if (aOffsetIndex >= 0x68 && aOffsetIndex <= 0xA7)
+		return aOffsetIndex * 0x80 + 0xAC00;
+	return 0;
+	}
+
+TBool TUnicodeCompressionState::EncodeAsIs(TUint16 aCode)
+	{
+	return aCode == 0x0000 || aCode == 0x0009 || aCode == 0x000A || aCode == 0x000D ||
+		   (aCode >= 0x0020 && aCode <= 0x007F);
+	}
+
+void TUnicodeCompressionState::Panic(TPanic aPanic)
+	{
+		User::Panic(_L16("ucmp"),(TInt)aPanic);
+	}
+
+EXPORT_C TUnicodeCompressor::TUnicodeCompressor():
+	iInputBufferStart(0),
+	iInputBufferSize(0),
+	iOutputBufferStart(0),
+	iOutputBufferSize(0),
+	iDynamicWindowIndex(0),
+	iOutputStream(NULL),
+	iOutputPointer(NULL),
+	iInput(NULL)
+	{
+		// Clear coverity warning
+		memset(iOutputBuffer, 0, sizeof(iOutputBuffer));
+	}
+
+EXPORT_C void TUnicodeCompressor::CompressL(RWriteStream& aOutput,MUnicodeSource& aInput,
+											TInt aMaxOutputBytes,TInt aMaxInputWords,
+											TInt* aOutputBytes,TInt* aInputWords)
+	{
+	DoCompressL(&aOutput,NULL,&aInput,aMaxOutputBytes,aMaxInputWords,aOutputBytes,aInputWords);
+	}
+
+EXPORT_C void TUnicodeCompressor::CompressL(TUint8* aOutput,MUnicodeSource& aInput,
+											TInt aMaxOutputBytes,TInt aMaxInputWords,
+											TInt* aOutputBytes,TInt* aInputWords)
+	{
+	DoCompressL(NULL,aOutput,&aInput,aMaxOutputBytes,aMaxInputWords,aOutputBytes,aInputWords);
+	}
+
+EXPORT_C TInt TUnicodeCompressor::FlushL(RWriteStream& aOutput,TInt aMaxOutputBytes,TInt& aOutputBytes)
+	{
+	DoCompressL(&aOutput,NULL,NULL,aMaxOutputBytes,0,&aOutputBytes,NULL);
+	return iOutputBufferSize;
+	}
+
+EXPORT_C TInt TUnicodeCompressor::FlushL(TUint8* aOutput,TInt aMaxOutputBytes,TInt& aOutputBytes)
+	{
+	DoCompressL(NULL,aOutput,NULL,aMaxOutputBytes,0,&aOutputBytes,NULL);
+	return iOutputBufferSize;
+	}
+
+EXPORT_C TInt TUnicodeCompressor::CompressedSizeL(MUnicodeSource& aInput,TInt aInputWords)
+	{
+	TInt bytes;
+	TUnicodeCompressor c;
+	c.DoCompressL(NULL,NULL,&aInput,KMaxTInt,aInputWords,&bytes,NULL);
+	return bytes;
+	}
+
+// Compress until input or output is exhausted or an exception occurs.
+void TUnicodeCompressor::DoCompressL(RWriteStream* aOutputStream,TUint8* aOutputPointer,MUnicodeSource* aInput,
+									 TInt aMaxOutputBytes,TInt aMaxInputWords,
+									 TInt* aOutputBytes,TInt* aInputWords)
+	{
+	iOutputStream = aOutputStream;
+	iOutputPointer = aOutputPointer;
+	iInput = aInput;
+	iMaxCompressedBytes = aMaxOutputBytes;
+	iMaxUnicodeWords = aMaxInputWords;
+	iCompressedBytes = iUnicodeWords = 0;
+	FlushOutputBufferL();
+	if (iInput)
+		{
+		while (iUnicodeWords < iMaxUnicodeWords && iCompressedBytes < iMaxCompressedBytes)
+			{
+			TUint16 x = iInput->ReadUnicodeValueL();
+			TAction action(x);
+			iInputBuffer[(iInputBufferStart + iInputBufferSize) % EMaxInputBufferSize] = action;
+			iInputBufferSize++;
+			iUnicodeWords++;
+			if (iInputBufferSize == EMaxInputBufferSize)
+				WriteRunL();
+			}
+		}
+	FlushInputBufferL();
+	if (aOutputBytes)
+		*aOutputBytes = iCompressedBytes;
+	if (aInputWords)
+		*aInputWords = iUnicodeWords;
+	}
+
+TUnicodeCompressor::TAction::TAction(TUint16 aCode):
+	iCode(aCode)
+	{
+	if (TUnicodeCompressionState::EncodeAsIs(aCode))
+		iTreatment = EPlainASCII;
+	else
+		{
+		iTreatment = TUnicodeCompressionState::DynamicWindowOffsetIndex(aCode);
+		if (iTreatment == -1)
+			{
+			iTreatment = TUnicodeCompressionState::StaticWindowIndex(aCode);
+			if (iTreatment == -1)
+				iTreatment = EPlainUnicode;
+			else
+				iTreatment += EFirstStatic;
+			}
+		}
+	}
+
+void TUnicodeCompressor::WriteCharacterFromBuffer()
+	{
+	const TAction& action = iInputBuffer[iInputBufferStart];
+	iInputBufferSize--;
+	iInputBufferStart = (iInputBufferStart + 1) % EMaxInputBufferSize;
+	WriteCharacter(action);
+	}
+
+void TUnicodeCompressor::FlushInputBufferL()
+	{
+	while (iInputBufferSize > 0 && iCompressedBytes < iMaxCompressedBytes)
+		WriteRunL();
+	}
+
+void TUnicodeCompressor::WriteRunL()
+	{
+	// Write out any leading characters that can be passed through.
+	if (!iUnicodeMode)
+		while (iInputBufferSize > 0)
+			{
+			const TAction& action = iInputBuffer[iInputBufferStart];
+			if (action.iTreatment == TAction::EPlainASCII ||
+				(action.iCode >= iActiveWindowBase && action.iCode < iActiveWindowBase + 128))
+				WriteCharacterFromBuffer();
+			else
+				break;
+			}
+
+	// Write a run of characters that cannot be passed through.
+	int i;
+	if (iInputBufferSize > 0)
+		{
+		/*
+		Find a run of characters with the same treatment and select that treatment
+		if the run has more than one character.
+		*/
+		int treatment = iInputBuffer[iInputBufferStart].iTreatment;
+		int next_treatment = treatment;
+		int run_size = 1;
+		for (i = 1; i < iInputBufferSize; i++)
+			{
+			int index = (iInputBufferStart + i) % EMaxInputBufferSize;
+			next_treatment = iInputBuffer[index].iTreatment;
+			if (next_treatment != treatment)
+				break;
+			run_size++;
+			}
+		if (run_size > 1)
+			SelectTreatment(treatment);
+		for (i = 0; i < run_size; i++)
+			WriteCharacterFromBuffer();
+		}
+
+	FlushOutputBufferL();
+	}
+
+void TUnicodeCompressor::FlushOutputBufferL()
+	{
+	while (iOutputBufferSize > 0 &&	iCompressedBytes < iMaxCompressedBytes)
+		{
+		TUint8 byte = iOutputBuffer[iOutputBufferStart];
+		if (iOutputPointer)
+			*iOutputPointer++ = byte;
+		else if (iOutputStream)
+			iOutputStream->WriteUint8L(byte);
+		iCompressedBytes++;
+		iOutputBufferSize--;
+		iOutputBufferStart = (iOutputBufferStart + 1) % EMaxOutputBufferSize;
+		}
+	}
+
+void TUnicodeCompressor::SelectTreatment(TInt aTreatment)
+	{
+	if (aTreatment == TAction::EPlainUnicode)
+		{
+		// Switch to Unicode mode if not there already.
+		if (!iUnicodeMode)
+			{
+			WriteByte(SCU);
+			iUnicodeMode = TRUE;
+			}
+		return;
+		}
+
+	if (aTreatment == TAction::EPlainASCII)
+		{
+		// Switch to single-byte mode, using the current dynamic window, if not there already.
+		if (iUnicodeMode)
+			{
+			WriteByte(UC0 + iDynamicWindowIndex);
+			iUnicodeMode = FALSE;
+			}
+		return;
+		}
+
+	if (aTreatment >= TAction::EFirstDynamic && aTreatment <= TAction::ELastDynamic)
+		{
+		TUint32 base = DynamicWindowBase(aTreatment);
+
+		// Switch to the appropriate dynamic window if it is available; if not, redefine and select dynamic window 4.
+		for (int i = 0; i < EDynamicWindows; i++)
+			if (base == iDynamicWindow[i])
+				{
+				if (iUnicodeMode)
+					WriteByte(UC0 + i);
+				else if (i != iDynamicWindowIndex)
+					WriteByte(SC0 + i);
+				iUnicodeMode = FALSE;
+				iDynamicWindowIndex = i;
+				iActiveWindowBase = base;
+				return;
+				}
+		if (iUnicodeMode)
+			WriteByte(UD0 + 4);
+		else
+			WriteByte(SD0 + 4);
+		iDynamicWindowIndex = 4;
+		iUnicodeMode = FALSE;
+		WriteByte(aTreatment);
+		iDynamicWindow[4] = base;
+		iActiveWindowBase = base;
+		return;
+		}
+	}
+
+// Write a character without changing mode or window.
+void TUnicodeCompressor::WriteCharacter(const TAction& aAction)
+	{
+	if (iUnicodeMode)
+		WriteUCharacter(aAction.iCode);
+	else
+		WriteSCharacter(aAction);
+	}
+
+void TUnicodeCompressor::WriteUCharacter(TUint16 aCode)
+	{
+	// Emit the 'quote Unicode' tag if the character would conflict with a tag.
+	if (aCode >= 0xE000 && aCode <= 0xF2FF)
+		WriteByte(UQU);
+
+	// Write the Unicode value big-end first.
+	WriteByte((aCode >> 8) & 0xFF);
+	WriteByte(aCode & 0xFF);
+	}
+
+void TUnicodeCompressor::WriteByte(TUint aByte)
+	{
+	if (iOutputBufferSize >= EMaxOutputBufferSize)
+		Panic(EOutputBufferOverflow); //Panic here is ok as this is a programming error
+	iOutputBuffer[(iOutputBufferStart + iOutputBufferSize) % EMaxOutputBufferSize] = (TUint8)aByte;
+	iOutputBufferSize++;
+	}
+
+void TUnicodeCompressor::WriteSCharacter(const TAction& aAction)
+	{
+	// Characters in the range 0x0020..0x007F, plus nul, tab, cr, and lf, can be emitted as their low bytes.
+	if (aAction.iTreatment == TAction::EPlainASCII)
+		{
+		WriteByte(aAction.iCode);
+		return;
+		}
+
+	// Characters in a static window can be written using SQ<n> plus a byte in the range 0x00-0x7F
+	if (aAction.iTreatment >= TAction::EFirstStatic && aAction.iTreatment <= TAction::ELastStatic)
+		{
+		int window = aAction.iTreatment - TAction::EFirstStatic;
+		WriteByte(SQ0 + window);
+		WriteByte(aAction.iCode);
+		return;
+		}
+
+	// Characters in the current dynamic window can be written as a byte in the range 0x80-0xFF.
+	if (aAction.iCode >= iActiveWindowBase && aAction.iCode < iActiveWindowBase + 128)
+		{
+		WriteByte(aAction.iCode - iActiveWindowBase + 0x80);
+		return;
+		}
+
+	// Characters in another dynamic window can be written using SQ<n> plus a byte in the range 0x80-0xFF
+	int i;
+	for (i = 0; i < EDynamicWindows; i++)
+		if (aAction.iCode >= iDynamicWindow[i] && aAction.iCode < iDynamicWindow[i] + 128)
+			{
+			WriteByte(SQ0 + i);
+			WriteByte(aAction.iCode - iDynamicWindow[i] + 0x80);
+			return;
+			}
+
+	// Other characters can be quoted.
+	WriteByte(SQU);
+	WriteByte((aAction.iCode >> 8) & 0xFF);
+	WriteByte(aAction.iCode & 0xFF);
+	return;
+	}
+
+EXPORT_C TUnicodeExpander::TUnicodeExpander():
+	iInputBufferStart(0),
+	iInputBufferSize(0),
+	iOutputBufferStart(0),
+	iOutputBufferSize(0),
+	iOutput(NULL),
+	iInputStream(NULL),
+	iInputPointer(NULL)
+	{
+		// Clear coverity warnings
+		memset(iInputBuffer, 0, sizeof(iInputBuffer));
+		memset(iOutputBuffer, 0, sizeof(iOutputBuffer));
+	}
+
+EXPORT_C void TUnicodeExpander::ExpandL(MUnicodeSink& aOutput,RReadStream& aInput,
+										TInt aMaxOutputWords,TInt aMaxInputBytes,
+										TInt* aOutputWords,TInt* aInputBytes)
+	{
+	DoExpandL(&aOutput,&aInput,NULL,aMaxOutputWords,aMaxInputBytes,aOutputWords,aInputBytes);
+	}
+
+EXPORT_C void TUnicodeExpander::ExpandL(MUnicodeSink& aOutput,const TUint8* aInput,
+										TInt aMaxOutputWords,TInt aMaxInputBytes,
+										TInt* aOutputWords,TInt* aInputBytes)
+	{
+	DoExpandL(&aOutput,NULL,aInput,aMaxOutputWords,aMaxInputBytes,aOutputWords,aInputBytes);
+	}
+
+EXPORT_C TInt TUnicodeExpander::FlushL(MUnicodeSink& aOutput,TInt aMaxOutputWords,TInt& aOutputWords)
+	{
+	DoExpandL(&aOutput,NULL,NULL,aMaxOutputWords,0,&aOutputWords,NULL);
+	return iOutputBufferSize;
+	}
+
+EXPORT_C TInt TUnicodeExpander::ExpandedSizeL(RReadStream& aInput,TInt aInputBytes)
+	{
+	TInt words;
+	TUnicodeExpander e;
+	e.DoExpandL(NULL,&aInput,NULL,KMaxTInt,aInputBytes,&words,NULL);
+	return words;
+	}
+
+EXPORT_C TInt TUnicodeExpander::ExpandedSizeL(const TUint8* aInput,TInt aInputBytes)
+	{
+	TInt words;
+	TUnicodeExpander e;
+	e.DoExpandL(NULL,NULL,aInput,KMaxTInt,aInputBytes,&words,NULL);
+	return words;
+	}
+
+// Expand until input or output is exhausted or an exception occurs.
+void TUnicodeExpander::DoExpandL(MUnicodeSink* aOutput,RReadStream* aInputStream,const TUint8* aInputPointer,
+								 TInt aMaxOutputWords,TInt aMaxInputBytes,
+								 TInt* aOutputWords,TInt* aInputBytes)
+	{
+	iOutput = aOutput;
+	iInputStream = aInputStream;
+	iInputPointer = aInputPointer;
+	iMaxUnicodeWords = aMaxOutputWords;
+	iMaxCompressedBytes = aMaxInputBytes;
+	iUnicodeWords = iCompressedBytes = 0;
+	iInputBufferStart = 0;
+	FlushOutputBufferL();
+	if (iInputPointer || iInputStream)
+		{
+		while (iUnicodeWords + iOutputBufferSize < iMaxUnicodeWords && iCompressedBytes < iMaxCompressedBytes)
+			HandleByteL();
+		}
+	if (aOutputWords)
+		*aOutputWords = iUnicodeWords;
+	if (aInputBytes)
+		*aInputBytes = iCompressedBytes;
+	}
+
+void TUnicodeExpander::HandleByteL()
+	{
+	TUint8 byte;
+	TBool handled = FALSE;
+	if (ReadByteL(byte))
+		{
+		if (iUnicodeMode)
+			handled = HandleUByteL(byte);
+		else
+			handled = HandleSByteL(byte);
+		}
+	iInputBufferStart = 0;
+	if (handled)
+		iInputBufferSize = 0;
+	FlushOutputBufferL();
+	}
+
+void TUnicodeExpander::FlushOutputBufferL()
+	{
+	while (iOutputBufferSize > 0 &&	iUnicodeWords < iMaxUnicodeWords)
+		{
+		if (iOutput)
+			iOutput->WriteUnicodeValueL(iOutputBuffer[iOutputBufferStart]);
+		iUnicodeWords++;
+		iOutputBufferSize--;
+		iOutputBufferStart = (iOutputBufferStart + 1) % EMaxOutputBufferSize;
+		}
+	}
+
+TBool TUnicodeExpander::HandleSByteL(TUint8 aByte)
+	{
+	// 'Pass-through' codes.
+	if (TUnicodeCompressionState::EncodeAsIs(aByte))
+		{
+		WriteChar(aByte);
+		return TRUE;
+		}
+
+	// Codes 0x80-0xFF select a character from the active window.
+	if (aByte >= 0x80)
+		{
+		WriteChar32(iActiveWindowBase + aByte - 0x80);
+		return TRUE;
+		}
+
+	// SQU: quote a Unicode character.
+	if (aByte == SQU)
+		return QuoteUnicodeL();
+
+	// SCU: switch to Unicode mode.
+	if (aByte == SCU)
+		{
+		iUnicodeMode = TRUE;
+		return TRUE;
+		}
+
+	// SQn: quote from window n.
+	if (aByte >= SQ0 && aByte <= SQ0 + 7)
+		{
+		int window = aByte - SQ0;
+		TUint8 byte;
+		if (ReadByteL(byte))
+			{
+			TUint32 c = byte;
+			if (c <= 0x7F)
+				c += iStaticWindow[window];
+			else
+				c += iDynamicWindow[window] - 0x80;
+			WriteChar32(c);
+			return TRUE;
+			}
+		else
+			return FALSE;
+		}
+
+	// SCn: switch to dynamic window n.
+	if (aByte >= SC0 && aByte <= SC0 + 7)
+		{
+		iActiveWindowBase = iDynamicWindow[aByte - SC0];
+		return TRUE;
+		}
+
+	// SDn: define dynamic window n and switch to it.
+	if (aByte >= SD0 && aByte <= SD0 + 7)
+		return DefineWindowL(aByte - SD0);
+
+	// SDX: define window in the expansion space.
+	if (aByte == SDX)
+		return DefineExpansionWindowL();
+
+	User::Leave(KErrCorrupt);
+	return FALSE;
+	}
+
+TBool TUnicodeExpander::HandleUByteL(TUint8 aByte)
+	{
+	// Plain Unicode; get the low byte and emit the Unicode value.
+	if (aByte <= 0xDF || aByte >= 0xF3)
+		{
+		TUint8 lo;
+		if (ReadByteL(lo))
+			{
+			TUint16 c = (TUint16)((aByte << 8) | lo);
+			WriteChar(c);
+			return TRUE;
+			}
+		else
+			return FALSE;
+		}
+
+	// Quote a Unicode character that would otherwise conflict with a tag.
+	if (aByte == UQU)
+		return QuoteUnicodeL();
+
+	// UCn: change to single byte mode and select window n.
+	if (aByte >= UC0 && aByte <= UC0 + 7)
+		{
+		iUnicodeMode = FALSE;
+		iActiveWindowBase = iDynamicWindow[aByte - UC0];
+		return TRUE;
+		}
+
+	// UDn: define dynamic window n and switch to it.
+	if (aByte >= UD0 && aByte <= UD0 + 7)
+		return DefineWindowL(aByte - UD0);
+
+	// UDX: define window in the expansion space.
+	if (aByte == UDX)
+		return DefineExpansionWindowL();
+
+	User::Leave(KErrCorrupt);
+	return FALSE;
+	}
+
+TBool TUnicodeExpander::QuoteUnicodeL()
+	{
+	TUint8 hi, lo;
+	if (ReadByteL(hi) && ReadByteL(lo))
+		{
+		TUint16 c = (TUint16)((hi << 8) | lo);
+		WriteChar(c);
+		return TRUE;
+		}
+	else
+		return FALSE;
+	}
+
+TBool TUnicodeExpander::DefineWindowL(TInt aIndex)
+	{
+	TUint8 window;
+	if (ReadByteL(window))
+		{
+		iUnicodeMode = FALSE;
+		iActiveWindowBase = DynamicWindowBase(window);
+		iDynamicWindow[aIndex] = iActiveWindowBase;
+		return TRUE;
+		}
+	else
+		return FALSE;
+	}
+
+TBool TUnicodeExpander::DefineExpansionWindowL()
+	{
+	TUint8 hi, lo;
+	if (ReadByteL(hi) && ReadByteL(lo))
+		{
+		iUnicodeMode = FALSE;
+		iActiveWindowBase = 0x10000 + (0x80 * ((hi & 0x1F) * 0x100 + lo));
+		iDynamicWindow[hi >> 5] = iActiveWindowBase;
+		return TRUE;
+		}
+	else
+		return FALSE;
+	}
+
+// Read either from the buffer (in the case of restarting after source finished in mid-operation) or from the source.
+TBool TUnicodeExpander::ReadByteL(TUint8& aByte)
+	{
+	if (iInputBufferStart < iInputBufferSize)
+		{
+		aByte = iInputBuffer[iInputBufferStart++];
+		return TRUE;
+		}
+	else if (iCompressedBytes < iMaxCompressedBytes)
+		{
+		if (iInputPointer)
+			aByte = *iInputPointer++;
+		else
+			aByte = iInputStream->ReadUint8L();
+		iInputBuffer[iInputBufferStart++] = aByte;
+		iInputBufferSize = iInputBufferStart;
+		iCompressedBytes++;
+		return TRUE;
+		}
+	else
+		return FALSE;
+	}
+
+void TUnicodeExpander::WriteChar(TUint16 aChar)
+	{
+	if (iOutputBufferSize >= EMaxOutputBufferSize)
+		Panic(EOutputBufferOverflow); //Panic here is ok since this is a programming error
+	iOutputBuffer[(iOutputBufferStart + iOutputBufferSize) % EMaxOutputBufferSize] = aChar;
+	iOutputBufferSize++;
+	}
+
+// Write a Unicode character; write using surrogates if in the range 0x10000..0x10FFFF.
+void TUnicodeExpander::WriteChar32(TUint aChar)
+	{
+	if (aChar <= 0xFFFF)
+		WriteChar((TUint16)aChar);
+	else if (aChar <= 0x10FFFF)
+		{
+		aChar -= 0x10000;									// reduce to 20-bit value in the range 0x0..0xFFFFF
+		WriteChar((TUint16)(0xD800 + (aChar >> 10)));		// first high surrogate + high 10 bits
+		WriteChar((TUint16)(0xDC00 + (aChar & 0x03FF)));	// first low surrogate + low 10 bits
+		}
+	else
+		//Panic to be kept here as impossible to test this case (nor the one before). Biggest value that can be passed is 0xFFFFF 
+		Panic(ENotUnicode);
+	}
+
+#endif // _UNICODE