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 |
|