genericopenlibs/openenvcore/libc/src/strcoll.cpp
changeset 0 e4d67989cc36
child 44 97b0fb8a2cc2
equal deleted inserted replaced
-1:000000000000 0:e4d67989cc36
       
     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     RFs fileSession;
       
   144     fileSession.Connect();
       
   145     CleanupClosePushL(fileSession);
       
   146         
       
   147     CCnvCharacterSetConverter* conv = CCnvCharacterSetConverter::NewL() ;
       
   148     CleanupStack::PushL(conv);
       
   149         
       
   150     CArrayFix<CCnvCharacterSetConverter::SCharacterSet> *charSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(fileSession);
       
   151     CleanupStack::PushL( charSet );
       
   152     
       
   153     TInt i = 0;
       
   154     TInt count = charSet->Count();
       
   155     TUint charSetUID = 0 ;
       
   156     while(i < count)
       
   157     {
       
   158         CCnvCharacterSetConverter::SCharacterSet characterSet = charSet->At(i); 
       
   159         i++;
       
   160         charSetUID = characterSet.Identifier();
       
   161        // const TBufC<25> charSetName = characterSet.NameIsFileName()?TParsePtrC(characterSet.Name()).Name():characterSet.Name();                             
       
   162         const TBufC<50> charSetName = characterSet.NameIsFileName()?TParsePtrC(characterSet.Name()).Name():characterSet.Name();
       
   163         const int CHAR_SET_NAME_SIZE = 100; //worst case size
       
   164         TBuf8<CHAR_SET_NAME_SIZE> aCharSetName;
       
   165        // if(wcstombs((char *)aCharSetName.Ptr(),(wchar_t*)(const_cast<TBufC<25>*>(&charSetName))->Des().PtrZ(),CHAR_SET_NAME_SIZE) == (size_t)-1)
       
   166         if(wcstombs((char *)aCharSetName.Ptr(),(wchar_t*)(const_cast<TBufC<50>*>(&charSetName))->Des().PtrZ(),CHAR_SET_NAME_SIZE) == (size_t)-1)
       
   167             {
       
   168                 CleanupStack::PopAndDestroy(3); 
       
   169                 return -1;
       
   170             }
       
   171         if(!aCharSetName.Compare(TPtrC8((const TText8*) LC_COLLATE_LocaleName)))
       
   172         {
       
   173             break;;
       
   174         }
       
   175         HBufC8*  stdInterName = conv->ConvertCharacterSetIdentifierToStandardNameL(charSetUID, fileSession);
       
   176         if(NULL != stdInterName)
       
   177         {
       
   178             if(!stdInterName->Compare(TPtrC8((const TText8*) LC_COLLATE_LocaleName)))
       
   179             {
       
   180                 delete stdInterName;
       
   181                 stdInterName = NULL;
       
   182                 break;
       
   183             }
       
   184             
       
   185             delete stdInterName;
       
   186             stdInterName = NULL;
       
   187         }
       
   188 
       
   189 	}
       
   190 	if(!charSetUID)	
       
   191 		{
       
   192 				CleanupStack::PopAndDestroy(3); 
       
   193 				return -1;
       
   194 		}
       
   195 
       
   196 	TPtrC8 remainderOfForeignText((const TText8*) s1);
       
   197 	TInt length = 0;
       
   198 	while(remainderOfForeignText.Length() > 0)
       
   199 	{
       
   200 		TBuf16<300> unicodeText;
       
   201 		TInt retVal = KErrNone;
       
   202 					
       
   203 		CCnvCharacterSetConverter::TAvailability  avail = conv->PrepareToConvertToOrFromL(charSetUID, fileSession);
       
   204 		if(CCnvCharacterSetConverter::ENotAvailable == avail)
       
   205 			{
       
   206 				CleanupStack::PopAndDestroy(3); 
       
   207 				return -1;
       
   208 			}
       
   209 					
       
   210 			TInt state = CCnvCharacterSetConverter::KStateDefault;
       
   211 			TInt aNumberOfUnconvertibleCharacters = 0;
       
   212 			TInt aIndexOfFirstByteOfFirstUnconvertibleCharacter = 0;
       
   213 
       
   214 			retVal = conv->ConvertToUnicode(unicodeText, remainderOfForeignText, state, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter);
       
   215 			length += unicodeText.Length();
       
   216 			
       
   217 			wcsncpy((wchar_t*)aUnicodeText, (wchar_t*) unicodeText.Ptr(), unicodeText.Length() );
       
   218 			
       
   219 			if(retVal < 0 && (retVal != CCnvCharacterSetConverter::EErrorIllFormedInput))
       
   220 			{
       
   221 				CleanupStack::PopAndDestroy(3); 
       
   222 				return -1;
       
   223 			}
       
   224 					
       
   225 			if(aNumberOfUnconvertibleCharacters)
       
   226 			{
       
   227 				
       
   228 				CleanupStack::PopAndDestroy(3); 
       
   229 				return -1;
       
   230 			}
       
   231 			
       
   232 			if(retVal == CCnvCharacterSetConverter::EErrorIllFormedInput)
       
   233 			{
       
   234 				
       
   235 				CleanupStack::PopAndDestroy(3); 
       
   236 				return -1;
       
   237 			}
       
   238 			
       
   239 			remainderOfForeignText.Set(remainderOfForeignText.Right(retVal));
       
   240 
       
   241 	}
       
   242 	aUnicodeText[length] = '\0';
       
   243 	CleanupStack::PopAndDestroy(3); 
       
   244 	return 0;
       
   245 
       
   246 }		
       
   247 
       
   248 
       
   249