charconvfw/charconvplugins/src/plugins/ucs2.cpp
changeset 0 1fb32624e06b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/charconvfw/charconvplugins/src/plugins/ucs2.cpp	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,278 @@
+/*
+* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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: 
+*
+*/
+
+
+#include <e32std.h>
+#include <charconv.h>
+#include <convgeneratedcpp.h>
+#include "ucs2.h"
+#include <ecom/implementationproxy.h>
+#include <charactersetconverter.h>
+
+class CUCS2ConverterImpl : public CCharacterSetConverterPluginInterface
+	{
+
+public:
+	virtual const TDesC8& ReplacementForUnconvertibleUnicodeCharacters();
+
+	virtual TInt ConvertFromUnicode(
+		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
+		const TDesC8& aReplacementForUnconvertibleUnicodeCharacters, 
+		TDes8& aForeign, 
+		const TDesC16& aUnicode, 
+		CCnvCharacterSetConverter::TArrayOfAscendingIndices& aIndicesOfUnconvertibleCharacters);
+
+	virtual TInt ConvertToUnicode(
+		CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
+		TDes16& aUnicode, 
+		const TDesC8& aForeign, 
+		TInt& aState, 
+		TInt& aNumberOfUnconvertibleCharacters, 
+		TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter);
+
+	virtual TBool IsInThisCharacterSetL(
+		TBool& aSetToTrue, 
+		TInt& aConfidenceLevel, 
+		const TDesC8& aSample);
+
+	static CUCS2ConverterImpl* NewL();
+	virtual ~CUCS2ConverterImpl();
+
+private:
+	CUCS2ConverterImpl();
+
+	};
+
+
+
+// The following code has been copied and modified from the plugin computer generated code
+// that is generated from the charconv/data/???.cpl && /???.txt files
+// *** code begins ***
+#define ARRAY_LENGTH(aArray) (sizeof(aArray)/sizeof((aArray)[0]))
+
+#pragma warning (disable: 4049) // compiler limit : terminating line number emission
+
+_LIT8(KLit8ReplacementForUnconvertibleUnicodeCharacters, "\xff\xfd");
+
+GLDEF_C const TDesC8& ReplacementForUnconvertibleUnicodeCharacters_internal()
+	{
+	return KLit8ReplacementForUnconvertibleUnicodeCharacters;
+	}
+
+GLDEF_D const SCnvConversionData conversionData=
+	{
+	SCnvConversionData::EUnspecified,
+	{NULL,NULL},
+	{NULL,NULL},
+	{NULL,NULL},
+	NULL,
+	NULL
+	};
+
+
+const TInt    KByteOrderMark = 0xfeff;
+const TInt 	  KStateOffset = 0x1000;
+
+
+const TDesC8& CUCS2ConverterImpl::ReplacementForUnconvertibleUnicodeCharacters()
+	{
+	return ReplacementForUnconvertibleUnicodeCharacters_internal();
+	}
+
+
+/**
+ * Takes a 16 bit UCS2 descriptor with or without BOM and translates it to an
+ * eight bit descriptor in Big Endian format.
+ *
+ * Note aDefaultEndiannessOfForeignCharacters is not used by this converter
+ *
+ * @param CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters
+ * @param const TDesC8&
+ * @param TDes8& aForeign
+ * @param const TDesC16& aUnicode
+ * @param CCnvCharacterSetConverter::TArrayOfAscendingIndices&
+ *
+ * returns number of converted characters
+*/
+TInt CUCS2ConverterImpl::ConvertFromUnicode(CCnvCharacterSetConverter::TEndianness /*aDefaultEndiannessOfForeignCharacters*/, 
+								 const TDesC8& /*aReplacementForUnconvertibleUnicodeCharacters*/, 
+								 TDes8& aForeign, 
+								 const TDesC16& aUnicode, 
+								 CCnvCharacterSetConverter::TArrayOfAscendingIndices& /*aIndicesOfUnconvertibleCharacters*/)
+	{
+	TInt numberOfUnicodeCharacters =0;
+	TInt nextChar;
+	
+	// start at the begining of the output buffer
+	aForeign.Zero();
+	
+	// while there is unicode data to convert and space in the output buffer
+	while ( (aForeign.Length() + 1 < aForeign.MaxLength()) && (numberOfUnicodeCharacters < aUnicode.Length()) )
+		{
+		nextChar = aUnicode[numberOfUnicodeCharacters];
+
+		// Note - this always converts to EBigEndian 
+		aForeign.Append((nextChar & 0xff00) >> 8);
+		aForeign.Append(nextChar & 0xff );
+			
+		numberOfUnicodeCharacters++;
+		}
+		
+	// returns the number of unconverted characters left at the end of the input descriptor  
+	return aUnicode.Length() - numberOfUnicodeCharacters;
+	}
+
+/**
+ * Takes an 8 bit descriptor with or without a BOM and translates it to unicode 
+ * Input endiness is determined by Byte Order Markers (BOM) in the source text.
+ * If no BOM is present aDefaultEndiannessOfForeignCharacters is used.
+ *
+ * When the data is too large to fit in the output buffer, the endiness is saved in the state
+ * variable between conversions
+ *
+ * @param aDefaultEndiannessOfForeignCharacters Default endiness if no BOMs present in the source
+ * @param aUnicode Contains the converted text in the Unicode character set
+ * @param aForeign The non-Unicode source text to be converted
+ * @param aState Not used by this converter
+ * @param aNumberOfUnconvertibleCharacters Contains the number of bytes which could not be converted to unicode
+ * @param aIndexOfFirstByteOfFirstUnconvertibleCharacter The index of the first unconvertable byte or -1 if all converted.
+ *
+ * @return aNumberOfUnconvertibleCharacters The number of unconverted bytes left at the end of the input 
+ * descriptor (e.g. because the output descriptor is not long enough to hold all the text), or one of the 
+ * error values defined in TError. 
+ * @internalTechnology 
+ */
+TInt CUCS2ConverterImpl::ConvertToUnicode(CCnvCharacterSetConverter::TEndianness aDefaultEndiannessOfForeignCharacters, 
+						   TDes16& aUnicode,	
+						   const TDesC8& aForeign,
+						   TInt& aState,
+						   TInt& aNumberOfUnconvertibleCharacters, 
+						   TInt& aIndexOfFirstByteOfFirstUnconvertibleCharacter) 
+	{
+	TInt numberOfBytesConverted = 0;
+	TInt numberOfUnicodeCharacters =0;
+	TChar nextChar;
+	
+	// work out what byte order to use
+	CCnvCharacterSetConverter::TEndianness byteOrderMark;
+	if ( aState==CCnvCharacterSetConverter::KStateDefault )
+		{
+		// this is the first call so use the default or BOM for byte order
+		byteOrderMark = aDefaultEndiannessOfForeignCharacters;
+		}
+	else
+		{
+		// this is not the first call so use the saved byte order
+		byteOrderMark = STATIC_CAST( CCnvCharacterSetConverter::TEndianness, aState - KStateOffset );
+		}
+		
+	if ( aForeign.Length() < 2)
+		{ // too small to do anything with		
+		return -1;
+		}
+	// If the state is KStateDefault (this is the first call) check for BOM markers
+	else if (aState==CCnvCharacterSetConverter::KStateDefault)
+		{
+		// is there a Little Endian BOM
+		if (aForeign[0]==0xff && aForeign[1]==0xfe )
+			{ 
+			byteOrderMark = CCnvCharacterSetConverter::ELittleEndian; 
+			}
+		else if (aForeign[0]==0xfe && aForeign[1]==0xff )
+			{
+			byteOrderMark = CCnvCharacterSetConverter::EBigEndian; 
+			}
+		// remember the detected state
+		aState = byteOrderMark + KStateOffset;
+		}
+
+	// start at begining of the output buffer provided
+	aUnicode.Zero();
+	
+	// while there is at least 2 bytes of data to convert and space in the output buffer
+	while ( (numberOfBytesConverted+1 < aForeign.Size()) && (numberOfUnicodeCharacters < aUnicode.MaxLength()) )
+		{
+		if (byteOrderMark == CCnvCharacterSetConverter::ELittleEndian )
+			{
+			// ELittleEndian 0x??00
+			nextChar = aForeign[numberOfBytesConverted] + ( aForeign[numberOfBytesConverted+1] << 8);
+			}
+		else
+			{
+			// EBigEndian 0x00??
+			nextChar = ( aForeign[numberOfBytesConverted] <<8 ) + aForeign[numberOfBytesConverted+1];
+			}
+			
+		// save the unicode character extracted	unless it's a BOM
+		if ( nextChar != KByteOrderMark )
+			{
+			aUnicode.Append( nextChar );
+			numberOfUnicodeCharacters++;	
+			}
+			
+		numberOfBytesConverted+=2;
+		}
+	
+	// there are no uncovertable characters with UCS2,
+	aNumberOfUnconvertibleCharacters = 0;
+	// a negative value indicates that all characters converted
+	aIndexOfFirstByteOfFirstUnconvertibleCharacter = -1;
+			
+	// returns the number of unconverted bytes left at the end of the input descriptor 
+	// Note there could be 1 byte left over if an odd number of bytes provided for conversion
+	return aForeign.Size() - numberOfBytesConverted;
+	}
+
+
+/**
+ * This converter does not support autodetect so always returns a confidence value of 0.
+ * @internalTechnology 
+ */
+TBool CUCS2ConverterImpl::IsInThisCharacterSetL(TBool& aSetToTrue, TInt& aConfidenceLevel, const TDesC8&)
+	{
+	aSetToTrue=ETrue;
+	aConfidenceLevel=0;
+	return EFalse;
+	}
+
+CUCS2ConverterImpl* CUCS2ConverterImpl::NewL()
+	{
+	CUCS2ConverterImpl* self = new(ELeave) CUCS2ConverterImpl();
+	return self;
+	}
+
+CUCS2ConverterImpl::~CUCS2ConverterImpl()
+	{
+	}
+
+CUCS2ConverterImpl::CUCS2ConverterImpl()
+	{
+	}
+
+const TImplementationProxy ImplementationTable[] = 
+	{
+		IMPLEMENTATION_PROXY_ENTRY(0x101FF492,	CUCS2ConverterImpl::NewL)
+	};
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+	{
+	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+
+	return ImplementationTable;
+	}
+
+