imgtools/imglib/host/utf16string.cpp
changeset 600 6d08f4a05d93
child 606 30b30f9da0b7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/imglib/host/utf16string.cpp	Fri Jun 25 18:11:34 2010 +0800
@@ -0,0 +1,261 @@
+/*
+* Copyright (c) 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: 
+* @internalComponent * @released
+*
+*/
+
+#include "utf16string.h"
+#ifdef __LINUX__
+#include <iconv.h>
+#elif defined(WIN32)
+#ifdef _STLP_INTERNAL_WINDOWS_H
+#define __INTERLOCKED_DECLARED
+#endif
+#include <windows.h>
+#endif
+UTF16String::UTF16String() :iData(0), iLength(0){
+}
+UTF16String::UTF16String(const UTF16String& aRight){
+	iLength = aRight.iLength ;
+	iData = new TUint16[iLength + 1];
+	memcpy(iData,aRight.iData, iLength << 1);
+	iData[iLength] = 0;
+}
+UTF16String::UTF16String(const string& aUtf8Str){
+	iData = 0 ;
+	iLength = 0 ;
+	Assign(aUtf8Str.c_str(),aUtf8Str.length());
+}
+UTF16String::UTF16String(const TUint16* aUtf16Str,TInt aLength /* = -1*/){
+	
+	if(aLength < 0){
+		const TUint16* p = aUtf16Str ;
+		while(*p){
+			p++ ;
+			aLength ++ ;
+		}
+	}
+	if(aLength > 0){		
+		iLength = aLength ;
+		aLength <<= 1 ;
+		iData = new TUint16[iLength + 1] ;
+		memcpy(iData,aUtf16Str,aLength);
+		iData[iLength] = 0;
+	}else{
+		iData = 0 ;
+		iLength = 0 ;
+	}
+	
+}
+UTF16String::UTF16String(const char* aUtf8Str,TInt aLength /*= -1 */){
+	iData = 0 ;
+	iLength = 0 ;	
+	Assign(aUtf8Str,aLength);
+}	
+UTF16String::~UTF16String(){
+	if(iData)
+		delete []iData ;
+}	
+
+UTF16String& UTF16String::operator = (const UTF16String& aRight){
+	if(&aRight != this){
+		if(iData) 
+			delete []iData ; 
+		iLength = aRight.iLength ;
+		iData = new TUint16[iLength + 1];
+		memcpy(iData,aRight.iData, iLength << 1);
+		iData[iLength] = 0;
+	}
+	return *this;
+}
+bool UTF16String::FromFile(const char* aFileName){
+	if(!aFileName || !(*aFileName))
+		return false ;
+	ifstream ifs(aFileName,ios_base::in + ios_base::binary); 	
+	if(!ifs.is_open())
+		return false ;
+	
+	ifs.seekg(0,ios_base::end);
+	size_t length = ifs.tellg();
+	if((length % 2) == 1 ){
+		ifs.close() ;
+		return false ;
+	}
+	ifs.seekg(0,ios_base::beg);
+	TUint16 hdr ;
+	size_t readLen = length - sizeof(hdr) ;
+	length >>= 1 ;	
+	TUint16 *newData = new TUint16[length + 1];
+	ifs.read(reinterpret_cast<char*>(&hdr),sizeof(hdr));		
+	if(hdr == 0xFEFF){ 
+		ifs.read(reinterpret_cast<char*>(newData),readLen);
+		length -- ;
+	}
+	else{		 
+		*newData = hdr ;
+		ifs.read(reinterpret_cast<char*>(&newData[1]),readLen);
+	} 
+	ifs.close();
+	iLength = length ;
+	if(iData)
+		delete []iData ;
+	iData = newData ;
+	iData[iLength] = 0;	
+	return true ;
+}
+/**
+* aResult will not changed on error
+*/
+bool UTF16String::ToUTF8(string& aResult) const {
+	if(IsEmpty()){
+		aResult = "";
+		return true;
+	}
+	size_t bufLen = (iLength + 1) << 2 ;
+	char* buffer = new char[bufLen] ;
+#ifdef WIN32
+	int r = WideCharToMultiByte(CP_UTF8,0,reinterpret_cast<WCHAR*>(iData),iLength,buffer,bufLen,NULL,NULL);
+	if(r < 0){
+		delete []buffer ;
+		return false ;
+	}
+	buffer[r] = 0;
+	aResult.assign(buffer,r);
+#else
+	iconv_t it = iconv_open("UTF-8","UTF-16");
+	if((iconv_t)(-1) == it){ 
+		return  false;
+	}
+	char* bufferEnd = buffer ;
+	char* in_ptr = reinterpret_cast<char*>(iData);
+	size_t in_len = iLength << 1 ;
+	iconv(it,&in_ptr,&in_len ,&bufferEnd,&bufLen);
+	iconv_close(it);
+	*bufferEnd = 0 ;
+	size_t length = bufferEnd - buffer ;
+	aResult.assign(buffer,length);
+#endif
+	delete []buffer ;
+	return true ;
+}
+bool UTF16String::Assign(const char* aUtf8Str,TInt aLength /* = -1*/) {
+	if(0 == aUtf8Str) return false ;	
+	if(aLength < 0) aLength = strlen(aUtf8Str); 
+		
+#ifdef WIN32
+	size_t newLength = aLength + 1;
+	TUint16* newData = new TUint16[newLength];
+	int r = MultiByteToWideChar(CP_UTF8,0,aUtf8Str,aLength,reinterpret_cast<WCHAR*>(newData),newLength);
+	if(r < 0){
+		delete []newData ;
+		return false ;
+	}
+	iLength = r ;	
+#else
+	char* forFree = 0 ;
+	if(aUtf8Str[aLength - 1] != 0){
+		forFree = new char[aLength + 1];
+		memcpy(forFree,aUtf8Str,aLength );
+		forFree[aLength] = 0;
+		aUtf8Str = forFree ;
+	}
+	iconv_t it = iconv_open("UTF-16","UTF-8");
+	if((iconv_t)(-1) == it){ 
+		 
+		return  false;
+	}
+	size_t newLength = aLength + 2;
+	TUint16* newData = new TUint16[newLength];
+	newLength <<= 1;
+	char* out_ptr = reinterpret_cast<char*>(newData);
+	size_t in_len = aLength ;
+	char* in_ptr = const_cast<char*>(aUtf8Str);
+	iconv(it,&in_ptr,&in_len ,&out_ptr ,&newLength);
+	newLength = out_ptr - reinterpret_cast<char*>(newData);
+	iconv_close(it);
+	if(newLength % 2 == 1){ //should not be possible
+		delete []newData;
+		return false ;
+	}
+	iLength = (newLength >> 1) ;
+	if(forFree)
+		delete []forFree;
+#endif
+	newData[iLength] = 0 ;
+	if(iData){
+		delete []iData ;
+	}
+	iData = newData ;	
+	if(*iData == 0xFEFF)
+		iLength -- ;
+	
+	return true ;
+}
+static const TUint16 NullUInt16Str[1] = {0};
+const TUint16* UTF16String::c_str() const {
+	if(0 == iData)
+		return NullUInt16Str;
+	else if(0xFEFF != *iData)
+		return iData ;
+	else
+		return iData + 1;
+}
+///
+/// aUtf16Str must end with '\0'
+/// 
+int UTF16String::Compare(const TUint16* aUtf16Str) const {
+	if(!aUtf16Str || !(*aUtf16Str))
+		return (iLength > 0) ? 1 : 0; 
+	size_t i ;
+	for(i = 0 ; aUtf16Str[i] != 0 ; i++) { 
+		if( iData[i] > aUtf16Str[i])
+			return 1;
+		else if(iData[i] < aUtf16Str[i])
+			return -1 ;
+	}
+	return (i < iLength) ? 1 : 0 ; 
+}
+///
+/// aUtf16Str must end with '\0'
+/// 
+int UTF16String::CompareNoCase(const TUint16* aUtf16Str) const {
+	if(!aUtf16Str || !(*aUtf16Str))
+		return (iLength > 0) ? 1 : 0; 
+	size_t i ;
+	TUint16 a, b;
+	for(i = 0 ; aUtf16Str[i] != 0 ; i++) { 
+		a = iData[i];
+		b = aUtf16Str[i] ;
+		if( a >= 'A' && a <= 'Z') a |= 0x20 ;
+		if( b >= 'A' && b <= 'Z') b |= 0x20 ;
+			
+		if( a > b )
+			return 1;
+		else if( a < b )
+			return -1 ;
+	}
+	return (i < iLength) ? 1 : 0 ; 
+}
+TUint16* UTF16String::Alloc(size_t aNewLen) {
+	TUint16* newData = new TUint16[aNewLen + 1] ;
+	if(!newData) return 0;
+	if(iData) delete []iData ;
+	
+	iLength = aNewLen ;
+	iData = newData ;
+	*iData = 0 ;
+	iData[aNewLen] = 0;
+	return iData;
+}