imgtools/imglib/host/utf16string.cpp
changeset 600 6d08f4a05d93
child 606 30b30f9da0b7
equal deleted inserted replaced
599:fa7a3cc6effd 600:6d08f4a05d93
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 * @internalComponent * @released
       
    16 *
       
    17 */
       
    18 
       
    19 #include "utf16string.h"
       
    20 #ifdef __LINUX__
       
    21 #include <iconv.h>
       
    22 #elif defined(WIN32)
       
    23 #ifdef _STLP_INTERNAL_WINDOWS_H
       
    24 #define __INTERLOCKED_DECLARED
       
    25 #endif
       
    26 #include <windows.h>
       
    27 #endif
       
    28 UTF16String::UTF16String() :iData(0), iLength(0){
       
    29 }
       
    30 UTF16String::UTF16String(const UTF16String& aRight){
       
    31 	iLength = aRight.iLength ;
       
    32 	iData = new TUint16[iLength + 1];
       
    33 	memcpy(iData,aRight.iData, iLength << 1);
       
    34 	iData[iLength] = 0;
       
    35 }
       
    36 UTF16String::UTF16String(const string& aUtf8Str){
       
    37 	iData = 0 ;
       
    38 	iLength = 0 ;
       
    39 	Assign(aUtf8Str.c_str(),aUtf8Str.length());
       
    40 }
       
    41 UTF16String::UTF16String(const TUint16* aUtf16Str,TInt aLength /* = -1*/){
       
    42 	
       
    43 	if(aLength < 0){
       
    44 		const TUint16* p = aUtf16Str ;
       
    45 		while(*p){
       
    46 			p++ ;
       
    47 			aLength ++ ;
       
    48 		}
       
    49 	}
       
    50 	if(aLength > 0){		
       
    51 		iLength = aLength ;
       
    52 		aLength <<= 1 ;
       
    53 		iData = new TUint16[iLength + 1] ;
       
    54 		memcpy(iData,aUtf16Str,aLength);
       
    55 		iData[iLength] = 0;
       
    56 	}else{
       
    57 		iData = 0 ;
       
    58 		iLength = 0 ;
       
    59 	}
       
    60 	
       
    61 }
       
    62 UTF16String::UTF16String(const char* aUtf8Str,TInt aLength /*= -1 */){
       
    63 	iData = 0 ;
       
    64 	iLength = 0 ;	
       
    65 	Assign(aUtf8Str,aLength);
       
    66 }	
       
    67 UTF16String::~UTF16String(){
       
    68 	if(iData)
       
    69 		delete []iData ;
       
    70 }	
       
    71 
       
    72 UTF16String& UTF16String::operator = (const UTF16String& aRight){
       
    73 	if(&aRight != this){
       
    74 		if(iData) 
       
    75 			delete []iData ; 
       
    76 		iLength = aRight.iLength ;
       
    77 		iData = new TUint16[iLength + 1];
       
    78 		memcpy(iData,aRight.iData, iLength << 1);
       
    79 		iData[iLength] = 0;
       
    80 	}
       
    81 	return *this;
       
    82 }
       
    83 bool UTF16String::FromFile(const char* aFileName){
       
    84 	if(!aFileName || !(*aFileName))
       
    85 		return false ;
       
    86 	ifstream ifs(aFileName,ios_base::in + ios_base::binary); 	
       
    87 	if(!ifs.is_open())
       
    88 		return false ;
       
    89 	
       
    90 	ifs.seekg(0,ios_base::end);
       
    91 	size_t length = ifs.tellg();
       
    92 	if((length % 2) == 1 ){
       
    93 		ifs.close() ;
       
    94 		return false ;
       
    95 	}
       
    96 	ifs.seekg(0,ios_base::beg);
       
    97 	TUint16 hdr ;
       
    98 	size_t readLen = length - sizeof(hdr) ;
       
    99 	length >>= 1 ;	
       
   100 	TUint16 *newData = new TUint16[length + 1];
       
   101 	ifs.read(reinterpret_cast<char*>(&hdr),sizeof(hdr));		
       
   102 	if(hdr == 0xFEFF){ 
       
   103 		ifs.read(reinterpret_cast<char*>(newData),readLen);
       
   104 		length -- ;
       
   105 	}
       
   106 	else{		 
       
   107 		*newData = hdr ;
       
   108 		ifs.read(reinterpret_cast<char*>(&newData[1]),readLen);
       
   109 	} 
       
   110 	ifs.close();
       
   111 	iLength = length ;
       
   112 	if(iData)
       
   113 		delete []iData ;
       
   114 	iData = newData ;
       
   115 	iData[iLength] = 0;	
       
   116 	return true ;
       
   117 }
       
   118 /**
       
   119 * aResult will not changed on error
       
   120 */
       
   121 bool UTF16String::ToUTF8(string& aResult) const {
       
   122 	if(IsEmpty()){
       
   123 		aResult = "";
       
   124 		return true;
       
   125 	}
       
   126 	size_t bufLen = (iLength + 1) << 2 ;
       
   127 	char* buffer = new char[bufLen] ;
       
   128 #ifdef WIN32
       
   129 	int r = WideCharToMultiByte(CP_UTF8,0,reinterpret_cast<WCHAR*>(iData),iLength,buffer,bufLen,NULL,NULL);
       
   130 	if(r < 0){
       
   131 		delete []buffer ;
       
   132 		return false ;
       
   133 	}
       
   134 	buffer[r] = 0;
       
   135 	aResult.assign(buffer,r);
       
   136 #else
       
   137 	iconv_t it = iconv_open("UTF-8","UTF-16");
       
   138 	if((iconv_t)(-1) == it){ 
       
   139 		return  false;
       
   140 	}
       
   141 	char* bufferEnd = buffer ;
       
   142 	char* in_ptr = reinterpret_cast<char*>(iData);
       
   143 	size_t in_len = iLength << 1 ;
       
   144 	iconv(it,&in_ptr,&in_len ,&bufferEnd,&bufLen);
       
   145 	iconv_close(it);
       
   146 	*bufferEnd = 0 ;
       
   147 	size_t length = bufferEnd - buffer ;
       
   148 	aResult.assign(buffer,length);
       
   149 #endif
       
   150 	delete []buffer ;
       
   151 	return true ;
       
   152 }
       
   153 bool UTF16String::Assign(const char* aUtf8Str,TInt aLength /* = -1*/) {
       
   154 	if(0 == aUtf8Str) return false ;	
       
   155 	if(aLength < 0) aLength = strlen(aUtf8Str); 
       
   156 		
       
   157 #ifdef WIN32
       
   158 	size_t newLength = aLength + 1;
       
   159 	TUint16* newData = new TUint16[newLength];
       
   160 	int r = MultiByteToWideChar(CP_UTF8,0,aUtf8Str,aLength,reinterpret_cast<WCHAR*>(newData),newLength);
       
   161 	if(r < 0){
       
   162 		delete []newData ;
       
   163 		return false ;
       
   164 	}
       
   165 	iLength = r ;	
       
   166 #else
       
   167 	char* forFree = 0 ;
       
   168 	if(aUtf8Str[aLength - 1] != 0){
       
   169 		forFree = new char[aLength + 1];
       
   170 		memcpy(forFree,aUtf8Str,aLength );
       
   171 		forFree[aLength] = 0;
       
   172 		aUtf8Str = forFree ;
       
   173 	}
       
   174 	iconv_t it = iconv_open("UTF-16","UTF-8");
       
   175 	if((iconv_t)(-1) == it){ 
       
   176 		 
       
   177 		return  false;
       
   178 	}
       
   179 	size_t newLength = aLength + 2;
       
   180 	TUint16* newData = new TUint16[newLength];
       
   181 	newLength <<= 1;
       
   182 	char* out_ptr = reinterpret_cast<char*>(newData);
       
   183 	size_t in_len = aLength ;
       
   184 	char* in_ptr = const_cast<char*>(aUtf8Str);
       
   185 	iconv(it,&in_ptr,&in_len ,&out_ptr ,&newLength);
       
   186 	newLength = out_ptr - reinterpret_cast<char*>(newData);
       
   187 	iconv_close(it);
       
   188 	if(newLength % 2 == 1){ //should not be possible
       
   189 		delete []newData;
       
   190 		return false ;
       
   191 	}
       
   192 	iLength = (newLength >> 1) ;
       
   193 	if(forFree)
       
   194 		delete []forFree;
       
   195 #endif
       
   196 	newData[iLength] = 0 ;
       
   197 	if(iData){
       
   198 		delete []iData ;
       
   199 	}
       
   200 	iData = newData ;	
       
   201 	if(*iData == 0xFEFF)
       
   202 		iLength -- ;
       
   203 	
       
   204 	return true ;
       
   205 }
       
   206 static const TUint16 NullUInt16Str[1] = {0};
       
   207 const TUint16* UTF16String::c_str() const {
       
   208 	if(0 == iData)
       
   209 		return NullUInt16Str;
       
   210 	else if(0xFEFF != *iData)
       
   211 		return iData ;
       
   212 	else
       
   213 		return iData + 1;
       
   214 }
       
   215 ///
       
   216 /// aUtf16Str must end with '\0'
       
   217 /// 
       
   218 int UTF16String::Compare(const TUint16* aUtf16Str) const {
       
   219 	if(!aUtf16Str || !(*aUtf16Str))
       
   220 		return (iLength > 0) ? 1 : 0; 
       
   221 	size_t i ;
       
   222 	for(i = 0 ; aUtf16Str[i] != 0 ; i++) { 
       
   223 		if( iData[i] > aUtf16Str[i])
       
   224 			return 1;
       
   225 		else if(iData[i] < aUtf16Str[i])
       
   226 			return -1 ;
       
   227 	}
       
   228 	return (i < iLength) ? 1 : 0 ; 
       
   229 }
       
   230 ///
       
   231 /// aUtf16Str must end with '\0'
       
   232 /// 
       
   233 int UTF16String::CompareNoCase(const TUint16* aUtf16Str) const {
       
   234 	if(!aUtf16Str || !(*aUtf16Str))
       
   235 		return (iLength > 0) ? 1 : 0; 
       
   236 	size_t i ;
       
   237 	TUint16 a, b;
       
   238 	for(i = 0 ; aUtf16Str[i] != 0 ; i++) { 
       
   239 		a = iData[i];
       
   240 		b = aUtf16Str[i] ;
       
   241 		if( a >= 'A' && a <= 'Z') a |= 0x20 ;
       
   242 		if( b >= 'A' && b <= 'Z') b |= 0x20 ;
       
   243 			
       
   244 		if( a > b )
       
   245 			return 1;
       
   246 		else if( a < b )
       
   247 			return -1 ;
       
   248 	}
       
   249 	return (i < iLength) ? 1 : 0 ; 
       
   250 }
       
   251 TUint16* UTF16String::Alloc(size_t aNewLen) {
       
   252 	TUint16* newData = new TUint16[aNewLen + 1] ;
       
   253 	if(!newData) return 0;
       
   254 	if(iData) delete []iData ;
       
   255 	
       
   256 	iLength = aNewLen ;
       
   257 	iData = newData ;
       
   258 	*iData = 0 ;
       
   259 	iData[aNewLen] = 0;
       
   260 	return iData;
       
   261 }