diff -r fa7a3cc6effd -r 6d08f4a05d93 imgtools/imglib/host/utf16string.cpp --- /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 +#elif defined(WIN32) +#ifdef _STLP_INTERNAL_WINDOWS_H +#define __INTERLOCKED_DECLARED +#endif +#include +#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(&hdr),sizeof(hdr)); + if(hdr == 0xFEFF){ + ifs.read(reinterpret_cast(newData),readLen); + length -- ; + } + else{ + *newData = hdr ; + ifs.read(reinterpret_cast(&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(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(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(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(newData); + size_t in_len = aLength ; + char* in_ptr = const_cast(aUtf8Str); + iconv(it,&in_ptr,&in_len ,&out_ptr ,&newLength); + newLength = out_ptr - reinterpret_cast(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; +}