sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Name : strcoll.cpp sl@0: // Part of : MRT sl@0: // Implementation for wcpcpy API sl@0: // Version : 1.0 sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: #include sl@0: #include "localeinfo.h" sl@0: #endif sl@0: sl@0: #ifdef SYMBIAN_DISTINCT_LOCALE_MODEL sl@0: #include sl@0: #endif sl@0: sl@0: #if (defined(__SYMBIAN32__) && (defined(__WINSCW__) || defined(__WINS__))) sl@0: #include "libc_wsd_defs.h" sl@0: #endif sl@0: sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: #define MAX_COL_LEVEL 1 sl@0: #endif sl@0: sl@0: #ifdef __cplusplus sl@0: extern "C" { sl@0: #endif sl@0: sl@0: #ifdef __SYMBIAN32__ sl@0: extern "C" char* LC_COLLATE_LocaleName[30]; sl@0: #ifdef EMULATOR sl@0: sl@0: char *GET_WSD_VAR_NAME(LC_COLLATE_LocaleName, g)(); sl@0: #define LC_COLLATE_LocaleName (GET_WSD_VAR_NAME(LC_COLLATE_LocaleName, g)()) sl@0: #endif //EMULATOR sl@0: sl@0: #endif //__SYMBIAN32__ sl@0: sl@0: #ifdef __cplusplus sl@0: } sl@0: #endif sl@0: sl@0: static int DoConvertionToUnicode(const char* s1, TUint16* aUnicodeText); sl@0: sl@0: EXPORT_C sl@0: int strcoll(const char *s1, const char *s2) sl@0: { sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: TInt retVal; sl@0: char *ret=NULL; sl@0: #endif sl@0: if((strcmp("C",(const char*) LC_COLLATE_LocaleName)==0) ||(strcmp("POSIX", (const char*) LC_COLLATE_LocaleName)==0)) sl@0: return strcmp (s1,s2); sl@0: else sl@0: { sl@0: TUint16* text1 = new TText16[strlen(s1) + 1]; sl@0: TUint16* text2 = new TText16[strlen(s2 ) + 1]; sl@0: sl@0: if((DoConvertionToUnicode(s1, text1) == -1) || (DoConvertionToUnicode(s2, text2) == -1)) sl@0: { sl@0: delete [] text1; sl@0: delete [] text2; sl@0: return -1; sl@0: } sl@0: sl@0: const TPtrC leftString((TText*) text1); sl@0: const TPtrC rightString((TText*) text2); sl@0: sl@0: TInt left = leftString.Length(); sl@0: TInt right = rightString.Length(); sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: ret=(char*)LC_COLLATE_LocaleName; sl@0: if(*ret==NULL) sl@0: { sl@0: #endif sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: retVal = Mem :: CompareC(text1,left,text2,right, MAX_COL_LEVEL,NULL); sl@0: #else sl@0: TInt retVal = Mem :: CompareC(text1,left,text2,right, MAX_COL_LEVEL,NULL); sl@0: #endif sl@0: #ifdef SYMBIAN_OE_ENHANCED_LOCALE_SUPPORT sl@0: } sl@0: else sl@0: { sl@0: CLocale* loc = CLocale::GetInstance(); sl@0: TExtendedLocale elocale; sl@0: const TText* text; sl@0: sl@0: #ifdef SYMBIAN_DISTINCT_LOCALE_MODEL sl@0: text = loc->GetCollateLocaleName(); sl@0: TPtrC localenew(text); sl@0: retVal = elocale.LoadLocaleAspect(localenew); sl@0: if ( retVal == KErrNotFound ) // load old collate dll sl@0: { sl@0: text = loc->GetLocaleName(); sl@0: TPtrC locale(text); sl@0: retVal = elocale.LoadLocaleAspect(ELocaleCollateSetting,locale); sl@0: } sl@0: #else sl@0: text = loc->GetLocaleName(); sl@0: TPtrC locale(text); sl@0: retVal = elocale.LoadLocaleAspect(ELocaleCollateSetting,locale); sl@0: #endif sl@0: if( retVal == KErrNone ) sl@0: { sl@0: TCollationMethod chmethod=elocale.GetPreferredCollationMethod(0); sl@0: retVal = Mem :: CompareC(text1,left,text2,right, MAX_COL_LEVEL,&chmethod); sl@0: } sl@0: } sl@0: #endif sl@0: delete [] text1; sl@0: delete [] text2; sl@0: return retVal; sl@0: } sl@0: sl@0: } sl@0: sl@0: static int DoConvertionToUnicode( const char* s1, TUint16* aUnicodeText) sl@0: { sl@0: sl@0: TInt r = KErrNone; sl@0: RFs fileSession; sl@0: r = fileSession.Connect(); sl@0: if (r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: CleanupClosePushL(fileSession); sl@0: sl@0: CCnvCharacterSetConverter* conv = CCnvCharacterSetConverter::NewL() ; sl@0: CleanupStack::PushL(conv); sl@0: sl@0: CArrayFix *charSet = CCnvCharacterSetConverter::CreateArrayOfCharacterSetsAvailableL(fileSession); sl@0: CleanupStack::PushL( charSet ); sl@0: sl@0: TInt i = 0; sl@0: TInt count = charSet->Count(); sl@0: TUint charSetUID = 0 ; sl@0: while(i < count) sl@0: { sl@0: CCnvCharacterSetConverter::SCharacterSet characterSet = charSet->At(i); sl@0: i++; sl@0: charSetUID = characterSet.Identifier(); sl@0: // const TBufC<25> charSetName = characterSet.NameIsFileName()?TParsePtrC(characterSet.Name()).Name():characterSet.Name(); sl@0: const TBufC<50> charSetName = characterSet.NameIsFileName()?TParsePtrC(characterSet.Name()).Name():characterSet.Name(); sl@0: const int CHAR_SET_NAME_SIZE = 100; //worst case size sl@0: TBuf8 aCharSetName; sl@0: // if(wcstombs((char *)aCharSetName.Ptr(),(wchar_t*)(const_cast*>(&charSetName))->Des().PtrZ(),CHAR_SET_NAME_SIZE) == (size_t)-1) sl@0: if(wcstombs((char *)aCharSetName.Ptr(),(wchar_t*)(const_cast*>(&charSetName))->Des().PtrZ(),CHAR_SET_NAME_SIZE) == (size_t)-1) sl@0: { sl@0: CleanupStack::PopAndDestroy(3); sl@0: return -1; sl@0: } sl@0: if(!aCharSetName.Compare(TPtrC8((const TText8*) LC_COLLATE_LocaleName))) sl@0: { sl@0: break;; sl@0: } sl@0: HBufC8* stdInterName = conv->ConvertCharacterSetIdentifierToStandardNameL(charSetUID, fileSession); sl@0: if(NULL != stdInterName) sl@0: { sl@0: if(!stdInterName->Compare(TPtrC8((const TText8*) LC_COLLATE_LocaleName))) sl@0: { sl@0: delete stdInterName; sl@0: stdInterName = NULL; sl@0: break; sl@0: } sl@0: sl@0: delete stdInterName; sl@0: stdInterName = NULL; sl@0: } sl@0: sl@0: } sl@0: if(!charSetUID) sl@0: { sl@0: CleanupStack::PopAndDestroy(3); sl@0: return -1; sl@0: } sl@0: sl@0: TPtrC8 remainderOfForeignText((const TText8*) s1); sl@0: TInt length = 0; sl@0: while(remainderOfForeignText.Length() > 0) sl@0: { sl@0: TBuf16<300> unicodeText; sl@0: TInt retVal = KErrNone; sl@0: sl@0: CCnvCharacterSetConverter::TAvailability avail = conv->PrepareToConvertToOrFromL(charSetUID, fileSession); sl@0: if(CCnvCharacterSetConverter::ENotAvailable == avail) sl@0: { sl@0: CleanupStack::PopAndDestroy(3); sl@0: return -1; sl@0: } sl@0: sl@0: TInt state = CCnvCharacterSetConverter::KStateDefault; sl@0: TInt aNumberOfUnconvertibleCharacters = 0; sl@0: TInt aIndexOfFirstByteOfFirstUnconvertibleCharacter = 0; sl@0: sl@0: retVal = conv->ConvertToUnicode(unicodeText, remainderOfForeignText, state, aNumberOfUnconvertibleCharacters, aIndexOfFirstByteOfFirstUnconvertibleCharacter); sl@0: length += unicodeText.Length(); sl@0: sl@0: wcsncpy((wchar_t*)aUnicodeText, (wchar_t*) unicodeText.Ptr(), unicodeText.Length() ); sl@0: sl@0: if(retVal < 0 && (retVal != CCnvCharacterSetConverter::EErrorIllFormedInput)) sl@0: { sl@0: CleanupStack::PopAndDestroy(3); sl@0: return -1; sl@0: } sl@0: sl@0: if(aNumberOfUnconvertibleCharacters) sl@0: { sl@0: sl@0: CleanupStack::PopAndDestroy(3); sl@0: return -1; sl@0: } sl@0: sl@0: if(retVal == CCnvCharacterSetConverter::EErrorIllFormedInput) sl@0: { sl@0: sl@0: CleanupStack::PopAndDestroy(3); sl@0: return -1; sl@0: } sl@0: sl@0: remainderOfForeignText.Set(remainderOfForeignText.Right(retVal)); sl@0: sl@0: } sl@0: aUnicodeText[length] = '\0'; sl@0: CleanupStack::PopAndDestroy(3); sl@0: return 0; sl@0: sl@0: } sl@0: sl@0: sl@0: