imgtools/imglib/host/utf16string.cpp
changeset 607 378360dbbdba
parent 606 30b30f9da0b7
equal deleted inserted replaced
591:22486c9c7b15 607:378360dbbdba
       
     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 		aLength = 0 ;
       
    45 		const TUint16* p = aUtf16Str ;
       
    46 		while(*p){
       
    47 			p++ ;
       
    48 			aLength ++ ;
       
    49 		}
       
    50 	}
       
    51 	if(aLength > 0){		
       
    52 		iLength = aLength ;
       
    53 		aLength <<= 1 ;
       
    54 		iData = new TUint16[iLength + 1] ;
       
    55 		memcpy(iData,aUtf16Str,aLength);
       
    56 		iData[iLength] = 0;
       
    57 	}else{
       
    58 		iData = 0 ;
       
    59 		iLength = 0 ;
       
    60 	}
       
    61 	
       
    62 }
       
    63 UTF16String::UTF16String(const char* aUtf8Str,TInt aLength /*= -1 */){
       
    64 	iData = 0 ;
       
    65 	iLength = 0 ;	
       
    66 	Assign(aUtf8Str,aLength);
       
    67 }	
       
    68 UTF16String::~UTF16String(){
       
    69 	if(iData)
       
    70 		delete []iData ;
       
    71 }	
       
    72 
       
    73 UTF16String& UTF16String::operator = (const UTF16String& aRight){
       
    74 	if(&aRight != this){
       
    75 		if(iData) 
       
    76 			delete []iData ; 
       
    77 		iLength = aRight.iLength ;
       
    78 		iData = new TUint16[iLength + 1];
       
    79 		memcpy(iData,aRight.iData, iLength << 1);
       
    80 		iData[iLength] = 0;
       
    81 	}
       
    82 	return *this;
       
    83 }
       
    84 bool UTF16String::FromFile(const char* aFileName){
       
    85 	if(!aFileName || !(*aFileName))
       
    86 		return false ;
       
    87 	ifstream ifs(aFileName,ios_base::in + ios_base::binary); 	
       
    88 	if(!ifs.is_open())
       
    89 		return false ;
       
    90 	
       
    91 	ifs.seekg(0,ios_base::end);
       
    92 	size_t length = ifs.tellg();
       
    93 	if((length % 2) == 1 ){
       
    94 		ifs.close() ;
       
    95 		return false ;
       
    96 	}
       
    97 	ifs.seekg(0,ios_base::beg);
       
    98 	TUint16 hdr ;
       
    99 	size_t readLen = length - sizeof(hdr) ;
       
   100 	length >>= 1 ;	
       
   101 	TUint16 *newData = new TUint16[length + 1];
       
   102 	ifs.read(reinterpret_cast<char*>(&hdr),sizeof(hdr));		
       
   103 	if(hdr == 0xFEFF){ 
       
   104 		ifs.read(reinterpret_cast<char*>(newData),readLen);
       
   105 		length -- ;
       
   106 	}
       
   107 	else{		 
       
   108 		*newData = hdr ;
       
   109 		ifs.read(reinterpret_cast<char*>(&newData[1]),readLen);
       
   110 	} 
       
   111 	ifs.close();
       
   112 	iLength = length ;
       
   113 	if(iData)
       
   114 		delete []iData ;
       
   115 	iData = newData ;
       
   116 	iData[iLength] = 0;	
       
   117 	return true ;
       
   118 }
       
   119 /**
       
   120 * aResult will not changed on error
       
   121 */
       
   122 bool UTF16String::ToUTF8(string& aResult) const {
       
   123 	if(IsEmpty()){
       
   124 		aResult = "";
       
   125 		return true;
       
   126 	}
       
   127 	size_t bufLen = (iLength + 1) << 2 ;
       
   128 	char* buffer = new char[bufLen] ;
       
   129 #ifdef WIN32
       
   130 	int r = WideCharToMultiByte(CP_UTF8,0,reinterpret_cast<WCHAR*>(iData),iLength,buffer,bufLen,NULL,NULL);
       
   131 	if(r < 0){
       
   132 		delete []buffer ;
       
   133 		return false ;
       
   134 	}
       
   135 	buffer[r] = 0;
       
   136 	aResult.assign(buffer,r);
       
   137 #else
       
   138 	iconv_t it = iconv_open("UTF-8","UTF-16");
       
   139 	if((iconv_t)(-1) == it){ 
       
   140 		return  false;
       
   141 	}
       
   142 	char* bufferEnd = buffer ;
       
   143 	char* in_ptr = reinterpret_cast<char*>(iData);
       
   144 	size_t in_len = iLength << 1 ;
       
   145 	iconv(it,&in_ptr,&in_len ,&bufferEnd,&bufLen);
       
   146 	iconv_close(it);
       
   147 	*bufferEnd = 0 ;
       
   148 	size_t length = bufferEnd - buffer ;
       
   149 	aResult.assign(buffer,length);
       
   150 #endif
       
   151 	delete []buffer ;
       
   152 	return true ;
       
   153 }
       
   154 bool UTF16String::Assign(const char* aUtf8Str,TInt aLength /* = -1*/) {
       
   155 	if(0 == aUtf8Str) return false ;	
       
   156 	if(aLength < 0) aLength = strlen(aUtf8Str); 
       
   157 		
       
   158 #ifdef WIN32
       
   159 	size_t newLength = aLength + 1;
       
   160 	TUint16* newData = new TUint16[newLength];
       
   161 	int r = MultiByteToWideChar(CP_UTF8,0,aUtf8Str,aLength,reinterpret_cast<WCHAR*>(newData),newLength);
       
   162 	if(r < 0){
       
   163 		delete []newData ;
       
   164 		return false ;
       
   165 	}
       
   166 	iLength = r ;	
       
   167 #else
       
   168 	char* forFree = 0 ;
       
   169 	if(aUtf8Str[aLength - 1] != 0){
       
   170 		forFree = new char[aLength + 1];
       
   171 		memcpy(forFree,aUtf8Str,aLength );
       
   172 		forFree[aLength] = 0;
       
   173 		aUtf8Str = forFree ;
       
   174 	}
       
   175 	iconv_t it = iconv_open("UTF-16","UTF-8");
       
   176 	if((iconv_t)(-1) == it){ 
       
   177 		 
       
   178 		return  false;
       
   179 	}
       
   180 	size_t newLength = aLength + 2;
       
   181 	TUint16* newData = new TUint16[newLength];
       
   182 	newLength <<= 1;
       
   183 	char* out_ptr = reinterpret_cast<char*>(newData);
       
   184 	size_t in_len = aLength ;
       
   185 	char* in_ptr = const_cast<char*>(aUtf8Str);
       
   186 	iconv(it,&in_ptr,&in_len ,&out_ptr ,&newLength);
       
   187 	newLength = out_ptr - reinterpret_cast<char*>(newData);
       
   188 	iconv_close(it);
       
   189 	if(newLength % 2 == 1){ //should not be possible
       
   190 		delete []newData;
       
   191 		return false ;
       
   192 	}
       
   193 	iLength = (newLength >> 1) ;
       
   194 	if(forFree)
       
   195 		delete []forFree;
       
   196 #endif
       
   197 	newData[iLength] = 0 ;
       
   198 	if(iData){
       
   199 		delete []iData ;
       
   200 	}
       
   201 	iData = newData ;	
       
   202 	if(*iData == 0xFEFF)
       
   203 		iLength -- ;
       
   204 	
       
   205 	return true ;
       
   206 }
       
   207 static const TUint16 NullUInt16Str[1] = {0};
       
   208 const TUint16* UTF16String::c_str() const {
       
   209 	if(0 == iData)
       
   210 		return NullUInt16Str;
       
   211 	else if(0xFEFF != *iData)
       
   212 		return iData ;
       
   213 	else
       
   214 		return iData + 1;
       
   215 }
       
   216 ///
       
   217 /// aUtf16Str must end with '\0'
       
   218 /// 
       
   219 int UTF16String::Compare(const TUint16* aUtf16Str) const {
       
   220 	if(!aUtf16Str || !(*aUtf16Str))
       
   221 		return (iLength > 0) ? 1 : 0; 
       
   222 	size_t i ;
       
   223 	for(i = 0 ; aUtf16Str[i] != 0 ; i++) { 
       
   224 		if( iData[i] > aUtf16Str[i])
       
   225 			return 1;
       
   226 		else if(iData[i] < aUtf16Str[i])
       
   227 			return -1 ;
       
   228 	}
       
   229 	return (i < iLength) ? 1 : 0 ; 
       
   230 }
       
   231 ///
       
   232 /// aUtf16Str must end with '\0'
       
   233 /// 
       
   234 int UTF16String::CompareNoCase(const TUint16* aUtf16Str) const {
       
   235 	if(!aUtf16Str || !(*aUtf16Str))
       
   236 		return (iLength > 0) ? 1 : 0; 
       
   237 	size_t i ;
       
   238 	TUint16 a, b;
       
   239 	for(i = 0 ; aUtf16Str[i] != 0 ; i++) { 
       
   240 		a = iData[i];
       
   241 		b = aUtf16Str[i] ;
       
   242 		if( a >= 'A' && a <= 'Z') a |= 0x20 ;
       
   243 		if( b >= 'A' && b <= 'Z') b |= 0x20 ;
       
   244 			
       
   245 		if( a > b )
       
   246 			return 1;
       
   247 		else if( a < b )
       
   248 			return -1 ;
       
   249 	}
       
   250 	return (i < iLength) ? 1 : 0 ; 
       
   251 }
       
   252 TUint16* UTF16String::Alloc(size_t aNewLen) {
       
   253 	TUint16* newData = new TUint16[aNewLen + 1] ;
       
   254 	if(!newData) return 0;
       
   255 	if(iData) delete []iData ;
       
   256 	
       
   257 	iLength = aNewLen ;
       
   258 	iData = newData ;
       
   259 	*iData = 0 ;
       
   260 	iData[aNewLen] = 0;
       
   261 	return iData;
       
   262 }