|
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 // |
|
15 |
|
16 #include <e32base.h> |
|
17 #include <e32std.h> |
|
18 #include <e32err.h> |
|
19 #include <e32debug.h> |
|
20 #include <e32property.h> |
|
21 #include <bacntf.h> |
|
22 #include <bautils.h> |
|
23 #include "LocaleRepository.h" |
|
24 #include "InitialiseLocale.h" |
|
25 #include <hal.h> |
|
26 |
|
27 using namespace NCentralRepositoryConstants ; |
|
28 |
|
29 |
|
30 // Text constants for debug messages |
|
31 #ifdef _DEBUG |
|
32 _LIT (KBadChangeNotification, "InitialiseLocale: Bad Change Notification") ; |
|
33 #endif |
|
34 |
|
35 // |
|
36 // CExtendedLocaleManager::LocaleChanged |
|
37 // |
|
38 // Callback function to be attached to an instance of |
|
39 // CEnvironmentChangeNotifier to persist system locale data. |
|
40 // |
|
41 // Note that this has to be a static member function so that |
|
42 // it can be encapsulated into a TCallback object for use with |
|
43 // a CEnvironmentChangeNotifier - we get round this by passing |
|
44 // in a "this" pointer so that while remaining a static function |
|
45 // it can access all the member data anyway! |
|
46 TInt CExtendedLocaleManager::LocaleChanged(TAny* aPtr) |
|
47 { |
|
48 CExtendedLocaleManager* thisLocaleManager = (CExtendedLocaleManager *) aPtr ; |
|
49 |
|
50 if(!thisLocaleManager->iChangeNotifier) |
|
51 { |
|
52 #ifdef _DEBUG |
|
53 RDebug::Print(KBadChangeNotification); |
|
54 #endif |
|
55 return EFalse; |
|
56 } |
|
57 |
|
58 |
|
59 TInt stat = thisLocaleManager->iChangeNotifier->Change(); |
|
60 if(stat & EChangesLocale) |
|
61 { |
|
62 // |
|
63 // System Locale data has been updated, persist |
|
64 // changes by writing to repository. |
|
65 TRAPD(err, thisLocaleManager->PersistLocaleL()); // No way to handle errors within this callback function, so ignore them |
|
66 if(err != KErrNone) |
|
67 { |
|
68 err=KErrNone; |
|
69 } |
|
70 } |
|
71 if(stat & EChangesSystemTime) |
|
72 { |
|
73 // changes by writing to HAL |
|
74 TInt ret = BaflUtils::PersistHAL(); |
|
75 __ASSERT_DEBUG(ret == KErrNone, User::Invariant() ); |
|
76 } |
|
77 |
|
78 return ETrue; |
|
79 } |
|
80 |
|
81 |
|
82 // |
|
83 // CExtendedLocaleManager::NewLC() |
|
84 // CExtendedLocaleManager::NewL() |
|
85 // |
|
86 // Usual 2 phase construction factory NewL NewLC classes |
|
87 // |
|
88 CExtendedLocaleManager* CExtendedLocaleManager::NewLC() |
|
89 { |
|
90 CExtendedLocaleManager* me = new(ELeave)CExtendedLocaleManager(); |
|
91 CleanupStack::PushL(me) ; |
|
92 me->ConstructL() ; |
|
93 return me; |
|
94 } |
|
95 |
|
96 |
|
97 CExtendedLocaleManager* CExtendedLocaleManager::NewL() |
|
98 { |
|
99 CExtendedLocaleManager* me = CExtendedLocaleManager::NewLC() ; |
|
100 CleanupStack::Pop(me) ; |
|
101 return me; |
|
102 } |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 // |
|
108 // CExtendedLocaleManager::CExtendedLocaleManager |
|
109 // |
|
110 // Constructor - doesn't really do anything! |
|
111 // |
|
112 CExtendedLocaleManager::CExtendedLocaleManager() |
|
113 { |
|
114 } |
|
115 |
|
116 |
|
117 |
|
118 // |
|
119 // CExtendedLocaleManager::ConstructL() |
|
120 // |
|
121 // Second phase constructor, initialises locale data from persisted (or default) |
|
122 // values in repository, creates an instance of CEnvironmentChangeNotifier, and |
|
123 // attaches the callback function, passing in our "this" pointer to get round the |
|
124 // requirement for the callback function to be a static. |
|
125 // |
|
126 void CExtendedLocaleManager::ConstructL() |
|
127 { |
|
128 |
|
129 TUid LocalePropertyUid; |
|
130 LocalePropertyUid.iUid = KUidLocalePersistProperties ; |
|
131 |
|
132 TInt error = RProperty::Define((TUint)EInitialisationState, RProperty::EInt,TSecurityPolicy::EAlwaysPass,TSecurityPolicy(ECapabilityWriteDeviceData)); |
|
133 if(error != KErrAlreadyExists) |
|
134 { |
|
135 User::LeaveIfError(error); |
|
136 |
|
137 //If the property definition fails bail out. Note that if the |
|
138 // property has already been defined (because the locale initialisation code |
|
139 // has already been called) this call will return KErrAlreadyExists so locale |
|
140 // initialisation will only take place once. |
|
141 // |
|
142 // Set property to indicate initialisation in progress |
|
143 User::LeaveIfError(RProperty::Set(LocalePropertyUid, EInitialisationState, ELocaleInitialisationInProgress)) ; |
|
144 |
|
145 TUid LocaleRepositoryUid; |
|
146 LocaleRepositoryUid.iUid = KLocalePersistRepositoryUid; |
|
147 |
|
148 |
|
149 // Initialise system locale data from repository contents. |
|
150 CRepository* repository = CRepository::NewLC(LocaleRepositoryUid); |
|
151 TRAPD(err, InitialiseLocaleL(*repository)); //this function should no longer attempt to set the failure flag |
|
152 if (err != KErrNone) |
|
153 { |
|
154 // Failed to read DLL name, load corresponding Locale aspect or read value from DLL, |
|
155 // Set property to indicate initialisation failure and bail out! |
|
156 User::LeaveIfError(RProperty::Set(LocalePropertyUid, EInitialisationState, ELocaleInitialisationFailed)) ; |
|
157 } |
|
158 CleanupStack::PopAndDestroy(repository); |
|
159 |
|
160 } |
|
161 |
|
162 //After Initialisation, monitor the system locale for changes. If initialiselocale.exe is restarted, |
|
163 //then initialisation will not be executed, going to monitor directly. |
|
164 |
|
165 // |
|
166 // Create and install an CActiveScheduler to look after the active object |
|
167 // in the change notifier |
|
168 iActiveScheduler = new (ELeave) CActiveScheduler; |
|
169 CActiveScheduler::Install(iActiveScheduler); |
|
170 |
|
171 |
|
172 // Create the change notifier and install the callback function |
|
173 const TCallBack myCallBackFunction(&CExtendedLocaleManager::LocaleChanged, this); |
|
174 iChangeNotifier = CEnvironmentChangeNotifier::NewL(CActive::EPriorityStandard, myCallBackFunction); |
|
175 iChangeNotifier->Start(); |
|
176 |
|
177 // Set property to indicate initialisation complete |
|
178 User::LeaveIfError(RProperty::Set(LocalePropertyUid, EInitialisationState, ELocaleInitialisationComplete)); |
|
179 |
|
180 //now call RProcess::Rendezvous to indicate initialiseLocale is completed with no error |
|
181 RProcess().Rendezvous(KErrNone); |
|
182 |
|
183 // All ready to go! Start the active sheduler. |
|
184 CActiveScheduler::Start(); |
|
185 |
|
186 } |
|
187 |
|
188 |
|
189 // |
|
190 // CExtendedLocaleManager::~CExtendedLocaleManager() |
|
191 // |
|
192 // Destructor to tidy up on shutdown (if needed!). |
|
193 CExtendedLocaleManager::~CExtendedLocaleManager() |
|
194 { |
|
195 delete iChangeNotifier; |
|
196 delete iActiveScheduler; |
|
197 } |
|
198 |
|
199 |
|
200 |
|
201 |
|
202 |
|
203 // |
|
204 // CExtendedLocaleManager::PersistLocaleL |
|
205 // |
|
206 // Persist system locale data by writing it to a repository |
|
207 void CExtendedLocaleManager::PersistLocaleL() |
|
208 { |
|
209 TUid LocaleRepositoryUid; |
|
210 LocaleRepositoryUid.iUid = KLocalePersistRepositoryUid ; |
|
211 |
|
212 CRepository* repository = CRepository::NewLC(LocaleRepositoryUid) ; |
|
213 |
|
214 // Refresh extended locale with current system settings |
|
215 iExtendedLocale.LoadSystemSettings(); |
|
216 |
|
217 // Perform repository update in a transaction so that we're |
|
218 // guaranteed to retain consistent state of repository contents. |
|
219 User::LeaveIfError(repository->StartTransaction(CRepository::EReadWriteTransaction)); |
|
220 repository->CleanupFailTransactionPushL(); |
|
221 |
|
222 TBuf<KMaxFileName> DllName ; |
|
223 |
|
224 // |
|
225 // Locale DLL for Language Settings |
|
226 User::LeaveIfError(iExtendedLocale.GetLocaleDllName(ELocaleLanguageSettings, DllName)); |
|
227 User::LeaveIfError(repository->Set(KLocaleLanguageDll, DllName)); |
|
228 |
|
229 // |
|
230 // Locale DLL for Collation/Charset settings |
|
231 User::LeaveIfError(iExtendedLocale.GetLocaleDllName(ELocaleCollateSetting, DllName)); |
|
232 User::LeaveIfError(repository->Set(KLocaleCollationDll, DllName)); |
|
233 |
|
234 // |
|
235 // Locale DLL for Locale settings |
|
236 User::LeaveIfError(iExtendedLocale.GetLocaleDllName(ELocaleLocaleSettings, DllName)); |
|
237 User::LeaveIfError(repository->Set(KLocaleLocaleDll, DllName)); |
|
238 |
|
239 // |
|
240 #ifndef SYMBIAN_DISTINCT_LOCALE_MODEL |
|
241 // Locale DLL for Time and date settings |
|
242 User::LeaveIfError(iExtendedLocale.GetLocaleDllName(ELocaleTimeDateSettings, DllName)); |
|
243 User::LeaveIfError(repository->Set(KLocaleTimeDateDll, DllName)); |
|
244 #endif |
|
245 |
|
246 // |
|
247 // Locale customisations (contents of embedded TLocale) |
|
248 TLocale* locale = iExtendedLocale.GetLocale() ; |
|
249 User::LeaveIfError(repository->Set(KLocaleCountryCode, locale->CountryCode())); |
|
250 User::LeaveIfError(repository->Set(KLocaleUtcOffset, User::UTCOffset().Int())); |
|
251 User::LeaveIfError(repository->Set(KLocaleDateFormat, locale->DateFormat())); |
|
252 User::LeaveIfError(repository->Set(KLocaleTimeFormat, locale->TimeFormat())); |
|
253 User::LeaveIfError(repository->Set(KLocaleCurrencySymbolPosition, locale->CurrencySymbolPosition())); |
|
254 User::LeaveIfError(repository->Set(KLocaleCurrencySpaceBetween, locale->CurrencySpaceBetween())); |
|
255 User::LeaveIfError(repository->Set(KLocaleCurrencyDecimalPlaces, locale->CurrencyDecimalPlaces())); |
|
256 User::LeaveIfError(repository->Set(KLocaleCurrencyNegativeInBrackets, locale->CurrencyNegativeInBrackets())); |
|
257 User::LeaveIfError(repository->Set(KLocaleCurrencyTriadsAllowed, locale->CurrencyTriadsAllowed())); |
|
258 User::LeaveIfError(repository->Set(KLocaleThousandsSeparator, (TInt)locale->ThousandsSeparator())); |
|
259 User::LeaveIfError(repository->Set(KLocaleDecimalSeparator, (TInt)locale->DecimalSeparator())); |
|
260 |
|
261 TInt index ; |
|
262 for (index = 0; index < KMaxDateSeparators; index++) |
|
263 { |
|
264 User::LeaveIfError(repository->Set(KLocaleDateSeparatorBase+index, (TInt)locale->DateSeparator(index))); |
|
265 } |
|
266 |
|
267 for (index = 0; index < KMaxTimeSeparators; index++) |
|
268 { |
|
269 User::LeaveIfError(repository->Set(KLocaleTimeSeparatorBase +index, (TInt)locale->TimeSeparator(index))); |
|
270 } |
|
271 |
|
272 User::LeaveIfError(repository->Set(KLocaleAmPmSpaceBetween, locale->AmPmSpaceBetween())); |
|
273 User::LeaveIfError(repository->Set(KLocaleAmPmSymbolPosition, locale->AmPmSymbolPosition())); |
|
274 User::LeaveIfError(repository->Set(KLocaleWorkDays, (TInt)locale->WorkDays())); |
|
275 User::LeaveIfError(repository->Set(KLocaleStartOfWeek, locale->StartOfWeek())); |
|
276 User::LeaveIfError(repository->Set(KLocaleClockFormat, locale->ClockFormat())); |
|
277 User::LeaveIfError(repository->Set(KLocaleUnitsGeneral, locale->UnitsGeneral())); |
|
278 User::LeaveIfError(repository->Set(KLocaleUnitsDistanceShort, locale->UnitsDistanceShort())); |
|
279 User::LeaveIfError(repository->Set(KLocaleUnitsDistanceLong, locale->UnitsDistanceLong())); |
|
280 User::LeaveIfError(repository->Set(KLocaleCurrencyNegativeFormat, locale->NegativeCurrencyFormat())); |
|
281 User::LeaveIfError(repository->Set(KLocaleCurrencyNegativeLoseSpace, locale->NegativeLoseSpace())); |
|
282 User::LeaveIfError(repository->Set(KLocaleCurrencySymbolOpposite, locale->NegativeCurrencySymbolOpposite())); |
|
283 |
|
284 TCurrencySymbol currencySymbol ; |
|
285 currencySymbol.Set() ; |
|
286 User::LeaveIfError(repository->Set(KLocaleCurrencySymbol, currencySymbol)); |
|
287 |
|
288 for (index = 0; index < 3; index++) |
|
289 { |
|
290 User::LeaveIfError(repository->Set(KLocaleLanguageDowngradeBase+index, locale->LanguageDowngrade(index))); |
|
291 } |
|
292 |
|
293 User::LeaveIfError(repository->Set(KLocaleDigitType, locale->DigitType())); |
|
294 User::LeaveIfError(repository->Set(KLocaleDeviceTimeState, locale->DeviceTime())); |
|
295 |
|
296 // Completed sucessfully, commit transaction and close registry |
|
297 TUint32 transactionErr ; |
|
298 User::LeaveIfError(repository->CommitTransaction(transactionErr)); |
|
299 CleanupStack::Pop(); // pop repository->CleanupFailTransactionPushL item |
|
300 CleanupStack::PopAndDestroy (repository); |
|
301 } |
|
302 |
|
303 |
|
304 |
|
305 |
|
306 // |
|
307 // Initialise System Locale data from persisted (or default) data held in a |
|
308 //repository. |
|
309 void CExtendedLocaleManager::InitialiseLocaleL(CRepository& aRepository) |
|
310 { |
|
311 |
|
312 // Get names of DLLs to be loaded |
|
313 TBuf<KMaxFileName> DllName ; |
|
314 |
|
315 #ifndef SYMBIAN_DISTINCT_LOCALE_MODEL |
|
316 // Collation/Charset settings |
|
317 User::LeaveIfError(aRepository.Get(KLocaleCollationDll, DllName)); |
|
318 User::LeaveIfError(iExtendedLocale.LoadLocaleAspect(ELocaleCollateSetting,DllName)); |
|
319 |
|
320 // Language Settings |
|
321 User::LeaveIfError(aRepository.Get(KLocaleLanguageDll, DllName)); |
|
322 User::LeaveIfError(iExtendedLocale.LoadLocaleAspect(ELocaleLanguageSettings,DllName)); |
|
323 |
|
324 // Locale settings |
|
325 User::LeaveIfError(aRepository.Get(KLocaleLocaleDll, DllName)); |
|
326 User::LeaveIfError(iExtendedLocale.LoadLocaleAspect(ELocaleLocaleSettings,DllName)); |
|
327 |
|
328 // Time and Date settings |
|
329 User::LeaveIfError(aRepository.Get(KLocaleTimeDateDll, DllName)); |
|
330 User::LeaveIfError(iExtendedLocale.LoadLocaleAspect(ELocaleTimeDateSettings,DllName)); |
|
331 |
|
332 #else |
|
333 |
|
334 User::LeaveIfError(aRepository.Get(KLocaleCollationDll, DllName)); |
|
335 User::LeaveIfError(iExtendedLocale.LoadLocaleAspect(DllName)); |
|
336 |
|
337 User::LeaveIfError(aRepository.Get(KLocaleLanguageDll, DllName)); |
|
338 User::LeaveIfError(iExtendedLocale.LoadLocaleAspect(DllName)); |
|
339 |
|
340 User::LeaveIfError(aRepository.Get(KLocaleLocaleDll, DllName)); |
|
341 User::LeaveIfError(iExtendedLocale.LoadLocaleAspect(DllName)); |
|
342 |
|
343 #endif |
|
344 |
|
345 iExtendedLocale.SaveSystemSettings(); |
|
346 |
|
347 // Locale customisations |
|
348 TLocale* locale = iExtendedLocale.GetLocale() ; |
|
349 |
|
350 TInt intValue ; |
|
351 User::LeaveIfError(aRepository.Get(KLocaleCountryCode, intValue)); |
|
352 locale->SetCountryCode(intValue) ; |
|
353 |
|
354 User::LeaveIfError(aRepository.Get(KLocaleUtcOffset, intValue)); |
|
355 User::SetUTCOffset(intValue) ; |
|
356 |
|
357 User::LeaveIfError(aRepository.Get(KLocaleDateFormat, intValue)); |
|
358 locale->SetDateFormat((TDateFormat)intValue) ; |
|
359 |
|
360 User::LeaveIfError(aRepository.Get(KLocaleTimeFormat, intValue)); |
|
361 locale->SetTimeFormat((TTimeFormat)intValue) ; |
|
362 |
|
363 User::LeaveIfError(aRepository.Get(KLocaleCurrencySymbolPosition, intValue)); |
|
364 locale->SetCurrencySymbolPosition((TLocalePos)intValue) ; |
|
365 |
|
366 User::LeaveIfError(aRepository.Get(KLocaleCurrencySpaceBetween, intValue)); |
|
367 locale->SetCurrencySpaceBetween((TBool)intValue) ; |
|
368 |
|
369 User::LeaveIfError(aRepository.Get(KLocaleCurrencyDecimalPlaces, intValue)); |
|
370 locale->SetCurrencyDecimalPlaces((TBool)intValue) ; |
|
371 |
|
372 User::LeaveIfError(aRepository.Get(KLocaleCurrencyNegativeInBrackets, intValue)); |
|
373 locale->SetCurrencyNegativeInBrackets((TBool)intValue) ; |
|
374 |
|
375 User::LeaveIfError(aRepository.Get(KLocaleCurrencyTriadsAllowed, intValue)); |
|
376 locale->SetCurrencyTriadsAllowed((TBool)intValue) ; |
|
377 |
|
378 TCurrencySymbol currencySymbol ; |
|
379 User::LeaveIfError(aRepository.Get(KLocaleCurrencySymbol, currencySymbol)); |
|
380 iExtendedLocale.SetCurrencySymbol(currencySymbol) ; |
|
381 |
|
382 User::LeaveIfError(aRepository.Get(KLocaleThousandsSeparator, intValue)); |
|
383 locale->SetThousandsSeparator(intValue) ; |
|
384 |
|
385 User::LeaveIfError(aRepository.Get(KLocaleDecimalSeparator, intValue)); |
|
386 locale->SetDecimalSeparator(intValue) ; |
|
387 |
|
388 TInt index ; |
|
389 for (index = 0; index < KMaxDateSeparators; index++) |
|
390 { |
|
391 User::LeaveIfError(aRepository.Get(KLocaleDateSeparatorBase+index, intValue)); |
|
392 locale->SetDateSeparator(intValue, index) ; |
|
393 } |
|
394 |
|
395 for (index = 0; index < KMaxTimeSeparators; index++) |
|
396 { |
|
397 User::LeaveIfError(aRepository.Get(KLocaleTimeSeparatorBase+index, intValue)); |
|
398 locale->SetTimeSeparator(intValue, index) ; |
|
399 } |
|
400 |
|
401 User::LeaveIfError(aRepository.Get(KLocaleAmPmSpaceBetween, intValue)); |
|
402 locale->SetAmPmSpaceBetween(intValue) ; |
|
403 |
|
404 User::LeaveIfError(aRepository.Get(KLocaleAmPmSymbolPosition, intValue)); |
|
405 locale->SetAmPmSymbolPosition((TLocalePos)intValue) ; |
|
406 |
|
407 User::LeaveIfError(aRepository.Get(KLocaleWorkDays, intValue)); |
|
408 locale->SetWorkDays(intValue) ; |
|
409 |
|
410 User::LeaveIfError(aRepository.Get(KLocaleStartOfWeek, intValue)); |
|
411 locale->SetStartOfWeek((TDay)intValue) ; |
|
412 |
|
413 User::LeaveIfError(aRepository.Get(KLocaleClockFormat, intValue)); |
|
414 locale->SetClockFormat((TClockFormat)intValue) ; |
|
415 |
|
416 User::LeaveIfError(aRepository.Get(KLocaleUnitsGeneral, intValue)); |
|
417 locale->SetUnitsGeneral((TUnitsFormat)intValue) ; |
|
418 |
|
419 User::LeaveIfError(aRepository.Get(KLocaleUnitsDistanceShort, intValue)); |
|
420 locale->SetUnitsDistanceShort((TUnitsFormat)intValue) ; |
|
421 |
|
422 User::LeaveIfError(aRepository.Get(KLocaleUnitsDistanceLong, intValue)); |
|
423 locale->SetUnitsDistanceLong((TUnitsFormat)intValue) ; |
|
424 |
|
425 User::LeaveIfError(aRepository.Get(KLocaleCurrencyNegativeFormat, intValue)); |
|
426 locale->SetNegativeCurrencyFormat((TLocale::TNegativeCurrencyFormat)intValue) ; |
|
427 |
|
428 User::LeaveIfError(aRepository.Get(KLocaleCurrencyNegativeLoseSpace, intValue)); |
|
429 locale->SetNegativeLoseSpace(intValue) ; |
|
430 |
|
431 User::LeaveIfError(aRepository.Get(KLocaleCurrencySymbolOpposite, intValue)); |
|
432 locale->SetNegativeCurrencySymbolOpposite(intValue) ; |
|
433 |
|
434 for (index = 0; index < 3; index++) |
|
435 { |
|
436 User::LeaveIfError(aRepository.Get(KLocaleLanguageDowngradeBase+index, intValue)); |
|
437 locale->SetLanguageDowngrade(index, (TLanguage)intValue) ; |
|
438 } |
|
439 |
|
440 User::LeaveIfError(aRepository.Get(KLocaleDigitType, intValue)); |
|
441 locale->SetDigitType((TDigitType)intValue) ; |
|
442 |
|
443 User::LeaveIfError(aRepository.Get(KLocaleDeviceTimeState, intValue)); |
|
444 locale->SetDeviceTime((TLocale::TDeviceTimeState)intValue) ; |
|
445 |
|
446 // |
|
447 // Sucessfully loaded a complete set of persisted/default Locale data - write to |
|
448 // system locale data. |
|
449 User::LeaveIfError(iExtendedLocale.SaveSystemSettings()); |
|
450 |
|
451 } |
|
452 |
|
453 |
|
454 // Entry point for the executable |
|
455 TInt E32Main() |
|
456 { |
|
457 TInt result = KErrNone; |
|
458 CTrapCleanup* tc = CTrapCleanup::New(); |
|
459 if(!tc) |
|
460 { |
|
461 User::Panic(KLocaleInitPanic, KErrNoMemory) ; |
|
462 } |
|
463 __UHEAP_MARK; |
|
464 |
|
465 CExtendedLocaleManager* localeManager = NULL ; |
|
466 TRAPD(err, (localeManager = CExtendedLocaleManager::NewL())); |
|
467 if(err != KErrNone) |
|
468 { |
|
469 result = err; |
|
470 } |
|
471 __UHEAP_MARKEND; |
|
472 |
|
473 delete localeManager; |
|
474 delete tc; |
|
475 return result; |
|
476 } |
|
477 |