os/ossrv/genericopenlibs/openenvcore/libc/src/strcoll.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // Name         : strcoll.cpp
    15 // Part of      : MRT
    16 // Implementation for wcpcpy API
    17 // Version      : 1.0
    18 //
    19 
    20 #include <stdlib.h>
    21 #include <string.h>
    22 #include <e32std.h>
    23 #include <charconv.h>
    24 #include <e32des16.h>
    25 #include <f32file.h> 
    26 #include <wchar.h>
    27 #include <langinfo.h>
    28 #include <e32debug.h>
    29 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
    30 #include <collate.h>
    31 #include "localeinfo.h"
    32 #endif
    33 
    34 #ifdef SYMBIAN_DISTINCT_LOCALE_MODEL
    35 #include <utf.h> 
    36 #endif
    37 
    38 #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__)))
    39 #include "libc_wsd_defs.h"
    40 #endif
    41 
    42 
    43 #ifdef __SYMBIAN32__
    44 #define MAX_COL_LEVEL 1
    45 #endif
    46 
    47 #ifdef __cplusplus
    48 extern "C" {
    49 #endif
    50 
    51 #ifdef __SYMBIAN32__
    52 	extern "C" char* LC_COLLATE_LocaleName[30];
    53 #ifdef EMULATOR
    54 
    55 char *GET_WSD_VAR_NAME(LC_COLLATE_LocaleName, g)();
    56 #define LC_COLLATE_LocaleName (GET_WSD_VAR_NAME(LC_COLLATE_LocaleName, g)())
    57 #endif //EMULATOR
    58 
    59 #endif //__SYMBIAN32__
    60 
    61 #ifdef __cplusplus
    62 }
    63 #endif
    64 
    65 static int DoConvertionToUnicode(const char* s1, TUint16* aUnicodeText);
    66 
    67 EXPORT_C
    68 int strcoll(const char *s1, const char *s2)
    69 {
    70 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
    71     TInt retVal;
    72 	char *ret=NULL;
    73 #endif
    74 	if((strcmp("C",(const char*) LC_COLLATE_LocaleName)==0) ||(strcmp("POSIX", (const char*) LC_COLLATE_LocaleName)==0)) 
    75 		return strcmp (s1,s2);
    76 	else	  	
    77 	{
    78 		TUint16* text1 = new TText16[strlen(s1) + 1];
    79 		TUint16* text2 = new TText16[strlen(s2 ) + 1];
    80 		
    81 		if((DoConvertionToUnicode(s1, text1) == -1) || (DoConvertionToUnicode(s2, text2) == -1))
    82 			{
    83 		  	delete [] text1;
    84 		 	delete [] text2;
    85 			return -1;
    86 			}
    87 
    88 		const TPtrC leftString((TText*) text1);
    89 		const TPtrC rightString((TText*) text2);
    90 		
    91 		TInt left = leftString.Length();
    92 		TInt right = rightString.Length();
    93 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
    94 		ret=(char*)LC_COLLATE_LocaleName;
    95 		if(*ret==NULL)
    96 		{
    97 #endif
    98 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
    99 		retVal = Mem :: CompareC(text1,left,text2,right, MAX_COL_LEVEL,NULL);	
   100 #else
   101 	   	TInt retVal = Mem :: CompareC(text1,left,text2,right, MAX_COL_LEVEL,NULL);
   102 #endif
   103 #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT
   104         }
   105         else
   106         {
   107         CLocale* loc = CLocale::GetInstance();
   108         TExtendedLocale elocale;
   109         const TText* text;
   110         
   111         #ifdef SYMBIAN_DISTINCT_LOCALE_MODEL
   112         text = loc->GetCollateLocaleName();
   113         TPtrC localenew(text);
   114         retVal = elocale.LoadLocaleAspect(localenew); 
   115         if ( retVal == KErrNotFound ) // load old collate dll
   116             {
   117             text = loc->GetLocaleName();
   118             TPtrC locale(text);
   119             retVal = elocale.LoadLocaleAspect(ELocaleCollateSetting,locale);  
   120             }
   121         #else
   122         text = loc->GetLocaleName();
   123         TPtrC locale(text);
   124         retVal = elocale.LoadLocaleAspect(ELocaleCollateSetting,locale);  
   125         #endif
   126         if( retVal == KErrNone )
   127             {    
   128             TCollationMethod chmethod=elocale.GetPreferredCollationMethod(0);
   129             retVal = Mem :: CompareC(text1,left,text2,right, MAX_COL_LEVEL,&chmethod);
   130             }
   131         }
   132 #endif
   133 	  	delete [] text1;
   134 	 	delete [] text2;
   135 		return retVal;
   136 	}	
   137 		 
   138 }
   139 
   140 static int DoConvertionToUnicode( const char* s1, TUint16* aUnicodeText)
   141 {
   142 
   143     TInt r = KErrNone;
   144     RFs fileSession;
   145     r = fileSession.Connect();
   146     if (r != KErrNone)
   147         {
   148             return r;
   149         }
   150     CleanupClosePushL(fileSession);
   151         
   152     CCnvCharacterSetConverter* conv = CCnvCharacterSetConverter::NewL() ;
   153     CleanupStack::PushL(conv);
   154         
   155     CArrayFix<CCnvCharacterSetConverter::SCharacterSet> *charSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(fileSession);
   156     CleanupStack::PushL( charSet );
   157     
   158     TInt i = 0;
   159     TInt count = charSet->Count();
   160     TUint charSetUID = 0 ;
   161     while(i < count)
   162     {
   163         CCnvCharacterSetConverter::SCharacterSet characterSet = charSet->At(i); 
   164         i++;
   165         charSetUID = characterSet.Identifier();
   166        // const TBufC<25> charSetName = characterSet.NameIsFileName()?TParsePtrC(characterSet.Name()).Name():characterSet.Name();                             
   167         const TBufC<50> charSetName = characterSet.NameIsFileName()?TParsePtrC(characterSet.Name()).Name():characterSet.Name();
   168         const int CHAR_SET_NAME_SIZE = 100; //worst case size
   169         TBuf8<CHAR_SET_NAME_SIZE> aCharSetName;
   170        // if(wcstombs((char *)aCharSetName.Ptr(),(wchar_t*)(const_cast<TBufC<25>*>(&charSetName))->Des().PtrZ(),CHAR_SET_NAME_SIZE) == (size_t)-1)
   171         if(wcstombs((char *)aCharSetName.Ptr(),(wchar_t*)(const_cast<TBufC<50>*>(&charSetName))->Des().PtrZ(),CHAR_SET_NAME_SIZE) == (size_t)-1)
   172             {
   173                 CleanupStack::PopAndDestroy(3); 
   174                 return -1;
   175             }
   176         if(!aCharSetName.Compare(TPtrC8((const TText8*) LC_COLLATE_LocaleName)))
   177         {
   178             break;;
   179         }
   180         HBufC8*  stdInterName = conv->ConvertCharacterSetIdentifierToStandardNameL(charSetUID, fileSession);
   181         if(NULL != stdInterName)
   182         {
   183             if(!stdInterName->Compare(TPtrC8((const TText8*) LC_COLLATE_LocaleName)))
   184             {
   185                 delete stdInterName;
   186                 stdInterName = NULL;
   187                 break;
   188             }
   189             
   190             delete stdInterName;
   191             stdInterName = NULL;
   192         }
   193 
   194 	}
   195 	if(!charSetUID)	
   196 		{
   197 				CleanupStack::PopAndDestroy(3); 
   198 				return -1;
   199 		}
   200 
   201 	TPtrC8 remainderOfForeignText((const TText8*) s1);
   202 	TInt length = 0;
   203 	while(remainderOfForeignText.Length() > 0)
   204 	{
   205 		TBuf16<300> unicodeText;
   206 		TInt retVal = KErrNone;
   207 					
   208 		CCnvCharacterSetConverter::TAvailability  avail = conv->PrepareToConvertToOrFromL(charSetUID, fileSession);
   209 		if(CCnvCharacterSetConverter::ENotAvailable == avail)
   210 			{
   211 				CleanupStack::PopAndDestroy(3); 
   212 				return -1;
   213 			}
   214 					
   215 			TInt state = CCnvCharacterSetConverter::KStateDefault;
   216 			TInt aNumberOfUnconvertibleCharacters = 0;
   217 			TInt aIndexOfFirstByteOfFirstUnconvertibleCharacter = 0;
   218 
   219 			retVal = conv->ConvertToUnicode(unicodeText, remainderOfForeignText, state, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter);
   220 			length += unicodeText.Length();
   221 			
   222 			wcsncpy((wchar_t*)aUnicodeText, (wchar_t*) unicodeText.Ptr(), unicodeText.Length() );
   223 			
   224 			if(retVal < 0 && (retVal != CCnvCharacterSetConverter::EErrorIllFormedInput))
   225 			{
   226 				CleanupStack::PopAndDestroy(3); 
   227 				return -1;
   228 			}
   229 					
   230 			if(aNumberOfUnconvertibleCharacters)
   231 			{
   232 				
   233 				CleanupStack::PopAndDestroy(3); 
   234 				return -1;
   235 			}
   236 			
   237 			if(retVal == CCnvCharacterSetConverter::EErrorIllFormedInput)
   238 			{
   239 				
   240 				CleanupStack::PopAndDestroy(3); 
   241 				return -1;
   242 			}
   243 			
   244 			remainderOfForeignText.Set(remainderOfForeignText.Right(retVal));
   245 
   246 	}
   247 	aUnicodeText[length] = '\0';
   248 	CleanupStack::PopAndDestroy(3); 
   249 	return 0;
   250 
   251 }		
   252 
   253 
   254