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