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