--- a/layers.sysdef.xml Thu Aug 26 11:46:18 2010 +0800
+++ b/layers.sysdef.xml Tue Sep 07 16:39:34 2010 +0800
@@ -140,6 +140,9 @@
<module name="syslibs_fatcharsetconv">
<unit name="fatcharsetconv" unitID="tls.fatcharsetconv" bldFile="sf\os\textandloc\charconvfw\fatfilenameconversionplugins\group" mrp="sf\os\textandloc\charconvfw\fatfilenameconversionplugins\group\syslibs_fatcharsetconv.mrp"/>
</module>
+ <module name="nearestlangutils">
+ <unit name="nearestlangutils" unitID="tls.nearestlangutils" bldFile="sf\os\textandloc\textandlocutils\nearestlangutils\group" mrp="sf\os\textandloc\textandlocutils\nearestlangutils\group\langutils.mrp"/>
+ </module>
</layer>
<layer name="api_test_layer">
<!--module name="test.app-framework_etext">
--- a/package_definition.xml Thu Aug 26 11:46:18 2010 +0800
+++ b/package_definition.xml Tue Sep 07 16:39:34 2010 +0800
@@ -26,13 +26,10 @@
<unit bldFile="fontservices/textshaperplugin/group" mrp="fontservices/textshaperplugin/group/graphics_iculayoutengine.mrp"/>
</component>
<component id="fontstore" name="Font Store" purpose="mandatory" filter="api_test"> <!-- both production and api_test-->
- <meta rel="testbuild">
- <group name="test.graphics_fntstore"/>
- </meta>
- <unit bldFile="fontservices/fontstore/group" mrp="fontservices/fontstore/group/graphics_fntstore.mrp"/>
+` <unit bldFile="fontservices/fontstore/group" mrp="fontservices/fontstore/group/graphics_fntstore.mrp"/>
</component>
<component id="textbase" name="Text Base" purpose="mandatory">
- <!-- placeholder for text code from GDI -->
+ <unit bldFile="fontservices/textbase/group" mrp="fontservices/textbase/group/textbase.mrp" />
</component>
<component id="freetypefontrasteriser" name="FreeType Font Rasteriser" purpose="optional" class="plugin">
<unit bldFile="fontservices/freetypefontrasteriser/group" mrp="fontservices/freetypefontrasteriser/group/graphics_freetype.mrp"/>
@@ -68,6 +65,9 @@
<component id="numberformatting" name="Number Formatting" introduced="7.0s" purpose="optional">
<unit bldFile="textrendering/numberformatting/group" mrp="textrendering/numberformatting/group/app-framework_numberconversion.mrp"/>
</component>
+ <component id="nearestlangutils" name="Nearest Language Utils">
+ <unit bldFile="textandlocutils/nearestlangutils/group" mrp="textandlocutils/nearestlangutils/group/langutils.mrp"/>
+ </component>
</collection>
<collection id="localesupport" name="Locale Support" level="util">
<component id="reflocales" name="Reference Locales" purpose="optional" class="plugin">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/bwins/langutilu.def Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,10 @@
+EXPORTS
+ ?IdealLanguage@LangUtil@@SA?AW4TLanguage@@XZ @ 1 NONAME ; enum TLanguage LangUtil::IdealLanguage(void)
+ ?NearestLanguageFile@LangUtil@@SAXABVRFs@@AAV?$TBuf@$0BAA@@@AAW4TLanguage@@@Z @ 2 NONAME ; void LangUtil::NearestLanguageFile(class RFs const &, class TBuf<256> &, enum TLanguage &)
+ ?ReleaseIdealLanguage@LangUtil@@SAXXZ @ 3 NONAME ; void LangUtil::ReleaseIdealLanguage(void)
+ ?GetEquivalentLanguageList@LangUtil@@SAXW4TLanguage@@AAY0BB@W42@@Z @ 4 NONAME ; void LangUtil::GetEquivalentLanguageList(enum TLanguage, enum TLanguage [17] &)
+ ?NearestLanguageFile@LangUtil@@SAXABVRFs@@AAV?$TBuf@$0BAA@@@@Z @ 5 NONAME ; void LangUtil::NearestLanguageFile(class RFs const &, class TBuf<256> &)
+ ?NearestLanguageFileV2@LangUtil@@SAXABVRFs@@AAV?$TBuf@$0BAA@@@AAW4TLanguage@@@Z @ 6 NONAME ; void LangUtil::NearestLanguageFileV2(class RFs const &, class TBuf<256> &, enum TLanguage &)
+ ?SetIdealLanguage@LangUtil@@SAHW4TLanguage@@@Z @ 7 NONAME ; int LangUtil::SetIdealLanguage(enum TLanguage)
+ ?GetDowngradePathL@LangUtil@@SAXABVRFs@@W4TLanguage@@AAV?$RArray@W4TLanguage@@@@@Z @ 8 NONAME ; void LangUtil::GetDowngradePathL(class RFs const &, enum TLanguage, class RArray<enum TLanguage> &)
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/T_LangUtilsServer.pkg Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,29 @@
+;
+; Copyright (c) 2010 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:
+;
+
+;Languages
+&EN
+
+;Localised Vendor name
+%{"t_PTPipsuite EN"}
+
+; Vendor name
+: "t_PTPipsuite"
+
+; test scripts
+"\epoc32\data\z\test\T_langutils.script"-"c:\sys\bin\T_langutils.script"
+"\epoc32\data\z\test\T_langutilsimp.script"-"c:\sys\bin\T_langutilsimp.script"
+"\epoc32\data\z\test\T_langutilslang.script"-"c:\sys\bin\T_langutilslang.script"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/bld.inf Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,66 @@
+// Copyright (c) 1997-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:
+//
+// LangUtils
+//
+//
+
+/**
+ @file
+*/
+
+
+PRJ_PLATFORMS
+
+DEFAULT
+
+
+PRJ_EXPORTS
+
+../inc/LangUtil.h SYMBIAN_OS_LAYER_PLATFORM_EXPORT_PATH(bafl/langutil.h)
+
+../group/langutils.iby /epoc32/rom/include/langutils.iby
+
+PRJ_MMPFILES
+
+../group/langutil.MMP
+
+PRJ_TESTEXPORTS
+../group/langutilTests.bat /epoc32/data/z/system/test/langutilTests.bat
+../group/langutilTests.iby /epoc32/rom/include/langutilTests.iby
+
+ ../tsrc/T_All_langutils.bat z:/test/T_All_langutils.bat
+ ../tsrc/T_All_langutils.script z:/test/T_All_langutils.script
+ ../tsrc/T_langutils.script z:/test/T_langutils.script
+ ../tsrc/T_langutilsimp.script z:/test/T_langutilsimp.script
+ ../tsrc/T_langutilslang.script z:/test/T_langutilslang.script
+
+../tsrc/file1.txt /epoc32/data/z/system/data/file1.txt
+../tsrc/file1.txt /epoc32/data/z/file1.txt
+../tsrc/file1.txt /epoc32/data/z/system/data/src/file1.txt
+../tsrc/file2.txt /epoc32/data/z/system/data/dst/file2.txt
+../tsrc/file123456789.txt /epoc32/data/z/system/data/file123456789.txt
+../tsrc/file2.txt /epoc32/data/z/system/data/file2.txt
+../tsrc/file5.txt /epoc32/data/z/system/data/file5.txt
+
+../tsrc/file1.txt /epoc32/release/wins/udeb/z/file1.txt
+../tsrc/file1.txt /epoc32/release/wins/urel/z/file1.txt
+../tsrc/file1.txt /epoc32/release/winscw/udeb/z/file1.txt
+../tsrc/file1.txt /epoc32/release/winscw/urel/z/file1.txt
+
+PRJ_TESTMMPFILES
+../tsrc/T_LangUtilsServer.mmp
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutil.MMP Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,50 @@
+// Copyright (c) 1997-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:
+//
+// Lang utility functions collection
+//
+//
+
+/**
+ @file
+*/
+
+
+TARGET langutil.lib
+CAPABILITY All -Tcb
+TARGETTYPE LIB
+UID 0x1000008D
+VENDORID 0x70000001
+
+
+USERINCLUDE ../inc
+USERINCLUDE ../src
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+START WINS
+BASEADDRESS 0x41900000
+END
+UNPAGED
+
+
+
+SOURCEPATH ../src
+SOURCE LangUtil.cpp
+
+
+
+
+SMPSAFE
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutilTests.bat Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,19 @@
+@rem
+@rem Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+@rem All rights reserved.
+@rem This component and the accompanying materials are made available
+@rem under the terms of "Eclipse Public License v1.0"
+@rem which accompanies this distribution, and is available
+@rem at the URL "http://www.eclipse.org/legal/epl-v10.html".
+@rem
+@rem Initial Contributors:
+@rem Nokia Corporation - initial contribution.
+@rem
+@rem Contributors:
+@rem
+@rem Description:
+@rem
+
+T_LangUtils.EXE
+T_LangUtilsImp.EXE
+T_LangUtilsLang.EXE
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutilTests.iby Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,34 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+#ifndef __LANGUTILS_TESTS_IBY__
+#define __LANGUTILS_TESTS_IBY__
+
+REM BaflTests
+#include <testbed.iby>
+
+file=ABI_DIR\BUILD_DIR\t_langutilsserver.exe sys\bin\t_langutilsserver.exe
+
+data=ZSYSTEM\Data\file1.txt \system\data\file1.txt
+data=ZSYSTEM\Data\file1.txt \file1.txt
+data=ZSYSTEM\Data\file1.txt \system\data\src\file1.txt
+data=ZSYSTEM\Data\file2.txt \system\data\dst\file2.txt
+data=ZSYSTEM\Data\file123456789.txt \system\data\file123456789.txt
+data=ZSYSTEM\Data\file2.txt \system\data\file2.txt
+data=ZSYSTEM\Data\file5.txt \system\data\file5.txt
+
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutils.iby Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,22 @@
+/*
+* Copyright (c) 1997-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:
+*
+*/
+#ifndef __LANGUTILS_IBY__
+#define __LANGUTILS_IBY__
+
+file=ABI_DIR\BUILD_DIR\langutil.lib System\Libs\langutil.lib
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/group/langutils.mrp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,10 @@
+component nearestlangutils
+source \sf\os\textandloc\textandlocalisationutils\nearestlangutils
+binary \sf\os\textandloc\textandlocalisationutils\nearestlangutils\group all
+exports \sf\os\textandloc\textandlocalisationutils\nearestlangutils\group
+
+notes_source \component_defs\release.src
+
+
+ipr D
+ipr T \sf\os\textandloc\textandlocalisationutils\nearestlangutils\tsrc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/inc/LangUtil.h Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,38 @@
+// Copyright (c) 1997-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:
+//
+
+
+#ifndef __LANGUTIL_H__
+#define __LANGUTIL_H__
+
+#include <e32std.h>
+#include <bautils.h>
+
+
+
+class LangUtil
+{
+public:
+ static void GetDowngradePathL(const RFs& aFs, const TLanguage aCurrentLanguage, RArray<TLanguage>& aLanguageArray );
+ static void GetEquivalentLanguageList(TLanguage aLang, TLanguagePath& aEquivalents);
+ static TLanguage IdealLanguage();
+ static void NearestLanguageFile(const RFs& aFs, TFileName& aName);
+ static void NearestLanguageFile(const RFs& aFs, TFileName& aName, TLanguage& aLanguage);
+ static void NearestLanguageFileV2(const RFs& aFs, TFileName& aName, TLanguage& aLanguage);
+ static void ReleaseIdealLanguage();
+ static TInt SetIdealLanguage(TLanguage aLanguage);
+
+};
+#endif // end of __LANGUTIL_H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/src/LangUtil.cpp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,908 @@
+// Copyright (c) 1997-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:
+//
+
+#include <bafl/langutil.h>
+#include <hal.h>
+#include <hal_data.h>
+#include "LangUtilImpl.h"
+
+
+/**
+Mimimum length of a filename and mimimum length of a suffix.
+Note these two values are tied together.
+*/
+const TInt KInvNameAndMinSuffixLength = 2;
+
+#define ISDIGIT(c) (c-'0' >= 0 && c-'0' <= 9)
+
+_LIT(KAllDrives, "YXWVUTSRQPONMLKJIHGFEDCBAZ");
+
+LOCAL_C const TLanguage dp0[] = { ELangCanadianEnglish, ELangAmerican,ELangEnglish, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangAustralian,ELangNewZealand,ELangInternationalEnglish,ELangSouthAfricanEnglish,ELangNone };
+LOCAL_C const TLanguage dp1[] = { ELangAmerican, ELangEnglish,ELangCanadianEnglish, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangAustralian,ELangNewZealand,ELangInternationalEnglish,ELangSouthAfricanEnglish, ELangNone };
+LOCAL_C const TLanguage dp2[] = { ELangAustralian, ELangEnglish, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangInternationalEnglish,ELangSouthAfricanEnglish, ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp3[] = { ELangSouthAfricanEnglish, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangInternationalEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp4[] = { ELangInternationalEnglish, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp5[] = { ELangEnglish_Apac, ELangEnglish, ELangAustralian, ELangAmerican,ELangInternationalEnglish,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp6[] = { ELangEnglish_Taiwan, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangInternationalEnglish,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp7[] = { ELangEnglish_HongKong, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangInternationalEnglish,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp8[] = { ELangEnglish_Prc, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangInternationalEnglish,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp9[] = { ELangEnglish_Japan, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangInternationalEnglish,ELangEnglish_Thailand,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp10[] = { ELangEnglish_Thailand, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangInternationalEnglish,ELangEnglish_India,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp11[] = { ELangEnglish_India, ELangEnglish, ELangAustralian, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangInternationalEnglish,ELangNewZealand,ELangSouthAfricanEnglish,ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp12[] = { ELangNewZealand, ELangEnglish, ELangAmerican, ELangEnglish_Apac,ELangEnglish_Taiwan,ELangEnglish_HongKong,ELangEnglish_Prc,ELangEnglish_Japan,ELangEnglish_Thailand,ELangEnglish_India,ELangAustralian,ELangInternationalEnglish,ELangSouthAfricanEnglish, ELangCanadianEnglish,ELangNone };
+LOCAL_C const TLanguage dp13[] = { ELangInternationalFrench,ELangFrench,ELangSwissFrench,ELangBelgianFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp14[] = { ELangBelgianFrench, ELangFrench,ELangInternationalFrench,ELangSwissFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp15[] = { ELangCanadianFrench, ELangFrench,ELangInternationalFrench,ELangSwissFrench,ELangBelgianFrench,ELangNone };
+LOCAL_C const TLanguage dp16[] = { ELangFrench,ELangInternationalFrench,ELangSwissFrench,ELangBelgianFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp17[] = { ELangSwissFrench,ELangFrench,ELangInternationalFrench,ELangBelgianFrench,ELangCanadianFrench,ELangNone };
+LOCAL_C const TLanguage dp18[] = { ELangSwissGerman,ELangGerman,ELangAustrian,ELangNone };
+LOCAL_C const TLanguage dp19[] = { ELangAustrian,ELangGerman,ELangSwissGerman,ELangNone };
+LOCAL_C const TLanguage dp20[] = { ELangGerman,ELangSwissGerman,ELangAustrian,ELangNone };
+LOCAL_C const TLanguage dp21[] = { ELangSerbian,ELangCroatian,ELangNone };
+LOCAL_C const TLanguage dp22[] = { ELangCroatian,ELangSerbian,ELangNone };
+LOCAL_C const TLanguage dp23[] = { ELangRomanian,ELangMoldavian,ELangNone };
+LOCAL_C const TLanguage dp24[] = { ELangMoldavian,ELangRomanian,ELangNone };
+LOCAL_C const TLanguage dp25[] = { ELangBelgianFlemish,ELangDutch,ELangNone };
+LOCAL_C const TLanguage dp26[] = { ELangDutch,ELangBelgianFlemish,ELangNone };
+LOCAL_C const TLanguage dp27[] = { ELangAfrikaans,ELangDutch,ELangNone };
+LOCAL_C const TLanguage dp28[] = { ELangMalay_Apac,ELangMalay,ELangNone };
+LOCAL_C const TLanguage dp29[] = { ELangIndonesian_Apac,ELangIndonesian,ELangNone };
+LOCAL_C const TLanguage dp30[] = { ELangSpanish,ELangInternationalSpanish,ELangLatinAmericanSpanish,ELangNone };
+LOCAL_C const TLanguage dp31[] = { ELangLatinAmericanSpanish,ELangSpanish,ELangInternationalSpanish,ELangNone };
+LOCAL_C const TLanguage dp32[] = { ELangInternationalSpanish,ELangSpanish,ELangLatinAmericanSpanish,ELangNone };
+LOCAL_C const TLanguage dp33[] = { ELangCyprusGreek,ELangGreek,ELangNone };
+LOCAL_C const TLanguage dp34[] = { ELangGreek,ELangCyprusGreek,ELangNone };
+LOCAL_C const TLanguage dp35[] = { ELangSwissItalian,ELangItalian,ELangNone };
+LOCAL_C const TLanguage dp36[] = { ELangItalian,ELangSwissItalian,ELangNone };
+LOCAL_C const TLanguage dp37[] = { ELangBrazilianPortuguese,ELangPortuguese,ELangNone };
+LOCAL_C const TLanguage dp38[] = { ELangPortuguese,ELangBrazilianPortuguese,ELangNone };
+LOCAL_C const TLanguage dp39[] = { ELangFinlandSwedish,ELangSwedish,ELangNone };
+LOCAL_C const TLanguage dp40[] = { ELangSwedish,ELangFinlandSwedish,ELangNone };
+LOCAL_C const TLanguage dp41[] = { ELangCyprusTurkish,ELangTurkish,ELangNone };
+LOCAL_C const TLanguage dp42[] = { ELangTurkish,ELangCyprusTurkish,ELangNone };
+LOCAL_C const TLanguage dp43[] = { ELangHongKongChinese, ELangTaiwanChinese, ELangPrcChinese,ELangNone };
+LOCAL_C const TLanguage dp44[] = { ELangTaiwanChinese, ELangHongKongChinese,ELangPrcChinese,ELangNone };
+LOCAL_C const TLanguage dp45[] = { ELangPrcChinese, ELangHongKongChinese, ELangTaiwanChinese,ELangNone };
+LOCAL_C const TLanguage * const KEquivalentLists[] = { dp0, dp1, dp2, dp3, dp4, dp5, dp6,
+ dp7, dp8, dp9, dp10, dp11, dp12, dp13, dp14, dp15, dp16, dp17,
+ dp18, dp19, dp20, dp21, dp22, dp23, dp24, dp25, dp26, dp27,
+ dp28, dp29, dp30, dp31, dp32, dp33, dp34, dp35, dp36, dp37,
+ dp38, dp39, dp40, dp41, dp42, dp43, dp44, dp45};
+
+
+
+LOCAL_C TBool IsLanguageExtended(const TLanguage aLanguage)
+ {
+ // For compatibility reasons, ELangNone is 0xFFFF. However, it's not an extended language.
+ if ((aLanguage==ELangNone) || ((static_cast<TUint>(aLanguage))<=KDialectMask))
+ return EFalse;
+ else
+ return ETrue;
+ }
+
+
+LOCAL_C TLanguage BaseLanguage(const TLanguage aLanguage)
+ {
+ if (IsLanguageExtended(aLanguage))
+ return static_cast<TLanguage>(aLanguage & KDialectMask);
+ else
+ return aLanguage;
+ }
+
+LOCAL_C TLanguage NextLanguage(TLanguage aLanguage)
+/** Returns the next best language to use after aLanguage,
+based on Symbian's base table of language near-equivalence.
+@internalAll */
+ {
+ switch (aLanguage)
+ {
+ case ELangAustralian:
+ case ELangNewZealand:
+ case ELangSouthAfricanEnglish:
+ case ELangInternationalEnglish:
+ case ELangAmerican:
+ case ELangEnglish_Apac:
+ case ELangEnglish_Taiwan:
+ case ELangEnglish_HongKong:
+ case ELangEnglish_Prc:
+ case ELangEnglish_Japan:
+ case ELangEnglish_Thailand:
+ return ELangEnglish;
+ case ELangCanadianEnglish:
+ return ELangAmerican; // 2-stage downgrade
+ case ELangSwissFrench:
+ case ELangBelgianFrench:
+ case ELangInternationalFrench:
+ case ELangCanadianFrench:
+ return ELangFrench;
+ case ELangSwissGerman:
+ case ELangAustrian:
+ return ELangGerman;
+ case ELangInternationalSpanish:
+ case ELangLatinAmericanSpanish:
+ return ELangSpanish;
+ case ELangSwissItalian:
+ return ELangItalian;
+ case ELangFinlandSwedish:
+ return ELangSwedish;
+ case ELangCyprusTurkish:
+ return ELangTurkish;
+ case ELangBelgianFlemish:
+ return ELangDutch;
+ case ELangHongKongChinese:
+ return ELangTaiwanChinese;
+ case ELangCyprusGreek:
+ return ELangGreek;
+ case ELangMalay_Apac:
+ return ELangMalay;
+ case ELangBrazilianPortuguese:
+ return ELangPortuguese;
+ default:
+ return ELangNone;
+ }
+ }
+
+
+void AddLanguage(TLanguagePath& aPath, TLanguage aNewLanguage)
+/** Add language to the language path if there is space.
+The first empty slot must have "ELangNone" in it. This will also be true
+on exit. */
+ {
+ TLanguage *p = aPath;
+ const TLanguage *end = &(aPath[KMaxDowngradeLanguages]);
+ while (p != end)
+ {
+ if (*p == aNewLanguage)
+ // language already in list
+ break;
+ if (*p == ELangNone)
+ {
+ // found the end of the list
+ p[0] = aNewLanguage;
+ p[1] = ELangNone;
+ break;
+ }
+ ++p;
+ }
+ return;
+ }
+
+void MakeLanguageDowngradePath(TLanguagePath& aPath,
+ TLanguage aCurrent, TLanguage aIdeal, const TLocale& aLocale)
+ {
+ TInt j = 0;
+ if( aIdeal != ELangNone)
+ {
+ aPath[j++]=aIdeal;
+ }
+ aPath[j++] = aCurrent;
+ aPath[j++] = ELangNone;
+
+ if (aCurrent & ~KDialectMask)
+ AddLanguage(aPath, static_cast<TLanguage>(aCurrent & KDialectMask));
+
+ for (TInt i=0;i<=2;i++)
+ {
+ AddLanguage(aPath, aLocale.LanguageDowngrade(i));
+ AddLanguage(aPath, BaseLanguage(aLocale.LanguageDowngrade(i)));
+ }
+
+ while (ELangNone != (aCurrent = NextLanguage(BaseLanguage(aCurrent))))
+ AddLanguage(aPath, aCurrent);
+ }
+
+
+
+//EXPORT_C
+void LangUtil::GetDowngradePathL(const RFs& aFs, const TLanguage aCurrentLanguage, RArray<TLanguage>& aLanguageArray){
+
+ TLocale currentLocale;
+ TNearestLanguageFileFinder languageDowngradePath(aFs);
+ TLanguage idealLanguage=IdealLanguage();
+ MakeLanguageDowngradePath(languageDowngradePath.iPath,aCurrentLanguage,idealLanguage, currentLocale);
+ aLanguageArray.Reset();
+ const TLanguage* p=languageDowngradePath.iPath;
+ while (*p != ELangNone)
+ {
+ User::LeaveIfError(aLanguageArray.Append(*p));
+ ++p;
+ }
+
+}
+
+
+//EXPORT_C
+void LangUtil::GetEquivalentLanguageList(TLanguage aLang, TLanguagePath& aEquivalents){
+
+ aEquivalents[0] = aLang;
+ aEquivalents[1] = ELangNone;
+ const TInt len = sizeof(KEquivalentLists) / sizeof(KEquivalentLists[0]);
+ for (TInt i = 0; i < len; ++i)
+ {
+ const TLanguage *ptr = KEquivalentLists[i];
+ if (ptr[0] == aLang)
+ {
+ TInt index = 1;
+ while (ELangNone != *ptr)
+ {
+ aEquivalents[index++] = (TLanguage)*(++ptr);
+ }
+ aEquivalents[index] = ELangNone;
+ break;
+ } // end if ptr[0]
+ } // end for i
+
+}
+
+
+
+//EXPORT_C
+TLanguage LangUtil::IdealLanguage(){
+
+ TLanguage* langPtr=(TLanguage*)Dll::Tls();
+
+ if( langPtr==NULL)
+ {
+ return(ELangNone);
+ }
+
+ return(*langPtr);
+
+}
+
+
+//EXPORT_C
+void LangUtil::NearestLanguageFile(const RFs& aFs, TFileName& aName){
+
+ TLanguage language;
+
+ NearestLanguageFile( aFs, aName, language);
+
+ (void)language;
+
+}
+
+
+//EXPORT_C
+void LangUtil::NearestLanguageFile(const RFs& aFs, TFileName& aName, TLanguage& aLanguage){
+#if defined(DO_PROFILING)
+ RDebug::ProfileReset(FIRST_PROFILE_INDEX, PROFILE_COUNT);
+ RDebug::ProfileStart(PROFILE_INDEX_1);
+#endif
+ TNearestLanguageFileFinder finder(aFs);
+ TBool goodSuffix=finder.SetFileName(aName);
+
+ // Only continue if the suffix is good.
+ if(goodSuffix)
+ {
+ // add preset customised resource drive to drive list
+ // Note that errors returned from AddCustomResourceDrive are ignored. This is because if
+ // a custom resource drive has not been found we still want to continue on with searching
+ // other drives according to our algorithm
+ finder.AddCustomResourceDrive();
+
+ TLocale locale;
+ TLanguage idealLanguage;
+ idealLanguage = IdealLanguage();
+ MakeLanguageDowngradePath(finder.iPath, User::Language(), idealLanguage, locale);
+ if (!finder.FindLanguageAndDrive()
+ && KErrNone != finder.FindFirstLanguageFileAndDrive())
+ finder.RepairFileName();
+ aLanguage = finder.Language();
+ }
+
+#if defined(DO_PROFILING)
+ RDebug::ProfileEnd(PROFILE_INDEX_1);
+ TProfile profile[PROFILE_COUNT];
+ RDebug::ProfileResult(&profile[0], FIRST_PROFILE_INDEX, PROFILE_COUNT);
+ if(goodSuffix)
+ {
+ RDebug::Print(_L("BaflUtils::NearestLanguageFile profile info: %d.%03ds"), profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime/1000000, profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime%1000000);
+ }
+ else
+ {
+ RDebug::Print(_L("BaflUtils::NearestLanguageFile (bad suffix ) profile info: %d.%03ds"), profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime/1000000, profile[PROFILE_INDEX_1-FIRST_PROFILE_INDEX].iTime%1000000);
+ }
+#endif
+
+}
+
+
+//EXPORT_C
+void LangUtil::NearestLanguageFileV2(const RFs& aFs, TFileName& aName, TLanguage& aLanguage){
+
+ TNearestLanguageFileFinder finder(aFs);
+ TBool goodSuffix=finder.SetFileName(aName);
+
+ // Continue only if the suffix is good.
+ if(goodSuffix)
+ {
+ // add preset customised resource drive to drive list
+ // Note that errors returned from AddCustomResourceDrive are ignored. This is because if
+ // a custom resource drive has not been found we still want to continue on with searching
+ // other drives according to our algorithm
+ finder.AddCustomResourceDrive();
+
+ GetEquivalentLanguageList(User::Language(), finder.iPath);
+ if (!finder.FindLanguageAndDrive()
+ && KErrNone != finder.FindFirstLanguageFileAndDrive())
+ finder.RepairFileName();
+ aLanguage = finder.Language();
+ }
+ else
+ {
+ aLanguage = ELangNone;
+ }
+
+}
+
+
+//EXPORT_C
+void LangUtil::ReleaseIdealLanguage(){
+
+ TLanguage* aLanguage=(TLanguage*)Dll::Tls();
+ if( aLanguage==NULL)
+ return;
+
+ delete aLanguage;
+ Dll::FreeTls();
+
+}
+
+
+//EXPORT_C
+TInt LangUtil::SetIdealLanguage(TLanguage aLanguage){
+TLanguage* langPtr=(TLanguage*)Dll::Tls();
+ if( langPtr==NULL)
+ {
+ langPtr=(TLanguage*)User::Alloc(sizeof(TLanguage));
+
+ if(!langPtr)
+ return(KErrNoMemory);
+
+ TInt ret=Dll::SetTls(langPtr);
+
+ if(ret!=KErrNone)
+ return(ret);
+ }
+ *langPtr=aLanguage;
+ return(KErrNone);
+
+}
+
+TInt RRealDirectoryScanner::Open(RFs& aFs, const TDesC& aMatchPattern)
+ {
+ return iDir.Open(aFs, aMatchPattern,
+ KEntryAttReadOnly | KEntryAttHidden | KEntryAttSystem | KEntryAttArchive);
+ }
+
+TInt RRealDirectoryScanner::Next(TEntry& aOut)
+ {
+ return iDir.Read(aOut);
+ }
+
+void RRealDirectoryScanner::Close()
+ {
+ iDir.Close();
+ }
+
+/**
+Simply counts the number of numerical characters at the end of the name passed.
+
+@internalComponent
+@param aFilename The filename to parse
+
+@return Count of the numeric digits at the end of the name passed,
+ e.g. x.r491 gives 3.
+*/
+TInt TNearestLanguageFileFinder::CountDigitsFromEnd(const TDesC& aFilename)
+ {
+ TInt digitCount = 0;
+
+ for (TInt idx = aFilename.Length()-1; idx>=0 && ISDIGIT (aFilename [idx]); --idx)
+ {
+ ++digitCount;
+ }
+
+ return digitCount;
+ }
+
+
+/**
+Counts the number of digits at the end of a filename.
+
+@internalComponent
+@param aFilename The filename to parse
+
+@return Count of the numeric digits at the end of the suffix,
+ e.g. x.r491 gives 3.
+ 0 if no numeric end of suffix,
+ KErrBadName for an invalid filename,
+ KErrNotSupported if the filename (minus path) is less
+ than or equal to KInvNameAndMinSuffixLength in length
+*/
+TInt TNearestLanguageFileFinder::CountDigitsFromEndInSuffix (const TDesC& aFilename)
+ {
+ TInt digitCount = 0;
+ TInt slashIdx = 0;
+ TInt len = aFilename.Length ();
+
+ // NOTE: We didn't use TChar here as they are too slow.
+ // We also didn't use TParse as they are too large.
+
+ // don't work on the path
+ for (slashIdx=len-1; slashIdx >= 0 && aFilename[slashIdx] != '\\'; --slashIdx)
+ {/*do nothing*/};
+
+ // Get new length
+ if (slashIdx>=0) {len = len-slashIdx-1;}
+
+ // Initial test to see if filename legal size.
+ if (len > KInvNameAndMinSuffixLength)
+ {
+ digitCount = CountDigitsFromEnd(aFilename);
+
+ // Can't store something bigger or we'll panic!
+ if (digitCount > KMaxSuffixLength)
+ {
+ digitCount = KErrBadName;
+ }
+ else
+ // numeric filename, e.g. "1234".
+ // No preceeding alpha character
+ if (!(len-digitCount))
+ {
+ digitCount = KErrBadName;
+ }
+ }
+ else
+ {
+ digitCount = KErrNotSupported;
+ }
+
+ return digitCount;
+ }
+
+RDirectoryScanner& TNearestLanguageFileFinder::DirectoryScanner()
+ {
+ return iDirScanner;
+ }
+
+TBool TNearestLanguageFileFinder::FileExists(const TDesC& aFileName) const
+ {
+ //return BaflUtils::FileExists(iFs, aFileName);
+ TEntry entry;
+ return(iFs.Entry(aFileName,entry)==KErrNone);
+
+ }
+
+TBool TNearestLanguageFileFinder::FindDrive()
+ {
+ ASSERT(iFileName);
+ TBool found=EFalse;
+ TInt driveLength=iDrives.Length();
+ for (TInt drive = 0; drive!=driveLength; ++drive)
+ {
+ (*iFileName)[0] = iDrives[drive];
+ if (FileExists(*iFileName))
+ {
+ found=ETrue;
+ break;
+ }
+ }
+ return found;
+ }
+
+TBool TNearestLanguageFileFinder::AppendLanguageCode(TLanguage aLanguage)
+ {
+ TInt rest = static_cast<TInt>(aLanguage);
+#ifdef _DEBUG
+ _LIT(KErrorMessage, "Bafl");
+#endif
+ __ASSERT_DEBUG(0 <= rest, User::Panic(KErrorMessage,KErrArgument));
+ iFileName->SetLength(iBaseLength);
+ const TInt remaining = iFileName->MaxLength() - iBaseLength;
+ TInt soFar = 0;
+ TBuf<1> num;
+ num.Append('0');
+ TBool appendLangSuccess = ETrue;
+ TInt digitCount = 0;
+ TInt digit = 0;
+ while (rest)
+ {
+ if (remaining == soFar)
+ {
+ // no more room in descriptor- return rather than panic,
+ // file cannot exist.
+ iFileName->SetLength(iBaseLength);
+ appendLangSuccess= EFalse;
+ break;
+ }
+ // Convert the number to ASCII by consistantly getting the base 10 remainder to convert.
+ // The number is updated minus the remainder for the next iteration.
+ // eg (rest = 123) -> (12, r3) -> (1, r2) -> (0, r1)
+ // Then insert the ASCII representation of the remainder into the filename end
+ // so it appears the correct way round.
+ // eg (filename.r) -> (filename.r3) -> (filename.r23) -> (filename.r123)
+ digit = rest % 10;
+ digitCount++;
+ rest /= 10;
+ num[0] = static_cast<TText16>(digit + '0');
+ iFileName->Insert(iBaseLength, num);
+
+ // Minimum suffix length is KInvNameAndMinSuffixLength
+ // so we have to insert zeros to make this up.
+ while (!rest && digitCount < KInvNameAndMinSuffixLength)
+ {
+ num[0] = static_cast<TText16>('0');
+ iFileName->Insert(iBaseLength, num);
+ ++digitCount;
+ }
+
+ ++soFar;
+ }
+
+ return appendLangSuccess;
+ }
+
+
+TBool TNearestLanguageFileFinder::FindLanguageAndDrive()
+/** Search for files across all drives in all languages in the path plus the
+language-neutral file. */
+ {
+ ASSERT(iFileName);
+ // No point appending if the suffix is bad
+ for (const TLanguage* currentLang = iPath; *currentLang != ELangNone; ++currentLang)
+ {
+ if (AppendLanguageCode(*currentLang) && FindDrive())
+ {
+ iLanguage = *currentLang;
+ return ETrue;
+ }
+ }
+ // search for language-neutral file
+ iFileName->SetLength(iBaseLength);
+ iFileName->Append(iSuffix);
+ return FindDrive();
+ }
+
+TInt TNearestLanguageFileFinder::LanguageNumberFromFile(const TDesC& aFileName, const TDesC& aStem)
+ {
+ TInt lang = 0;
+ TInt multiplier = 1;
+ TInt leadingZeroCount = 0;
+ TInt languageNumber = KErrNotFound;
+ const TText* firstChar = aFileName.Ptr();
+ const TText* lastChar = firstChar + aFileName.Length() - 1;
+ const TText* currentChar = lastChar;
+ // string cannot contain only numbers, because it must have a ':' in it
+ while ('0' <= *currentChar && *currentChar <= '9')
+ {
+ if (*currentChar == '0')
+ leadingZeroCount++;
+ else
+ {
+ leadingZeroCount = 0;
+ lang += multiplier * (*currentChar - '0');
+ }
+ multiplier *= 10;
+ --currentChar;
+ }
+ TInt along=lastChar - currentChar;
+ if (2 <= along)
+ {
+ // We have at least 2 digits at the end.
+ // trim of bad leading zeros
+ TInt maxTrim = along - 2;
+ if (maxTrim < leadingZeroCount)
+ {
+ leadingZeroCount = maxTrim;
+ }
+ currentChar += leadingZeroCount;
+ // we have at least 2 digits at the end but does the rest of it match the stem?
+ TPtrC foundStem(firstChar, currentChar - firstChar + 1);
+ //foundStem.CompareF(aStem.Right(foundStem.Length()))
+ if (0 == foundStem.CompareF(aStem))
+ {
+ languageNumber=lang;
+ }
+ }
+ return languageNumber;
+ }
+
+TInt TNearestLanguageFileFinder::FindFirstLanguageFile(RFs& aFs)
+ {
+ ASSERT(iFileName);
+ iFileName->SetLength(iBaseLength);
+ TPtrC name(*iFileName);
+ TParsePtrC nameToParse(name);
+ TPtrC nameStem(nameToParse.NameAndExt());
+ iFileName->Append('*');
+ TInt bestLanguageMatch = KMaxTInt;
+ RDirectoryScanner& scanner = DirectoryScanner();
+ TInt err = scanner.Open(aFs, *iFileName);
+ if (err != KErrNone)
+ {
+ return err;
+ }
+ TEntry entry;
+ while (KErrNone == scanner.Next(entry))
+ {
+ TInt lang = LanguageNumberFromFile(entry.iName, nameStem);
+ if (0 < lang && lang < bestLanguageMatch)
+ {
+ bestLanguageMatch = lang;
+ }
+ }
+ scanner.Close();
+ if (bestLanguageMatch != KMaxTInt)
+ {
+ iLanguage = static_cast<TLanguage>(bestLanguageMatch);
+ AppendLanguageCode(static_cast<TLanguage>(bestLanguageMatch));
+ return KErrNone;
+ }
+ return KErrNotFound;
+ }
+
+// Try each drive for any language files
+// iFileName must have a directory specifier
+TInt TNearestLanguageFileFinder::FindFirstLanguageFileAndDrive()
+ {
+ ASSERT(iFileName);
+ TInt findFirstResult=KErrNotFound;
+ TInt driveLength=iDrives.Length();
+ for (TInt drive = 0; drive != driveLength; ++drive)
+ {
+ (*iFileName)[0] = iDrives[drive];
+ TInt err = FindFirstLanguageFile(CONST_CAST(RFs&,iFs));
+ if (err == KErrNone || err == KErrNoMemory)
+ {
+ findFirstResult=err;
+ break;
+ }
+ }
+ return findFirstResult;
+ }
+
+/**
+Invalid filenames are any filename whose length (minus path) must be greater
+than KInvNameAndMinSuffixLength, and whose form is purely numerical, i.e. '1234'
+*/
+TBool TNearestLanguageFileFinder::SetFileName(TFileName& aFileName)
+ {
+ iDrives.Zero();
+ iFileName = &aFileName;
+ iOriginalBaseLength = iFileName->Length();
+
+ TInt suffixLength = CountDigitsFromEndInSuffix (aFileName);
+
+ // No point trying for filenames thats are badly formed
+ // or that are too large.
+ if (suffixLength >= 0 &&
+ KInvNameAndMinSuffixLength < iOriginalBaseLength)
+ {
+ if (suffixLength > 0)
+ {
+ // all of suffix to be replaced
+ iSuffix = iFileName->Right(suffixLength);
+ iOriginalBaseLength -= suffixLength;
+ iFileName->SetLength(iOriginalBaseLength);
+ }
+ else
+ {
+ // No numerical part to suffix
+ TInt periodIdx = 0;
+
+ // Search for the period within range KInvNameAndMinSuffixLength
+ // from the end. As this must work for all values of
+ // KInvNameAndMinSuffixLength
+ for (TInt i = iOriginalBaseLength-1;
+ !periodIdx && i >= (iOriginalBaseLength-KInvNameAndMinSuffixLength-1);
+ --i)
+ {
+ if ((*iFileName) [i] == '.')
+ {
+ periodIdx = i;
+ }
+ }
+
+ // Don't handle files ending in a period.
+ // This is because the behaviour is different between Windows
+ // and Symbian Fs. In Windows it strips the period off.
+ //
+ // However, and this shouldn't happen as it is not shown
+ // (in the documentation) to be valid.
+ // Just try our best.
+ if (periodIdx == iOriginalBaseLength-1)
+ {
+ iSuffix.Zero();
+ return EFalse;
+ }
+ else
+ if (periodIdx)
+ {
+ // If there are KInvNameAndMinSuffixLength chars after the period
+ // simply replace them.
+ TInt right = iOriginalBaseLength-periodIdx-1;
+ iSuffix = iFileName->Right(right);
+ iOriginalBaseLength -= right;
+ iFileName->SetLength(iOriginalBaseLength);
+ }
+ else
+ {
+ // Make the suffix start from KInvNameAndMinSuffixLength
+ // from the right
+ TInt right = KInvNameAndMinSuffixLength;
+ iSuffix = iFileName->Right(right);
+ iOriginalBaseLength -= right;
+ iFileName->SetLength(iOriginalBaseLength);
+ }
+ }
+ }
+ else
+ {
+ // bad or no suffix - treat the same
+ iSuffix.Zero();
+ return EFalse;
+ }
+
+ // For filenames with no drive letter prefix and also for filenames
+ // shorter than the drive letter length, i.e. with no drive
+ // information, insert it.
+ // Handles if the user simply enters the drive, e.g. "c:".
+ if (iOriginalBaseLength < KMaxDriveName || (*iFileName)[1] != ':')
+ {
+ // Set up the default if none supplied and make room in the filename
+ // array to contain a drive specification. Set initial drive letter to -1
+ // so the iFileName is repaired before exited
+ iInitialDriveLetter = -1;
+ iFileName->Insert(0, _L("_:"));
+ iDrives.Append('Z');
+ }
+ else
+ {
+ // Use the drive supplied inthe aName to NearestLanguageFile()
+ iInitialDriveLetter = (*iFileName)[0];
+ iDrives.Append(iInitialDriveLetter);
+ }
+
+ iBaseLength = iFileName->Length();
+
+ return ETrue;
+ }
+
+
+TLanguage TNearestLanguageFileFinder::Language()
+ {
+ return iLanguage;
+ }
+
+TNearestLanguageFileFinder::TNearestLanguageFileFinder(
+ const RFs& aFs)
+ : iFs(aFs), iFileName(0), iLanguage(ELangNone)
+ {
+ }
+
+void TNearestLanguageFileFinder::RepairFileName()
+ {
+ ASSERT(iFileName);
+ iFileName->SetLength(iBaseLength);
+ if (iInitialDriveLetter == -1)
+ iFileName->Delete(0, 2);
+ else
+ (*iFileName)[0] = static_cast<TText>(iInitialDriveLetter);
+ iFileName->SetLength(iOriginalBaseLength);
+ iFileName->Append(iSuffix);
+ }
+
+
+/**
+Add the custom resource drive to the start of the iDrives string.
+
+The custom resource drive is a preset writeable drive on which customised
+resource files may be present. This drive takes priority over the other
+drives when searching for language files.
+
+@return KErrNone if iDrives string was successfully modified; KErrAlreadyExists
+if the drive is already present in the string; otherwise one of
+the other system-wide error codes (iDrives will be unmodified).
+*/
+TInt TNearestLanguageFileFinder::AddCustomResourceDrive()
+ {
+ TInt drive = GetCustomResourceDriveNumber();
+ if (drive<0)
+ return drive;
+
+ // if drive not already in drive list
+ if (iDrives.LocateF('A' + drive) < 0)
+ {
+ // add it
+ _LIT(KDrivePlaceholder, "_");
+ iDrives.Insert(0, KDrivePlaceholder);
+ iDrives[0] = 'A' + drive;
+ return KErrNone;
+ }
+ else
+ return KErrAlreadyExists;
+ }
+
+
+void TNearestLanguageFileFinder::AddAllDrives()
+ {
+ ASSERT(iDrives.Length() < 2);
+ if (iDrives.Length() == 0)
+ {
+ iDrives = KAllDrives;
+ return;
+ }
+ TInt pos = KAllDrives().LocateF(iDrives[0]);
+ if (pos < 0)
+ {
+ iDrives = KAllDrives;
+ return;
+ }
+ iDrives.Append(KAllDrives().Left(pos));
+ iDrives.Append(KAllDrives().Mid(pos + 1));
+ }
+
+
+/**
+Get the value of the custom resource drive.
+
+The custom resource drive is a preset writeable drive on which customised language resource
+files can reside. The drive number is accessed via the HAL attribute ECustomResourceDrive.
+It is then returned if it has been defined as a valid drive no.
+Otherwise for backward compatibility reasons an attempt is then made to access the system
+drive HAL attribute instead. This drive number is returned if it has been defined as a valid
+drive number.
+Otherwise if neither a valid ECustomResourceDrive or ESystemDrive exists then KErrNotFound
+is returned.
+
+Note that the ESystemDrive HAL attribute has been deprecated. It is accessed here to cater
+for existing implementations which still expect it to be used.
+
+@return The drive number (corresponding to a TDriveNumber value) if successful;
+KErrNotFound if neither a valid ECustomResourceDrive or a valid ESystemDrive HAL attribute
+is defined;
+
+@see HAL::ECustomResourceDrive
+@see HAL::ESystemDrive
+*/
+TInt TNearestLanguageFileFinder::GetCustomResourceDriveNumber() const
+ {
+ TInt drive = KErrNotFound;
+
+ // access custom resource drive attribute
+ if (HAL::Get(HAL::ECustomResourceDrive, drive) == KErrNone)
+ {
+ // check that drive is valid
+ if (drive>=EDriveA && drive<=EDriveZ)
+ return drive;
+ }
+
+ // access system drive attribute
+ // (Note that ESystemDrive is deprecated. It is checked here
+ // solely for backward compatibility reasons.)
+ if (HAL::Get(HAL::ESystemDrive, drive) == KErrNone)
+ {
+ // check that drive is valid
+ if (drive>=EDriveA && drive<=EDriveZ)
+ return drive;
+ }
+
+ return KErrNotFound;
+ }
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/src/LangUtilImpl.h Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,148 @@
+// Copyright (c) 1997-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:
+//
+
+#ifndef __LANGUTILIMPL_H__
+#define __LANGUTILIMPL_H__
+
+
+#include <f32file.h>
+#include <e32std.h>
+
+/**
+Specifies the maximum length of the numerical part of the suffix.
+
+If this is changed the documentation of the following functions
+must also be updated:
+
+ LangUtil::NearestLanguageFile()
+ TNearestLanguageFileFinder::CountDigitsFromEndInValidSuffix()
+ TNearestLanguageFileFinder::SetFileName()
+*/
+const TInt KMaxSuffixLength = 5;
+
+class RDirectoryScanner
+/**
+@internalAll
+*/
+ {
+public:
+ virtual TInt Open(RFs& aFs, const TDesC& aMatchPattern) = 0;
+ virtual TInt Next(TEntry& aOut) = 0;
+ virtual void Close() = 0;
+ virtual ~RDirectoryScanner() {}
+ };
+
+NONSHARABLE_CLASS(RRealDirectoryScanner) : public RDirectoryScanner
+/**
+@internalAll
+*/
+ {
+public:
+ virtual TInt Open(RFs& aFs, const TDesC& aMatchPattern);
+ virtual TInt Next(TEntry& aOut);
+ virtual void Close();
+private:
+ RDir iDir;
+ };
+
+
+/**
+ * Add a language to the end of the language path, unless it is already
+ * present. On entry, the language path must have an ELangNone entry at its
+ * end. This will be true on exit also.
+ * @internalAll
+ */
+void AddLanguage(TLanguagePath& aPath, TLanguage aNewLanguage);
+
+/**
+ * Create a language path from the current language, ideal language and locale.
+ * The path may have up to eight entries in it.
+ * @internalAll
+ */
+
+void MakeLanguageDowngradePath(TLanguagePath& aPath,
+ TLanguage aCurrent, TLanguage aIdeal, const TLocale& aLocale);
+
+
+/**
+ * This class contains all the functions for working out the nearest language
+ * file. It can be derived from for test code purposes.
+ * @internalAll
+ */
+NONSHARABLE_CLASS(TNearestLanguageFileFinder)
+ {
+public:
+ TNearestLanguageFileFinder(const RFs& aFs);
+ TBool SetFileName(TFileName& aFileName);
+ TLanguage Language();
+ // put back the original suffix and drive letter
+ void RepairFileName();
+ // add the preset custom resource drive, if any, to iDrives.
+ TInt AddCustomResourceDrive();
+ // add all remaining drives to iDrives. iDrives must not have more than one
+ // drive in it on entry.
+ void AddAllDrives();
+ // Tries to append the language code to iFileName. This is 00..09 or just the number.
+ // If there was not enough space, EFalse is returned.
+ TBool AppendLanguageCode(TLanguage aLanguage);
+ // Search the drives in iDrives for the file named iFileName.
+ // iFileName must have a drive specifier, which will be overwritten.
+ TBool FindDrive();
+ // Search for files across all drives in all languages in the path plus the
+ // language-neutral file.
+ // On entry, iFileName should be the original name with a drive specifier
+ // minus the suffix. On return, iFileName will be untouched if EFalse is
+ // returned, but contain the result if ETrue is returned.
+ TBool FindLanguageAndDrive();
+ // Test whether the filename passed in matches the stem given + numbers
+ // added to the end. Returns the number if it does, or KErrNotFound if not.
+ // aFileName must not end in a digit.
+ static TInt LanguageNumberFromFile(const TDesC& aFileName, const TDesC& aStem);
+ // Find lowest numbered file that matches iFileName, which must be without
+ // its suffix.
+ TInt FindFirstLanguageFile(RFs&);
+ // Try each drive for any language files that match iFileName.
+ // iFileName must have a directory specifier and be without its suffix.
+ // returns KErrNotFound, KErrNone or error code.
+ TInt FindFirstLanguageFileAndDrive();
+
+ virtual TInt GetCustomResourceDriveNumber() const;
+
+ virtual TInt FileExists(const TDesC& aFileName) const;
+ // return our member that is our directory scanning class
+ virtual RDirectoryScanner& DirectoryScanner();
+ virtual ~TNearestLanguageFileFinder() {}
+
+private:
+ TInt CountDigitsFromEnd(const TDesC& aFilename);
+ TInt CountDigitsFromEndInSuffix (const TDesC& aFilename);
+
+public:
+ const RFs& iFs;
+ TFileName* iFileName;
+ TLanguage iLanguage;
+ TBuf<26> iDrives;
+ TLanguagePath iPath;
+ TBuf<KMaxSuffixLength> iSuffix;
+ TInt iInitialDriveLetter;
+ // length minus the removed suffix
+ TInt iOriginalBaseLength;
+ // length plus added drive letter minus removed suffix
+ TInt iBaseLength;
+ RRealDirectoryScanner iDirScanner;
+ };
+
+#endif // __LANGUTILIMPL_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_All_langutils.bat Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+@echo on
+testexecute.exe z:\test\T_All_langutils.script
+@echo off
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_All_langutils.script Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,6 @@
+PRINT Run All T_LangUtilsServer tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILS
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSIMP
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSLANG
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtils.MMP Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,37 @@
+// Copyright (c) 1997-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:
+//
+// T_CLIPB.MMP for test component T_CLIPB (released in BAFL)
+//
+//
+
+target T_LangUtils.exe
+targettype EXE
+UID 0x1000007a
+
+SOURCEPATH ../tsrc
+userinclude ../inc
+userinclude ../src
+userinclude ../tsrc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+source /T_LangUtils.cpp
+source /T_LangUtilsTestShareFunc.cpp
+
+STATICLIBRARY langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+
+CAPABILITY WriteDeviceData
+
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtils.cpp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,425 @@
+// Copyright (c) 1997-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:
+//
+
+
+#include <baclipb.h>
+#include <f32file.h>
+#include <s32strm.h>
+#include <s32file.h>
+#include <e32lang.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+#include "t_langutils.h"
+
+
+
+#define test(cond) \
+ { \
+ TBool __bb = (cond); \
+ TEST(__bb); \
+ if (!__bb) \
+ { \
+ ERR_PRINTF1(_L("ERROR: Test Failed")); \
+ User::Leave(1); \
+ } \
+ }
+
+// File names for copying
+
+const TPtrC KSystem1Folder =_L("C:\\System1\\");
+const TPtrC KSystem1Data1Folder =_L("C:\\System1\\data1\\");
+
+const TPtrC KSystem1Data1File1 =_L("C:\\System1\\data1\\file1.txt");
+const TPtrC KFile1 =_L("C:\\file1.txt");
+const TPtrC KSystem1Data1SrcFile1 =_L("C:\\System1\\data1\\src\\file1.txt");
+const TPtrC KSystem1Data1DstFile2 =_L("C:\\System1\\data1\\dst\\file2.txt");
+const TPtrC KSystem1Data1File123456789 =_L("C:\\System1\\data1\\file123456789.txt");
+const TPtrC KSystem1Data1File2 =_L("C:\\System1\\data1\\file2.txt");
+const TPtrC KSystem1Data1File5 =_L("C:\\System1\\data1\\file5.txt");
+const TPtrC KSystem1Data1SrcFolder =_L("C:\\System1\\data1\\src\\");
+const TPtrC KSystem1Data1DstFolder =_L("C:\\System1\\data1\\dst\\");
+
+const TPtrC KZFile1 =_L("Z:\\file1.txt");
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+//LangUtil::GetEquivalentLanguageList
+//LangUtil::NearestLanguageFileV2
+//test data
+_LIT (KNullFilename, "");
+_LIT (KRscFilename, "C:\\geltest.rsc");
+_LIT (KRscFilenameNoSuffix, "C:\\geltest.");
+
+_LIT (KAmericanLang, "C:\\geltest.r10");
+_LIT (KFrenchLang, "C:\\geltest.r02");
+_LIT (KJapanEnglishLang, "C:\\geltest.r160");
+_LIT (KEnglishLang, "C:\\geltest.r01");
+_LIT (KInvalidDriveLetterV2, "q:\\geltest.rsc");
+_LIT (KNoSuchLangFile, "c:\\geltest.r54");
+
+
+//Delete "aFullName" file.
+void CT_LANGUTILS::DeleteTestFile(const TDesC& aFullName)
+ {
+ RFs fsSession;
+ TInt err = fsSession.Connect();
+ if(err == KErrNone)
+ {
+ TEntry entry;
+ if(fsSession.Entry(aFullName, entry) == KErrNone)
+ {
+ INFO_PRINTF2(_L("Deleting \"%S\" file.\n"), &aFullName);
+ err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+ if(err != KErrNone)
+ {
+ INFO_PRINTF3(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
+ }
+ err = fsSession.Delete(aFullName);
+ if(err != KErrNone)
+ {
+ INFO_PRINTF3(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
+ }
+ }
+ fsSession.Close();
+ }
+ else
+ {
+ INFO_PRINTF3(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+ }
+ }
+
+//Delete "aFullName" dir.
+void CT_LANGUTILS::DeleteTestDir(const TDesC& aFullName)
+ {
+ RFs fsSession;
+ TInt err = fsSession.Connect();
+ if(err == KErrNone)
+ {
+ TEntry entry;
+ if(fsSession.Entry(aFullName, entry) == KErrNone)
+ {
+ INFO_PRINTF2(_L("Deleting \"%S\" dir.\n"), &aFullName);
+ err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+ if(err != KErrNone)
+ {
+ INFO_PRINTF3(_L("Error %d changing \"%S\" dir attributes.\n"), err, &aFullName);
+ }
+ err = fsSession.RmDir(aFullName);
+ if(err != KErrNone)
+ {
+ INFO_PRINTF3(_L("Error %d deleting \"%S\" dir.\n"), err, &aFullName);
+ }
+ }
+ fsSession.Close();
+ }
+ else
+ {
+ INFO_PRINTF3(_L("Error %d connecting file session. Dir: %S.\n"), err, &aFullName);
+ }
+ }
+
+//Delete data files used by the test
+void CT_LANGUTILS::DeleteTestFiles()
+ {
+ DeleteTestFile(KSystem1Data1File1);
+ DeleteTestFile(KFile1);
+ DeleteTestFile(KSystem1Data1SrcFile1);
+ DeleteTestFile(KSystem1Data1DstFile2);
+ DeleteTestFile(KSystem1Data1File123456789);
+ DeleteTestFile(KSystem1Data1File2);
+ DeleteTestFile(KSystem1Data1File5);
+ DeleteTestDir(KSystem1Data1SrcFolder);
+ DeleteTestDir(KSystem1Data1DstFolder);
+ DeleteTestDir(KSystem1Data1Folder);
+ DeleteTestDir(KSystem1Folder);
+ }
+
+
+
+
+void CT_LANGUTILS::DeleteTestFiles2(RFs &aFs)
+{
+ LangUtilsTest::DeleteFile (aFs, KRscFilename);
+ LangUtilsTest::DeleteFile (aFs, KAmericanLang);
+ LangUtilsTest::DeleteFile (aFs, KFrenchLang);
+ LangUtilsTest::DeleteFile (aFs, KJapanEnglishLang);
+ LangUtilsTest::DeleteFile (aFs, KEnglishLang);
+}
+
+void CT_LANGUTILS::CreateTestFiles2(RFs &aFs)
+{
+ test(LangUtilsTest::FileExists (aFs, KRscFilename) == EFalse);
+ test(LangUtilsTest::FileExists (aFs, KAmericanLang) == EFalse);
+ test(LangUtilsTest::FileExists (aFs, KFrenchLang) == EFalse);
+ test(LangUtilsTest::FileExists (aFs, KJapanEnglishLang) == EFalse);
+ test(LangUtilsTest::FileExists (aFs, KEnglishLang) == EFalse);
+
+ // Create the files...
+ RFile rFile;
+ test(KErrNone == rFile.Create (aFs, KRscFilename, EFileRead));
+ rFile.Close ();
+ test(KErrNone == rFile.Create (aFs, KAmericanLang, EFileRead));
+ rFile.Close ();
+ test (KErrNone == rFile.Create (aFs, KFrenchLang, EFileRead));
+ rFile.Close ();
+ test(KErrNone == rFile.Create (aFs, KEnglishLang, EFileRead));
+ rFile.Close ();
+}
+///////////////////////////////////////////////////////////////////////////////////////
+//Copy test file from Z: to C: drive.
+
+void CT_LANGUTILS::CopyTestFiles()
+ {
+ RFs fsSession;
+ TInt err = fsSession.Connect();
+ if(err == KErrNone)
+ {
+ User::LeaveIfError(fsSession.MkDir(KSystem1Folder));
+ User::LeaveIfError(fsSession.MkDir(KSystem1Data1Folder));
+ test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File1) == KErrNone);
+ test( LangUtilsTest::CopyFile(fsSession, KZFile1, KFile1) == KErrNone);
+ test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File123456789) == KErrNone);
+ test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File2) == KErrNone);
+ test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1File5) == KErrNone);
+ User::LeaveIfError(fsSession.MkDir(KSystem1Data1SrcFolder));
+ User::LeaveIfError(fsSession.MkDir(KSystem1Data1DstFolder));
+ test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1SrcFile1) == KErrNone);
+ test( LangUtilsTest::CopyFile(fsSession, KZFile1, KSystem1Data1DstFile2) == KErrNone);
+
+ fsSession.Close();
+ }
+ else
+ {
+ INFO_PRINTF2(_L("Error %d connecting file session.\n"), err);
+ }
+ }
+
+
+
+
+
+/**
+@SYMTestCaseID TI18N-BAFL-CT-4003
+@SYMTestCaseDesc Tests Baflutils::TestNearestLanguageFileV2.
+@SYMTestPriority Medium
+@SYMTestActions Pass in various resource file names and change system locale setting, check the return values.
+@SYMTestExpectedResults The test must not fail.
+@SYMPREQ 2525 Install device equivalent languages from SIS files
+*/
+void CT_LANGUTILS::TestNearestLanguageFileV2(RFs& aFs)
+ {
+ /* test case ID to be added */
+ INFO_PRINTF1(_L (" @SYMTestCaseID TI18N-BAFL-CT-4003 "));
+
+ __UHEAP_MARK;
+
+ CleanupClosePushL (aFs);
+ User::LeaveIfError (aFs.Connect ());
+
+ DeleteTestFiles2(aFs);
+ CreateTestFiles2(aFs);
+
+ TBuf <256> filename;
+ TLanguage lang = ELangNone;
+ INFO_PRINTF2 (_L("lang initial value is %d\n"), lang);
+
+ // Test NearestLanguageFile with empty name
+ TFileName resPath;
+ LangUtil::NearestLanguageFileV2(aFs, resPath, lang);
+ test(resPath.Length()==0);
+ INFO_PRINTF2 (_L("lang returned by NLFV2 is %d\n"), lang);
+ test(ELangNone == lang);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for the null file - %S - is - %S -\n"), &KNullFilename, &filename);
+
+ // Test NearestLanguageFile with invalid drive letter
+ filename.Copy (KInvalidDriveLetterV2);
+ LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+ //test(filename==KRscFilenameNoSuffix);
+ INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, lang is %d\n"), &KInvalidDriveLetterV2, &filename, lang);
+ //test(ELangNone == lang);
+
+ // Test NearestLanguageFile with incorrect ext
+ DeleteTestFiles2(aFs);
+ RFile rFile;
+ test (KErrNone == rFile.Create (aFs, KFrenchLang, EFileRead));
+ rFile.Close ();
+ filename.Copy (KNoSuchLangFile);
+ LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+ //test(filename==KRscFilenameNoSuffix);
+ INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, lang is %d\n"), &KNoSuchLangFile, &filename, lang);
+ //test(ELangNone == lang);
+ LangUtilsTest::DeleteFile (aFs, KFrenchLang);
+ CreateTestFiles2(aFs);
+
+ // Test NearestLanguageFile with no suffix
+ filename.Copy (KRscFilenameNoSuffix);
+ LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+ test(filename==KRscFilenameNoSuffix);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilenameNoSuffix, &filename);
+ test(ELangNone == lang);
+
+ // change locale to American
+ /*
+ TExtendedLocale loc;
+ loc.LoadSystemSettings();
+ TInt ret = loc.LoadLocaleAspect(_L ("elocl_lan.010"));
+ INFO_PRINTF2(_L("LoadLocale returns %d\n"), ret);
+ test(KErrNone == ret);
+ ret = loc.SaveSystemSettings();
+ test(KErrNone == ret);
+
+ // Test NearestLanguageFile: AmE is supported
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+ //test(filename == KEnglishLang);
+ test(filename == KAmericanLang);
+ test(lang == ELangAmerican);
+
+ // Delete geltest.r10, AmE downgrades to En_GB.
+ LangUtilsTest::DeleteFile (aFs, KAmericanLang);
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+ test(filename == KEnglishLang);
+ test(lang == ELangEnglish);
+
+
+ // Delete geltest.r01, AmE downgrades to en_GB, to ELangNone.
+ LangUtilsTest::DeleteFile (aFs, KEnglishLang);
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFileV2(aFs, filename, lang);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+ test(filename == KRscFilename); // filename remains unchanged.
+ test(lang == ELangNone);
+
+ // restore locale settings
+ INFO_PRINTF1(_L("Restoring locale settings.\n"));
+ loc.LoadSystemSettings();
+ ret = loc.LoadLocaleAspect(_L("elocl_lan.001"));
+ test(KErrNone == ret);
+ ret = loc.SaveSystemSettings();
+ test(KErrNone == ret);
+ */
+
+ CleanupStack::PopAndDestroy (&aFs);
+
+ __UHEAP_MARKEND;
+ }
+
+/**
+@SYMTestCaseID TI18N-BAFL-CT-4004
+@SYMTestCaseDesc Tests Baflutils::TestGetEquivalentLanguageList.
+@SYMTestPriority Medium
+@SYMTestActions Pass in various language ID's and check the returned list.
+@SYMTestExpectedResults The test must not fail.
+@SYMPREQ 2525 Install device equivalent languages from SIS files
+*/
+void CT_LANGUTILS::TestGetEquivalentLanguageList()
+ {
+ /* test case ID to be added */
+ INFO_PRINTF1 (_L (" @SYMTestCaseID TI18N-BAFL-CT-4004 "));
+
+ __UHEAP_MARK;
+
+ TLanguagePath lp;
+ // Test GetNearestLanguageFile();
+ // 1- There is an entry in the table for the given language
+ LangUtil::GetEquivalentLanguageList(ELangCyprusGreek, lp);
+ test(ELangCyprusGreek == lp[0]);
+ test(ELangGreek == lp[1]);
+ test(ELangNone == lp[2]);
+
+ // 2- There is no entry for the given language
+ LangUtil::GetEquivalentLanguageList(ELangFarsi, lp);
+ test(ELangFarsi == lp[0]);
+ test(ELangNone == lp[1]);
+
+ __UHEAP_MARKEND;
+ }
+
+/**
+@SYMTestCaseID TI18N-BAFL-CT-4004
+@SYMTestCaseDesc Tests Baflutils::TestGetDowngradePathL.
+@SYMTestPriority Medium
+@SYMTestActions Pass in various language ID's and check the returned list.
+@SYMTestExpectedResults The test must not fail.
+@SYMPREQ 2525 Install device equivalent languages from SIS files
+*/
+void CT_LANGUTILS::TestGetDowngradePathL()
+ {
+ RFs fsSession;
+ TInt err = fsSession.Connect();
+ if(err == KErrNone)
+ {
+ TLanguage currentLang = ELangPrcChinese;
+ RArray<TLanguage> languageArray;
+ LangUtil::GetDowngradePathL(fsSession, currentLang,languageArray);
+ fsSession.Close();
+ test(ELangPrcChinese == languageArray[0]);
+ test(1 == languageArray.Count());
+ languageArray.Close();
+ }
+ else
+ {
+ INFO_PRINTF2(_L("Error %d connecting file session. "), err);
+ }
+ }
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0038
+@SYMTestCaseDesc Tests Baflutils.
+@SYMTestPriority Medium
+@SYMTestActions Executes all T_baflutils tests.
+@SYMTestExpectedResults The test must not fail.
+@SYMDEF DEF050397 - Crimson test code improvement to be propagated into MCL
+*/
+void CT_LANGUTILS::TestLANGUTILS()
+ {
+ RFs fs;
+
+ CopyTestFiles();
+ TestNearestLanguageFileV2(fs);
+ TestGetEquivalentLanguageList();
+ TestGetDowngradePathL();
+
+ DeleteTestFiles();
+ }
+
+CT_LANGUTILS::CT_LANGUTILS()
+ {
+ SetTestStepName(KTestStep_T_LANGUTILS);
+ }
+
+TVerdict CT_LANGUTILS::doTestStepL()
+ {
+ SetTestStepResult(EFail);
+
+ __UHEAP_MARK;
+
+ TRAPD(error1, TestLANGUTILS());
+
+ __UHEAP_MARKEND;
+
+ if(error1 == KErrNone )
+ {
+ SetTestStepResult(EPass);
+ }
+
+ return TestStepResult();
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsImp.cpp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,639 @@
+// Copyright (c) 1997-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:
+//
+
+#include "t_langutilsimp.h"
+
+
+#define test(cond) \
+ { \
+ TBool __bb = (cond); \
+ TEST(__bb); \
+ if (!__bb) \
+ { \
+ ERR_PRINTF1(_L("ERROR: Test Failed")); \
+ User::Leave(1); \
+ } \
+ }
+
+
+
+void CT_LANGUTILSIMP::TestPath(const TLanguagePath& aPath, const TLanguage* aExpected, TInt aExpectedCount)
+ {
+ for (int i = 0; i != aExpectedCount; ++i)
+ test(aPath[i] == *aExpected++);
+ test(aPath[aExpectedCount] == ELangNone);
+ }
+
+const TLanguage ExpectedPath[] = { ELangFrench, ELangJapanese, ELangGerman, ELangGreek,
+ ELangArabic, ELangEnglish, ELangItalian, ELangHebrew };
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0443
+@SYMTestCaseDesc Tests TLanguagePath class
+@SYMTestPriority High
+@SYMTestActions Test for adding different language paths
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void CT_LANGUTILSIMP::TestAddLanguage()
+ {
+ INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0443 "));
+ TLanguagePath path;
+ path[0] = ELangNone;
+ AddLanguage(path, ELangNone);
+ TestPath(path, ExpectedPath, 0);
+ AddLanguage(path, ELangFrench);
+ TestPath(path, ExpectedPath, 1);
+ AddLanguage(path, ELangFrench);
+ TestPath(path, ExpectedPath, 1);
+ AddLanguage(path, ELangNone);
+ TestPath(path, ExpectedPath, 1);
+ AddLanguage(path, ELangFrench);
+ TestPath(path, ExpectedPath, 1);
+ AddLanguage(path, ELangJapanese);
+ TestPath(path, ExpectedPath, 2);
+ AddLanguage(path, ELangFrench);
+ TestPath(path, ExpectedPath, 2);
+ AddLanguage(path, ELangNone);
+ TestPath(path, ExpectedPath, 2);
+ AddLanguage(path, ELangGerman);
+ TestPath(path, ExpectedPath, 3);
+ AddLanguage(path, ELangGreek);
+ TestPath(path, ExpectedPath, 4);
+ AddLanguage(path, ELangArabic);
+ TestPath(path, ExpectedPath, 5);
+ AddLanguage(path, ELangNone);
+ TestPath(path, ExpectedPath, 5);
+ AddLanguage(path, ELangEnglish);
+ TestPath(path, ExpectedPath, 6);
+ AddLanguage(path, ELangItalian);
+ TestPath(path, ExpectedPath, 7);
+ AddLanguage(path, ELangNone);
+ TestPath(path, ExpectedPath, 7);
+ AddLanguage(path, ELangHebrew);
+ TestPath(path, ExpectedPath, 8);
+ AddLanguage(path, ELangHebrew);
+ TestPath(path, ExpectedPath, 8);
+ AddLanguage(path, ELangEnglish);
+ TestPath(path, ExpectedPath, 8);
+ AddLanguage(path, ELangItalian);
+ TestPath(path, ExpectedPath, 8);
+ AddLanguage(path, ELangNone);
+ TestPath(path, ExpectedPath, 8);
+ AddLanguage(path, ELangFrench);
+ TestPath(path, ExpectedPath, 8);
+ AddLanguage(path, ELangNone);
+ TestPath(path, ExpectedPath, 8);
+ AddLanguage(path, ELangGerman);
+ TestPath(path, ExpectedPath, 8);
+ }
+
+
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0444
+@SYMTestCaseDesc Tests for the functionality of TLocale class
+@SYMTestPriority High
+@SYMTestActions Test for language downgrades
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void CT_LANGUTILSIMP::TestDowngrade(SDowngradeTest& aTest)
+ {
+ INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0444 "));
+ TLocale loc;
+ loc.SetLanguageDowngrade(0, aTest.iIn[1]);
+ loc.SetLanguageDowngrade(1, aTest.iIn[2]);
+ loc.SetLanguageDowngrade(2, aTest.iIn[3]);
+ TLanguagePath path;
+ MakeLanguageDowngradePath(path, aTest.iIn[0], ELangNone, loc);
+ for (int i = 0; ; ++i)
+ {
+ test(i < 9);
+ test(aTest.iOut[i] == path[i]);
+ if (path[i] == ELangNone)
+ return;
+ }
+
+ MakeLanguageDowngradePath(path, ELangAustralian, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangNewZealand, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangSouthAfricanEnglish, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangInternationalEnglish, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangAmerican, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangEnglish_Apac, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangEnglish_Taiwan, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangEnglish_HongKong, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangEnglish_Prc, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangEnglish_Japan, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangEnglish_Thailand, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangSwissFrench, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangBelgianFrench, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangInternationalFrench, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangCanadianFrench, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangSwissGerman, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangAustrian, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangInternationalSpanish, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangLatinAmericanSpanish, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangSwissItalian, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangFinlandSwedish, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangCyprusTurkish, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangBelgianFlemish, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangHongKongChinese, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangCyprusGreek, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangMalay_Apac, ELangNone, loc);
+ MakeLanguageDowngradePath(path, ELangBrazilianPortuguese, ELangNone, loc);
+
+ }
+
+
+// Test Dialect enumeration.
+// Each value represents a dialect (variant) of a TLanguage language.
+// E.g. AmericanSprint is represented by ELangAmerican | EDialectSprint
+
+// The dialect location -- top six bits
+const TUint KDialectFactor=0x0400;
+enum TDialect
+ {
+ // The following are example dialects for testing only
+ EDialectSprint = (1*KDialectFactor),
+ EDialectOrange = (2*KDialectFactor),
+ EDialectMaximum = EDialectOrange // This must always be equal to the last TDialect enum.
+ // Up to 63 dialects.
+ };
+
+const TLanguage ELangEnglishOrange = static_cast<TLanguage>(ELangEnglish|EDialectOrange);
+const TLanguage ELangAmericanSprint = static_cast<TLanguage>(ELangAmerican|EDialectSprint);
+
+SDowngradeTest DowngradeData[] =
+ {
+ // 0 = test language
+ // 1-3 = language downgrade for locale
+ // 4- = calculated language downgrade path, terminated with ELangNone.
+ {{ELangEnglishOrange, ELangNone, ELangNone, ELangNone},
+ {ELangEnglishOrange, ELangEnglish, ELangNone}},
+ {{ELangAmericanSprint, ELangNone, ELangNone, ELangNone},
+ {ELangAmericanSprint, ELangAmerican, ELangEnglish, ELangNone}},
+ {{ELangFrench, ELangNone, ELangNone, ELangNone},
+ {ELangFrench, ELangNone}},
+ {{ELangSwissFrench, ELangNone, ELangNone, ELangNone},
+ {ELangSwissFrench, ELangFrench, ELangNone}},
+ {{ELangCanadianEnglish, ELangNone, ELangNone, ELangNone},
+ {ELangCanadianEnglish, ELangAmerican, ELangEnglish, ELangNone}},
+ {{ELangSwissFrench, ELangNone, ELangFrench, ELangNone},
+ {ELangSwissFrench, ELangFrench, ELangNone}},
+ {{ELangCanadianEnglish, ELangEnglish, ELangNone, ELangAmerican},
+ {ELangCanadianEnglish, ELangEnglish, ELangAmerican, ELangNone}},
+ {{ELangCanadianEnglish, ELangNone, ELangNone, ELangSwissFrench},
+ {ELangCanadianEnglish, ELangSwissFrench, ELangAmerican, ELangEnglish, ELangNone}},
+ {{ELangCanadianEnglish, ELangFrench, ELangAmerican, ELangSwissFrench},
+ {ELangCanadianEnglish, ELangFrench, ELangAmerican, ELangSwissFrench, ELangEnglish, ELangNone}},
+ {{ELangCanadianEnglish, ELangNone, ELangGerman, ELangSwissFrench},
+ {ELangCanadianEnglish, ELangGerman, ELangSwissFrench, ELangAmerican, ELangEnglish, ELangNone}},
+ {{ELangCanadianEnglish, ELangFinlandSwedish, ELangGerman, ELangSwissFrench},
+ {ELangCanadianEnglish, ELangFinlandSwedish, ELangGerman, ELangSwissFrench, ELangAmerican, ELangEnglish, ELangNone}},
+ {{ELangFinlandSwedish, ELangFinlandSwedish, ELangFinlandSwedish, ELangFinlandSwedish},
+ {ELangFinlandSwedish, ELangSwedish, ELangNone}},
+ };
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0445
+@SYMTestCaseDesc Tests for language downgrades
+@SYMTestPriority High
+@SYMTestActions Call up downgrade path test function
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void CT_LANGUTILSIMP::TestMakeLanguageDowngradePath()
+ {
+ INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0445 "));
+ for (int i = 0; i != sizeof(DowngradeData)/sizeof(DowngradeData[0]); ++i)
+ TestDowngrade(DowngradeData[i]);
+ }
+
+void CT_LANGUTILSIMP::SetUpFinderForLanguageAndDriveSearchL(
+ TTestNearestLanguageFileFinder& aFinder)
+ {
+ aFinder.iDrives = _L("ZAG");
+ aFinder.iFilesSearchedFor = new(ELeave) CDesCArraySeg(10);
+ aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.e02"));
+ aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.e02"));
+ aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.e02"));
+ aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.e15702")); //Extended lang
+ aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.e15702"));
+ aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.e15702"));
+ aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.e01"));
+ aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.e01"));
+ aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.e01"));
+ aFinder.iFilesSearchedFor->AppendL(_L("z:\\dir\\name.ext"));
+ aFinder.iFilesSearchedFor->AppendL(_L("a:\\dir\\name.ext"));
+ aFinder.iFilesSearchedFor->AppendL(_L("g:\\dir\\name.ext"));
+ aFinder.iDrivesChecked = _L("zagzagzagzagzag");
+ }
+
+_LIT(KTestFileName1, "z:\\dir\\name.ext");
+//_LIT(KTestFileName2, "z:\\dir\\náme.ext");
+_LIT(KTestFileName2, "z:\\dir\\n\u00c1me.ext");
+_LIT(KTestFileName3, "a:\\dir\\name.ext");
+_LIT(KTestFileName4, "c:\\dir\\name.ext");
+_LIT(KTestFileName5, "d:\\dir\\name.ext");
+_LIT(KTestFileName6, "y:\\dir\\name.ext");
+_LIT(KTestFileName7, "A:\\dir\\name.ext");
+_LIT(KTestFileName8, "C:\\dir\\name.ext");
+_LIT(KTestFileName9, "Y:\\dir\\name.ext");
+_LIT(KTestFileName11, "\\abc\\defg.hijkl");
+_LIT(KTestFileName256Chars, "\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz0.ext");
+
+_LIT(KExpectedFileName256Chars, "?:\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz01234\
+\\abcdefghijklmnopqrstuvwxyz01234\\abcdefghijklmnopqrstuvwxyz0.e");
+_LIT(KExpectedFileName1, "?:\\dir\\name.e");
+_LIT(KExpectedSuffix1, "xt");
+_LIT(KExpectedFileName2, "?:\\abc\\defg.hij");
+_LIT(KExpectedSuffix2, "kl");
+_LIT(KTestFileName1French, "z:\\dir\\name.e02");
+_LIT(KTestFileName1Japanese, "z:\\dir\\name.e32");
+_LIT(KTestFileName1Mongolian, "z:\\dir\\name.e54321");
+_LIT(KTestFileName1AmericanSprint, "z:\\dir\\name.e1034"); //American=0x0A, Sprint=0x0400. 0x040A=1034.
+_LIT(KCheckedForFrench, "?:\\dir\\name.e02");
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0446
+@SYMTestCaseDesc Nearest language finder test
+@SYMTestPriority High
+@SYMTestActions Test drive sequence construction
+ Test addition of language number
+ Test searching each drive for the specified file
+ Test searching language and drive down the language path
+ Test filename matching
+ Test searching for any language file within a drive
+ Test searching all drives for any language
+@SYMTestExpectedResults Test must not fail
+@SYMREQ REQ0000
+*/
+void CT_LANGUTILSIMP::TestNearestLanguageFinder()
+ {
+ INFO_PRINTF1(_L(" @SYMTestCaseID:SYSLIB-BAFL-CT-0446 "));
+ RFs dummy;
+ TTestNearestLanguageFileFinder finder(dummy);
+
+ // Test file name setting and disecting
+ // SetFileName
+ // RepairFileName
+ TFileName fileName(KTestFileName1);
+ finder.SetFileName(fileName);
+ test(0 <= finder.iFileName->MatchF(KExpectedFileName1));
+ test(0 == finder.iSuffix.Compare(KExpectedSuffix1));
+ test('z' == finder.iInitialDriveLetter);
+ finder.RepairFileName();
+ test(0 == finder.iFileName->Compare(KTestFileName1));
+ fileName = KTestFileName11;
+ finder.SetFileName(fileName);
+ test(0 <= finder.iFileName->MatchF(KExpectedFileName2));
+ test(0 == finder.iSuffix.Compare(KExpectedSuffix2));
+ test(-1 == finder.iInitialDriveLetter);
+ finder.RepairFileName();
+ test(0 == finder.iFileName->Compare(KTestFileName11));
+ fileName = KTestFileName256Chars;
+ finder.SetFileName(fileName);
+ test(0 <= finder.iFileName->MatchF(KExpectedFileName256Chars));
+ test(0 == finder.iSuffix.Compare(KExpectedSuffix1));
+ test(-1 == finder.iInitialDriveLetter);
+ finder.RepairFileName();
+ test(0 == finder.iFileName->Compare(KTestFileName256Chars));
+
+ // Test drive sequence construction
+ // AddCustomResourceDrive
+ finder.iCustomRscDrive = static_cast<TInt>(EDriveC); // drive c:
+ fileName = KTestFileName1;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrNone);
+ test(0 == finder.iDrives.CompareF(_L("CZ")));
+ fileName = KTestFileName3;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrNone);
+ test(0 == finder.iDrives.CompareF(_L("CA")));
+ fileName = KTestFileName4;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrAlreadyExists);
+ test(0 == finder.iDrives.CompareF(_L("C")));
+ fileName = KTestFileName5;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrNone);
+ test(0 == finder.iDrives.CompareF(_L("CD")));
+ fileName = KTestFileName6;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrNone);
+ test(0 == finder.iDrives.CompareF(_L("CY")));
+ fileName = KTestFileName7;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrNone);
+ test(0 == finder.iDrives.CompareF(_L("CA")));
+ fileName = KTestFileName8;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrAlreadyExists);
+ test(0 == finder.iDrives.CompareF(_L("C")));
+ fileName = KTestFileName9;
+ finder.SetFileName(fileName);
+ test(finder.AddCustomResourceDrive() == KErrNone);
+ test(0 == finder.iDrives.CompareF(_L("CY")));
+ // AddAllDrives
+ fileName = KTestFileName1;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("ZYXWVUTSRQPONMLKJIHGFEDCBA")));
+ fileName = KTestFileName3;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("AYXWVUTSRQPONMLKJIHGFEDCBZ")));
+ fileName = KTestFileName4;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("CYXWVUTSRQPONMLKJIHGFEDBAZ")));
+ fileName = KTestFileName5;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("DYXWVUTSRQPONMLKJIHGFECBAZ")));
+ fileName = KTestFileName6;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("YXWVUTSRQPONMLKJIHGFEDCBAZ")));
+ fileName = KTestFileName7;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("AYXWVUTSRQPONMLKJIHGFEDCBZ")));
+ fileName = KTestFileName8;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("CYXWVUTSRQPONMLKJIHGFEDBAZ")));
+ fileName = KTestFileName9;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ test(0 == finder.iDrives.CompareF(_L("YXWVUTSRQPONMLKJIHGFEDCBAZ")));
+
+ // Test addition of language number
+ // AppendLanguageCode
+ fileName = KTestFileName1;
+ finder.SetFileName(fileName);
+ finder.AppendLanguageCode(ELangFrench);
+ test(0 == finder.iFileName->CompareF(KTestFileName1French));
+ finder.SetFileName(fileName);
+ finder.AppendLanguageCode(ELangJapanese);
+ test(0 == finder.iFileName->CompareF(KTestFileName1Japanese));
+ finder.SetFileName(fileName);
+ finder.AppendLanguageCode(ELangAmericanSprint);
+ test(0 == finder.iFileName->CompareF(KTestFileName1AmericanSprint));
+
+ fileName = KTestFileName1;
+ finder.SetFileName(fileName);
+ finder.AppendLanguageCode(static_cast<TLanguage>(54321));
+ test(0 == finder.iFileName->CompareF(KTestFileName1Mongolian));
+ fileName = KTestFileName256Chars;
+ finder.SetFileName(fileName);
+ test(!finder.AppendLanguageCode(ELangFrench));
+
+ // Test searching each drive for the specified file
+ // FindDrive
+ finder.iFileCheckedFor = KCheckedForFrench;
+ finder.iDrivesChecked = _L("D");
+ fileName = KTestFileName5;
+ finder.SetFileName(fileName);
+ finder.AppendLanguageCode(ELangFrench);
+ finder.FindDrive();
+ test(finder.iDrivesChecked.Length() == 0);
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ finder.iDrivesChecked = _L("dyxwvutsrqponmlkjihgfecbaz");
+ finder.AppendLanguageCode(ELangFrench);
+ finder.FindDrive();
+ test(finder.iDrivesChecked.Length() == 0);
+ fileName = KTestFileName5;
+ finder.SetFileName(fileName);
+ finder.AddAllDrives();
+ finder.iDrivesChecked = _L("dyxwvutsrqponmlkjihgfecbaz");
+ finder.AppendLanguageCode(ELangFrench);
+ finder.iFilesThatExist = new (ELeave) CDesCArraySeg(10);
+ finder.iFilesThatExist->AppendL(_L("o:\\dIR\\NAmE.E02"));
+ test(finder.FindDrive());
+ test(0 == finder.iFileName->CompareF(_L("O:\\dir\\name.e02")));
+ fileName = KTestFileName2;
+ finder.SetFileName(fileName);
+ finder.AppendLanguageCode(ELangFrench);
+ finder.AddAllDrives();
+ finder.iDrivesChecked = _L("zyxwvutsrqponmlkjihgfedcba");
+ finder.iFilesThatExist->AppendL(_L("v:\\dIR\\NA\x301mE.E02"));
+ //finder.iFileCheckedFor = _L("?:\\dir\\nÁme.e02");
+ finder.iFileCheckedFor = _L("?:\\dir\\n\u00c1me.e02");
+ test(finder.FindDrive());
+ //test(0 == finder.iFileName->CompareF(_L("v:\\dir\\nÁme.e02")));
+ test(0 == finder.iFileName->CompareF(_L("v:\\dir\\n\u00c1me.e02")));
+ delete finder.iFilesThatExist;
+ finder.iFilesThatExist = 0;
+
+ // Test searching language and drive down the language path
+ // FindLanguageAndDrive
+ finder.iPath[0] = static_cast<TLanguage>(2);
+ finder.iPath[1] = static_cast<TLanguage>(15702);
+ finder.iPath[2] = static_cast<TLanguage>(1);
+ finder.iPath[3] = ELangNone;
+ fileName = KTestFileName1;
+ finder.SetFileName(fileName);
+ SetUpFinderForLanguageAndDriveSearchL(finder);
+ finder.iFileCheckedFor = _L("?:\\dir\\name.e*");
+ test(!finder.FindLanguageAndDrive());
+ // check that iFileName is undamaged
+ finder.RepairFileName();
+ test(0 == finder.iFileName->CompareF(KTestFileName1));
+ delete finder.iFilesSearchedFor;
+ finder.iFilesThatExist = new (ELeave) CDesCArraySeg(10);
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e15702"));
+ fileName = KTestFileName1;
+ finder.SetFileName(fileName);
+ SetUpFinderForLanguageAndDriveSearchL(finder);
+ test(finder.FindLanguageAndDrive());
+ test(0 == finder.iFileName->CompareF(_L("a:\\dir\\name.e15702")));
+ delete finder.iFilesSearchedFor;
+ finder.iFilesSearchedFor = 0;
+
+ finder.iPath[0] = static_cast<TLanguage>(7);
+ finder.iPath[1] = ELangNone;
+ finder.iFilesThatExist->AppendL(_L("g:\\dir\\name.ext"));
+ fileName = KTestFileName1;
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("ZAG");
+ finder.iDrivesChecked = _L("ZAGZAG");
+ test(finder.FindLanguageAndDrive());
+ test(0 == finder.iFileName->CompareF(_L("g:\\dir\\name.ext")));
+ delete finder.iFilesThatExist;
+ finder.iFilesThatExist = 0;
+
+ // Test filename matching
+ // LanguageNumberFromFile
+ test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("AVB")));
+ //test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("ávb04"), _L("A\x301VB")));
+ //test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("a\x301vb04"), _L("ÁVB")));
+ test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("\u00e1vb04"), _L("A\x301VB")));
+ test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("a\x301vb04"), _L("\u00c1VB")));
+ test(5254 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb5254"), _L("aVb")));
+ test(KErrNotFound == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("avb04")));
+ test(KErrNotFound == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("av")));
+ test(KErrNotFound == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb04"), _L("")));
+ test(0 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb0000000"), _L("AVB00000")));
+ test(4 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb000000004"), _L("AVB0000000")));
+ test(100004 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb000100004"), _L("AVB000")));
+ test(111114 == TNearestLanguageFileFinder::LanguageNumberFromFile(_L("avb0111114"), _L("AVB0")));
+
+ // Test searching for any language file within a drive
+ // FindFirstLanguageFile
+ fileName = KTestFileName3;
+ finder.SetFileName(fileName);
+ finder.iFilesThatExist = new (ELeave) CDesCArraySeg(10);
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e107"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e07"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e02"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.ee01"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.01"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name01"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name01.e01"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e15108"));
+ finder.iFilesThatExist->AppendL(_L("a:\\dir\\name.e03"));
+ finder.iTestScanner.iDriveError[0] = KErrNoMemory;
+ fileName = KTestFileName3;
+ finder.SetFileName(fileName);
+ test(KErrNotFound == finder.FindFirstLanguageFile(dummy));
+ finder.iTestScanner.iDriveError[0] = KErrAbort;
+ fileName = KTestFileName3;
+ finder.SetFileName(fileName);
+ test(KErrNotFound == finder.FindFirstLanguageFile(dummy));
+ finder.iTestScanner.iDriveError[0] = KErrNone;
+ fileName = KTestFileName3;
+ finder.SetFileName(fileName);
+ test(0 <= finder.FindFirstLanguageFile(dummy));
+ test(0 == finder.iFileName->CompareF(_L("a:\\dir\\name.e02")));
+
+ finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.100"));
+ finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.9539"));
+ finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.19539"));
+ finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.1000"));
+ finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.102"));
+ fileName = _L("a:\\abcdefg.xx");
+ finder.SetFileName(fileName);
+ test(0 <= finder.FindFirstLanguageFile(dummy));
+ test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+ finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.aaa100"));
+ finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.0523")); // not well-formed. Will not count.
+ finder.iFilesThatExist->AppendL(_L("a:\\abcdefg.1001"));
+ fileName = _L("a:\\abcdefg.xx");
+ finder.SetFileName(fileName);
+ test(0 <= finder.FindFirstLanguageFile(dummy));
+ test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+ fileName = _L("a:\\abaffafg.xx");
+ finder.SetFileName(fileName);
+ test(0 <= finder.FindFirstLanguageFile(dummy));
+ test(0 == finder.iFileName->CompareF(_L("a:\\abaffafg.100")));
+ finder.iFilesThatExist->AppendL(_L("a:\\abaffafg.09"));
+ fileName = _L("a:\\abaffafg.xx");
+ finder.SetFileName(fileName);
+ test(0 <= finder.FindFirstLanguageFile(dummy));
+ test(0 == finder.iFileName->CompareF(_L("a:\\abaffafg.09")));
+
+ // Test searching all drives for any language
+ // FindFirstLanguageFileAndDrive
+ finder.iFilesThatExist->AppendL(_L("z:\\abcdefg.05"));
+ fileName = _L("c:\\abcdefg.xx");
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("az");
+ test(0 <= finder.FindFirstLanguageFileAndDrive());
+ test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+ fileName = _L("c:\\abaffafg.xx");
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("az");
+ test(0 <= finder.FindFirstLanguageFileAndDrive());
+ test(0 == finder.iFileName->CompareF(_L("a:\\abaffafg.09")));
+ fileName = _L("c:\\abcdefg.xx");
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("za");
+ test(0 <= finder.FindFirstLanguageFileAndDrive());
+ test(0 == finder.iFileName->CompareF(_L("z:\\abcdefg.05")));
+ fileName = _L("c:\\xxx.xx");
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("za");
+ test(KErrNotFound == finder.FindFirstLanguageFileAndDrive());
+ finder.iTestScanner.iDriveError[25] = KErrAbort;
+ fileName = _L("c:\\abcdefg.xx");
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("za");
+ test(0 <= finder.FindFirstLanguageFileAndDrive());
+ test(0 == finder.iFileName->CompareF(_L("a:\\abcdefg.1000")));
+ fileName = _L("c:\\abcdefg.xx");
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("za");
+ finder.iTestScanner.iDriveError[0] = KErrNoMemory;
+ test(KErrNotFound == finder.FindFirstLanguageFileAndDrive());
+ fileName = _L("c:\\abcdefg.xx");
+ finder.SetFileName(fileName);
+ finder.iDrives = _L("za");
+ finder.iTestScanner.iDriveError[0] = KErrAbort;
+ test(KErrNotFound == finder.FindFirstLanguageFileAndDrive());
+
+ }
+
+
+
+
+
+void CT_LANGUTILSIMP::TestLANGUTILSIMP()
+ {
+ __UHEAP_MARK;
+
+ INFO_PRINTF1(_L("LangUtils Internal Tests: "));
+
+ TestAddLanguage();
+ TestMakeLanguageDowngradePath();
+ TestNearestLanguageFinder();
+
+
+
+ __UHEAP_MARKENDC(0);
+ }
+
+CT_LANGUTILSIMP::CT_LANGUTILSIMP()
+ {
+ SetTestStepName(KTestStep_T_LANGUTILSIMP);
+ }
+
+TVerdict CT_LANGUTILSIMP::doTestStepL()
+ {
+ SetTestStepResult(EFail);
+
+ __UHEAP_MARK;
+
+ TRAPD(error1, TestLANGUTILSIMP());
+
+ __UHEAP_MARKEND;
+
+ if(error1 == KErrNone )
+ {
+ SetTestStepResult(EPass);
+ }
+
+ return TestStepResult();
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsImp.mmp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,38 @@
+// Copyright (c) 1997-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:
+//
+// Tests some code internal to BaflUtils
+//
+//
+
+target T_LangUtilsImp.exe
+targettype EXE
+
+userinclude ../src
+userinclude ../inc
+userinclude ../tsrc
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+
+
+sourcepath ../tsrc
+source T_LangUtilsImp.cpp
+source T_LangUtilsTestShareFunc.cpp
+
+STATICLIBRARY langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+
+
+VENDORID 0x70000001
+
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsLang.cpp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,310 @@
+// Copyright (c) 1997-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:
+//
+#include <f32file.h>
+#include <hal.h>
+#include <e32std.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+#include "t_langutilslang.h"
+
+#define test(cond) \
+ { \
+ TBool __bb = (cond); \
+ TEST(__bb); \
+ if (!__bb) \
+ { \
+ ERR_PRINTF1(_L("ERROR: Test Failed")); \
+ User::Leave(1); \
+ } \
+ }
+
+
+LOCAL_D RFs TheFs;
+
+// Our test diectory and files...
+
+_LIT (KNullFilename, "");
+_LIT (KRscFilename, "C:\\abc.rsc");
+_LIT (KRscFilenameNoSuffix, "C:\\abc.");
+
+_LIT (KAmericanLang, "C:\\abc.r10");
+_LIT (KFrenchLang, "C:\\abc.r02");
+_LIT (KJapanEnglishLang, "C:\\abc.r160");
+_LIT (KEnglishLang, "C:\\abc.r01");
+
+LOCAL_C void DeleteTestFiles()
+{
+ User::LeaveIfError (TheFs.Connect ());
+ ::CleanupClosePushL (TheFs);
+
+ LangUtilsTest::DeleteFile (TheFs, KRscFilename);
+ LangUtilsTest::DeleteFile (TheFs, KAmericanLang);
+ LangUtilsTest::DeleteFile (TheFs, KFrenchLang);
+ LangUtilsTest::DeleteFile (TheFs, KJapanEnglishLang);
+ LangUtilsTest::DeleteFile (TheFs, KEnglishLang);
+
+ CleanupStack::PopAndDestroy (&::TheFs);
+}
+
+
+
+void CT_LANGUTILSLANG::CreateTestFiles()
+{
+ User::LeaveIfError (TheFs.Connect ());
+ ::CleanupClosePushL (TheFs);
+ test (LangUtilsTest::FileExists (TheFs, KRscFilename) == EFalse);
+ test (LangUtilsTest::FileExists (TheFs, KAmericanLang) == EFalse);
+ test (LangUtilsTest::FileExists (TheFs, KFrenchLang) == EFalse);
+ test (LangUtilsTest::FileExists (TheFs, KJapanEnglishLang) == EFalse);
+ test (LangUtilsTest::FileExists (TheFs, KEnglishLang) == EFalse);
+
+ // Create the files...
+ RFile rFile;
+ // KFilename1 can't be created
+ rFile.Create (TheFs, KRscFilename, EFileRead);
+ rFile.Close ();
+ rFile.Create (TheFs, KAmericanLang, EFileRead);
+ rFile.Close ();
+ rFile.Create (TheFs, KFrenchLang, EFileRead);
+ rFile.Close ();
+
+ CleanupStack::PopAndDestroy (&::TheFs);
+
+}
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0070
+@SYMTestCaseDesc Tests the configuration of the ideal language.
+@SYMTestPriority High
+@SYMTestActions Set the ideal language and look for nearest language files.
+@SYMTestExpectedResults The test must not fail.
+@SYMREQ 3770: Configurable "ideal language" in LangUtil::NearestLanguageFile.
+*/
+void CT_LANGUTILSLANG::TestIdeaLang()
+ {
+ INFO_PRINTF1 (_L (" @SYMTestCaseID SYSLIB-BAFL-CT-0070 TestIdeaLang "));
+
+ __UHEAP_MARK;
+
+ User::LeaveIfError (TheFs.Connect ());
+ ::CleanupClosePushL (TheFs);
+
+ TBuf <256> filename;
+ TLanguage language;
+
+ // Test ideal language code
+
+ // Check initial value of ideal language
+
+ language=LangUtil::IdealLanguage();
+ test(language == ELangNone);
+
+ // Set and read back the ideal language
+
+ LangUtil::SetIdealLanguage( ELangGerman);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangGerman);
+
+ LangUtil::SetIdealLanguage( ELangAmerican);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangAmerican);
+
+ // Test NearestLanguageFile with empty name
+ TFileName resPath;
+ LangUtil::NearestLanguageFile (TheFs, resPath);
+ test(resPath.Length()==0);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for the null file - %S - is - %S -\n"), &KNullFilename, &filename);
+
+ // Test NearestLanguageFile with no suffix
+ filename.Copy (KRscFilenameNoSuffix);
+ LangUtil::NearestLanguageFile (TheFs, filename);
+ test(filename==KRscFilenameNoSuffix);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilenameNoSuffix, &filename);
+
+ // Test NearestLanguageFile
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+ test(filename == KAmericanLang);
+
+ // Set ideal language to one we don't have
+ LangUtil::SetIdealLanguage( ELangGerman);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangGerman);
+
+ // Test NearestLanguageFile
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+ test(filename == KRscFilename);
+
+ // Restore ideal language to default
+ LangUtil::SetIdealLanguage( ELangNone);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangNone);
+
+ // Test NearestLanguageFile
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+ test(filename == KRscFilename);
+
+ // Set ideal language to French
+
+ LangUtil::SetIdealLanguage( ELangFrench);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangFrench);
+
+ // Test NearestLanguageFile
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename);
+ INFO_PRINTF3 (_L ("The NearestLanguageFile for %S is %S\n"), &KRscFilename, &filename);
+ test(filename == KFrenchLang);
+
+ // Restore ideal language to default
+ LangUtil::SetIdealLanguage( ELangNone);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangNone);
+
+ // Release ideal language - free's TLS
+
+ LangUtil::ReleaseIdealLanguage();
+
+ CleanupStack::PopAndDestroy (&::TheFs);
+
+ __UHEAP_MARKEND;
+ }
+
+/**
+@SYMTestCaseID SYSLIB-BAFL-CT-0071
+@SYMTestCaseDesc Tests the overload of LangUtil::NearestLanguageFile.
+@SYMTestPriority High
+@SYMTestActions Calls the overload of LangUtil::NearestLanguageFile and checks the returned language.
+@SYMTestExpectedResults The test must not fail.
+@SYMREQ 3785: Overload of LangUtil::NearestLanguageFile.
+*/
+void CT_LANGUTILSLANG::TestNearestLang()
+ {
+ INFO_PRINTF1 (_L (" @SYMTestCaseID SYSLIB-BAFL-CT-0071 TestNearestLang "));
+
+ __UHEAP_MARK;
+
+ User::LeaveIfError (TheFs.Connect ());
+ ::CleanupClosePushL (TheFs);
+
+ TBuf <256> filename;
+ TLanguage language;
+
+ // Ensure that ideal language is default
+ LangUtil::SetIdealLanguage( ELangNone);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangNone);
+
+ // Test NearestLanguageFile overload with language returned
+ language=ELangAmerican;
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename, language);
+ INFO_PRINTF4(_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+ test(language == ELangNone);
+ test(filename == KRscFilename);
+
+ // Set ideal language to American
+
+ LangUtil::SetIdealLanguage( ELangAmerican);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangAmerican);
+
+ // Test NearestLanguageFile overload with language returned
+ language=ELangNone;
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename, language);
+ INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+ test(language == ELangAmerican);
+ test(filename == KAmericanLang);
+
+ // Set ideal language to French
+
+ LangUtil::SetIdealLanguage( ELangFrench);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangFrench);
+
+ // Test NearestLanguageFile overload with language returned
+ language=ELangNone;
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename, language);
+ INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+ test(language == ELangFrench);
+ test(filename == KFrenchLang);
+
+ // Set ideal language to one we don't have
+ LangUtil::SetIdealLanguage( ELangGerman);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangGerman);
+
+ // Test NearestLanguageFile overload with language returned
+ language=ELangAmerican;
+ filename.Copy (KRscFilename);
+ LangUtil::NearestLanguageFile (TheFs, filename, language);
+ INFO_PRINTF4 (_L ("The NearestLanguageFile for %S is %S, language = %d\n"), &KRscFilename, &filename, language);
+ test(language == ELangNone);
+ test(filename == KRscFilename);
+
+ // Restore ideal language to default
+ LangUtil::SetIdealLanguage( ELangNone);
+ language=LangUtil::IdealLanguage();
+ test(language == ELangNone);
+
+ // Release ideal language - free's TLS
+
+ LangUtil::ReleaseIdealLanguage();
+
+ CleanupStack::PopAndDestroy (&::TheFs);
+
+ __UHEAP_MARKEND;
+ }
+
+
+void CT_LANGUTILSLANG::TestLANGUTILSLANG ()
+ {
+ CreateTestFiles();
+ TestIdeaLang ();
+ TestNearestLang ();
+ DeleteTestFiles();
+ }
+
+CT_LANGUTILSLANG::CT_LANGUTILSLANG()
+ {
+ SetTestStepName(KTestStep_T_LANGUTILSLANG);
+ }
+
+TVerdict CT_LANGUTILSLANG::doTestStepL()
+ {
+ SetTestStepResult(EFail);
+
+ __UHEAP_MARK;
+
+ TRAPD(error1, TestLANGUTILSLANG());
+
+ __UHEAP_MARKEND;
+
+ if(error1 == KErrNone )
+ {
+ SetTestStepResult(EPass);
+ }
+
+ return TestStepResult();
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsLang.mmp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,33 @@
+// Copyright (c) 1997-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:
+//
+//
+
+target T_LangUtilsLang.exe
+targettype exe
+
+OS_LAYER_SYSTEMINCLUDE_SYMBIAN
+userinclude ../inc
+userinclude ../src
+userinclude ../tsrc
+
+SOURCEPATH .
+source T_LangUtilsLang.cpp
+source T_LangUtilsTestShareFunc.cpp
+
+STATICLIBRARY langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+VENDORID 0x70000001
+
+SMPSAFE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsServer.mmp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,31 @@
+TARGET t_langutilsserver.exe
+TARGETTYPE exe
+UID 0x1000007A 0xE27AD85E
+//UID 0 0xE27AD85D
+
+CAPABILITY ProtServ WriteDeviceData
+
+
+SOURCEPATH ../tsrc
+userinclude ../inc
+userinclude ../src
+userinclude ../tsrc
+
+OS_LAYER_LIBC_SYSTEMINCLUDE
+APP_LAYER_SYSTEMINCLUDE
+
+SOURCE t_langutilsserver.cpp
+source T_LangUtilsTestShareFunc.cpp
+source T_LangUtils.cpp
+source T_LangUtilsImp.cpp
+source T_LangUtilsLang.cpp
+
+
+STATICLIBRARY langutil.lib
+library euser.lib hal.lib efsrv.lib estor.lib centralrepository.lib
+LIBRARY testexecuteutils.lib
+LIBRARY testexecutelogclient.lib
+
+#ifdef ENABLE_ABIV2_MODE
+DEBUGGABLE_UDEBONLY
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsTestShareFunc.cpp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,408 @@
+// Copyright (c) 1997-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:
+//
+
+#include <langutil.h>
+#include "T_LangUtilsTestShareFunc.h"
+
+void DoCopyFileL(RFs& aFs, const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch)
+ {
+ CFileMan* fileMan=CFileMan::NewL(aFs);
+ CleanupStack::PushL(fileMan);
+ User::LeaveIfError(fileMan->Copy(aSourceFullName,aTargetFullName,aSwitch));
+ CleanupStack::PopAndDestroy(); // fileMan
+ }
+
+
+TInt LangUtilsTest::CopyFile(RFs& aFs, const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch)
+/** Copies one or more files.
+
+For more details,
+@see CFileMan::Copy()
+@since 5.1
+@param aFs File server session
+@param aSourceFullName Path indicating the file(s) to be copied. Any path
+components that are not specified here will be taken from the session path.
+@param aTargetFullName Path indicating the directory into which the file(s)
+are to be copied
+@param aSwitch=CFileMan::EOverWrite Set this to zero for no overwriting and
+no recursion; CFileMan::EOverWrite to overwrite files with the same name; or
+CFileMan::ERecurse for recursion.
+@return KErrNone if successful, otherwise another of the system-wide error
+codes.*/
+ {
+ TRAPD(err,DoCopyFileL(aFs,aSourceFullName,aTargetFullName,aSwitch));
+ return err;
+ }
+
+TBool LangUtilsTest::FileExists(const RFs& aFileSession,const TDesC& aFileName)
+/** Checks if the specified file exists.
+
+@param aFs File server session
+@param aFileName File to check
+@return ETrue if the file exists, otherwise EFalse */
+ { // static
+ TEntry entry;
+ return(aFileSession.Entry(aFileName,entry)==KErrNone);
+ }
+
+void DoDeleteFileL(RFs& aFs, const TDesC& aSourceFullName, TUint aSwitch)
+ {
+ CFileMan* fileMan=CFileMan::NewL(aFs);
+ CleanupStack::PushL(fileMan);
+ User::LeaveIfError(fileMan->Delete(aSourceFullName,aSwitch));
+ CleanupStack::PopAndDestroy(); // fileMan
+ }
+
+
+EXPORT_C TInt LangUtilsTest::DeleteFile(RFs& aFs, const TDesC& aSourceFullName, TUint aSwitch)
+/** Deletes one or more files.
+
+For more details,
+@see CFileMan::Delete().
+@since 5.1
+@param aFs File server session
+@param aSourceFullName Path indicating the file(s) to be deleted. May either
+be a full path, or relative to the session path. Use wildcards to specify
+more than one file.
+@param aSwitch=0 Specify CFileMan::ERecurse for recursion,
+zero for no recursion.
+@return KErrNone if successful, otherwise another of the system-wide error
+codes. */
+ {
+ TRAPD(err,DoDeleteFileL(aFs,aSourceFullName,aSwitch));
+ return err;
+ }
+
+NONSHARABLE_CLASS(TKeyDesC16Array) : public TKeyArrayFix
+ {
+public:
+ TKeyDesC16Array(TKeyCmpText aType);
+private: // from TKey
+ TInt Compare(TInt aLeft,TInt aRight) const;
+ };
+
+TKeyDesC16Array::TKeyDesC16Array(TKeyCmpText aType)
+ : TKeyArrayFix(0,aType,0)
+ {
+ }
+
+TInt TKeyDesC16Array::Compare(TInt aLeft,TInt aRight) const
+ {
+ TDesC16* left=(*(TDesC16**)At(aLeft));
+ TDesC16* right=(*(TDesC16**)At(aRight));
+ switch (iCmpType)
+ {
+ case ECmpFolded:
+ return(left->CompareF(*right));
+ case ECmpCollated:
+ return(left->CompareC(*right));
+ default:
+ break;
+ }
+ return(left->Compare(*right));
+ }
+
+EXPORT_C CDesC16Array::CDesC16Array(TBufRep aRep,TInt aGranularity)
+ : CArrayFixBase(aRep,sizeof(HBufC16*),aGranularity)
+ {
+ }
+
+EXPORT_C CDesC16Array::~CDesC16Array()
+/** Frees all resources owned by the object, prior to its destruction. In particular,
+it deletes all descriptors from the array and frees the memory allocated to
+the array buffer. */
+ {
+ Reset();
+ }
+
+EXPORT_C void CDesC16Array::Reset()
+/** Deletes all descriptors from the array and frees the memory allocated to the
+array buffer.
+
+@see CDesC16Array::Delete() */
+ {
+ Delete(0,Count());
+ }
+
+EXPORT_C void CDesC16Array::Delete(TInt aIndex)
+ {
+ Delete(aIndex,1);
+ }
+
+/**
+ *
+ * Deletes one or more logically contiguous descriptor elements from the
+ * array.
+ *
+ * The deletion starts at the specified position.Deleting descriptor
+ * elements from the array frees the memory occupied by the associated
+ * heap descriptors and removes their pointers from the array buffer but
+ * does not cause the array buffer to be automatically compressed. Call
+ * the Compress() function to return excess space in the array buffer to
+ * the heap.
+ *
+ * @param " TInt aPos "
+ * The starting position in the array from which
+ * descriptor elements are to be deleted. The position is
+ * relative to zero, i.e. zero implies the first
+ * descriptor element. This value must not be negative
+ * and must not be greater than the number of descriptor
+ * elements currently in the array, otherwise the
+ * functions raise an E32USER-CBase 21 panic.
+ * @param " TInt aCount "
+ * If specified, the number of contiguous descriptor
+ * elements to be deleted from the array. This value must
+ * not be negative otherwise the function raises an
+ * E32USER-CBase 22 panic. This value must not be
+ * negative otherwise the function raises an
+ * E32USER-CBase 22 panic. This value must not be
+ * negative otherwise the function raises an
+ * E32USER-CBase 22 panic. This value plus the value of
+ * the starting position must not be greater than the
+ * number of descriptor elements in the array, otherwise
+ * the function raises an E32USER-CBase 29 panic. If not
+ * specified, one element is assumed.
+ */
+EXPORT_C void CDesC16Array::Delete(TInt aIndex,TInt aCount)
+ {
+ TInt count=aCount;
+ for (TInt ii=aIndex; count--; ii++)
+ User::Free(*(HBufC16**)At(ii));
+ CArrayFixBase::Delete(aIndex,aCount);
+ }
+
+EXPORT_C TInt CDesC16Array::MdcaCount() const
+/** Returns the number of descriptor elements in the array. The function implements
+the function interface MDesC16Array::MdcaCount().
+
+@return The number of descriptor elements. */
+ {
+ return Count();
+ }
+
+EXPORT_C TPtrC16 CDesC16Array::MdcaPoint(TInt anIndex) const
+/** Indexes into a descriptor array. The function implements the interface MDesC16Array::MdcaPoint().
+
+ @param aIndex The position of the descriptor element within the array. The
+ position is relative to zero; i.e. zero implies the first descriptor element
+ in the array. This value must be non-negative and less than the number of
+ descriptors currently within the array otherwise the operator panics with
+ EArrayIndexOutOfRange.
+ @return A non-modifiable pointer descriptor representing the descriptor element
+ located at position aIndex within the array. */
+ {
+ HBufC16* temp=(*(HBufC16**)At(anIndex));
+ return (TPtrC16)(*temp);
+ }
+
+EXPORT_C void CDesC16Array::AppendL(const TDesC16& aPtr)
+/** Appends a descriptor onto the end of any existing descriptor elements in the
+array.
+
+@param aPtr A reference to the descriptor to be appended to the array. */
+ {
+ InsertL(Count(),aPtr);
+ }
+
+EXPORT_C void CDesC16Array::InsertL(TInt aPos,const TDesC16& aPtr)
+/** Inserts a descriptor into the array at the specified position.
+
+If the specified position is the same as the current number of descriptor
+elements in the array, this has the effect of appending the element.
+
+@param aPos The position within the array where the descriptor element is
+to be inserted. The position is relative to zero, i.e. zero implies the first
+descriptor element. This value must not be negative and must not be greater
+than the number of descriptor elements currently in the array, otherwise the
+function raises an E32USER-CBase 21 panic.
+@param aPtr The descriptor to be inserted into the array. */
+ {
+ HBufC16* bufPtr=aPtr.AllocLC();
+ CArrayFixBase::InsertL(aPos,&bufPtr);
+ CleanupStack::Pop();
+ }
+
+EXPORT_C TInt CDesC16Array::InsertIsqL(const TDesC16& aPtr,TKeyCmpText aTextComparisonType)
+/** Inserts a descriptor into the array at a position which maintains the sequence
+of the descriptors.
+
+The sequence is determined by comparing descriptors using one of the TDesC
+comparison functions. The enumeration aTextComparisonType governs how the
+descriptors are to be compared.
+
+The array should already be in sequence, otherwise the position of the new
+descriptor element is unpredictable. Descriptor elements which are the same
+are not permitted.
+
+@param aPtr A reference to the descriptor to be inserted into the array.
+@param aTextComparisonType An enumeration which determines the type of comparison
+to be made between descriptors for the purpose of choosing the insertion position.
+If no parameter is explicitly passed, ECmpFolded is used by default.
+@return The position within the array of the inserted descriptor. */
+ {
+ HBufC16* bufPtr=aPtr.AllocLC();
+ TKeyDesC16Array key(aTextComparisonType);
+ TInt found=CArrayFixBase::InsertIsqL(&bufPtr,key);
+ CleanupStack::Pop();
+ return(found);
+ }
+
+EXPORT_C TInt CDesC16Array::InsertIsqAllowDuplicatesL(const TDesC16& aPtr,TKeyCmpText aTextComparisonType)
+/** Inserts a descriptor into the array at a position which maintains the sequence
+of the descriptors; allows duplicates.
+
+The sequence is determined by comparing descriptors using one of the TDesC
+comparison functions. The enumeration aTextComparisonType governs how the
+descriptors are to be compared.
+
+The array should already be in sequence, otherwise the position of the new
+descriptor element is unpredictable. Descriptor elements which are the same
+are permitted; if the descriptor aPtr is a duplicate of an existing descriptor
+within the array, then the new descriptor element is positioned after the
+existing descriptor element.
+
+@param aPtr A reference to the descriptor to be inserted into the array.
+@param aTextComparisonType An enumeration which determines the type of comparison
+to be made between descriptors for the purpose of choosing the insertion position.
+If no parameter is explicitly passed, ECmpFolded is used by default.
+@return The position within the array of the inserted descriptor. */
+ {
+ HBufC16* bufPtr=aPtr.AllocLC();
+ TKeyDesC16Array key(aTextComparisonType);
+ TInt found=CArrayFixBase::InsertIsqAllowDuplicatesL(&bufPtr,key);
+ CleanupStack::Pop();
+ return(found);
+ }
+
+EXPORT_C void CDesC16Array::Sort(TKeyCmpText aTextComparisonType)
+/** Sorts the descriptor elements into sequence.
+
+The sequence is determined by comparing descriptors using one of the member
+functions of the descriptor base class TDesC.
+
+@param aTextComparisonType An enumeration which defines the type of comparison
+to be made between descriptors. By default the comparison type is ECmpFolded. */
+ {
+ TKeyDesC16Array key(aTextComparisonType);
+ CArrayFixBase::Sort(key);
+ }
+
+EXPORT_C TInt CDesC16Array::Find(const TDesC16& aPtr,TInt& aPos,TKeyCmpText aTextComparisonType) const
+/** Finds the position of a descriptor element within the array which matches the
+specified descriptor, using a sequential search.
+
+The array is searched sequentially for a matching descriptor element, starting
+with the first descriptor element in the array. Descriptors are compared using
+one of the TDesC comparison functions. The enumeration aTextComparisonType
+governs how the descriptors are to be compared.
+
+Where an array has duplicate descriptor elements, the function only supplies
+the position of the first descriptor element.
+
+@param aPtr A reference to a descriptor to be used for comparison.
+@param aPos If the descriptor element is found, this reference is set to the
+position of that descriptor element within the array. The position is relative
+to zero, (i.e. the first descriptor element in the array is at position 0).
+If the descriptor element is not found and the array is not empty, then the
+value of the reference is set to the number of descriptor elements in the
+array. If the descriptor element is not found and the array is empty, then
+the reference is set to zero.
+@param aTextComparisonType An enumeration which determines the type of comparison
+to be made between descriptors. If no parameter is explicitly passed,ECmpFolded
+is used by default.
+@return Zero, if a matching descriptor element is found. Non-zero, if no matching
+descriptor element can be found. */
+ {
+ TKeyDesC16Array key(aTextComparisonType);
+ const TDesC16* tmp=(&aPtr);
+ return(CArrayFixBase::Find(&tmp,key,aPos));
+ }
+
+EXPORT_C TInt CDesC16Array::FindIsq(const TDesC16& aPtr,TInt& aPos,TKeyCmpText aTextComparisonType) const
+/** Finds the position of a descriptor element within the array which matches the
+specified descriptor, using a binary search technique. The array must
+be in sequence, otherwise the outcome is unpredictable.
+
+Descriptors are compared using one of the TDesC comparison functions. The
+enumeration aTextComparisonType governs how the descriptors are to be compared.
+
+Where an array has duplicate descriptor elements, the function cannot guarantee
+which matching descriptor element it will return; except that it will find
+one of them.
+
+@param aPtr A reference to a descriptor to be used for comparison.
+@param aPos If the descriptor element is found, the reference is set to the
+position of that descriptor element within the array. The position is relative
+to zero, (i.e. the first descriptor element in the array is at position 0).
+If the descriptor element is not found and the array is not empty, then the
+reference is set to the position of the first descriptor element in the array
+whose content is greater than the content of aPtr. If the descriptor element
+is not found and the array is empty, then the reference is set to zero.
+@param aTextComparisonType An enumeration which determines the type of comparison
+to be made between descriptors. If no parameter is explicitly passed, ECmpFolded
+is used by default.
+@return Zero, if a matching descriptor element is found. Non-zero, if no matching
+descriptor element can be found. */
+ {
+ TKeyDesC16Array key(aTextComparisonType);
+ const TDesC16* tmp=(&aPtr);
+ return(CArrayFixBase::FindIsq(&tmp,key,aPos));
+ }
+
+
+EXPORT_C CDesC16ArraySeg::CDesC16ArraySeg(TInt aGranularity)
+ : CDesC16Array((TBufRep)CBufSeg::NewL,aGranularity)
+/** Construct a segmented descriptor array with the specified granularity.
+
+No memory is allocated to the array buffer by this C++ constructor.
+
+@param aGranularity The granularity of the array. This value must be positive
+otherwise the constructor raises an E32USER-CBase 18 panic. */
+ {
+ __DECLARE_NAME(_S("CDesC16ArraySeg"));
+ }
+
+EXPORT_C CDesC16ArraySeg::~CDesC16ArraySeg()
+/** Frees all resources owned by the object, prior to its destruction. */
+ {}
+
+
+/* The following 3 function is defined so that the functions IdealLanguage,
+SetIdealLanguage, ReleaseIdealLanguage will compile as part as an .exe
+These functions use a global TAny* to store the data that would have been
+stored in the TLS under normal compilation (ie If the BaUtils was compilled
+as part of a DLL).
+*/
+
+TAny* ptr(NULL);
+
+TAny* Dll::Tls()
+ {
+ return ptr;
+ }
+
+TInt Dll::SetTls(TAny* aPtr)
+ {
+ ptr = aPtr;
+ return KErrNone;
+ }
+
+void Dll::FreeTls()
+ {
+ ptr = NULL;
+ }
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_LangUtilsTestShareFunc.h Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,36 @@
+// Copyright (c) 1997-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:
+//
+
+#ifndef __T_LANGUTILS_TEST_SHAREFUNC_H__
+#define __T_LANGUTILS_TEST_SHAREFUNC_H__
+
+#include <e32std.h>
+#include <f32file.h>
+
+
+
+class LangUtilsTest
+ {
+public:
+ static TInt DeleteFile(RFs& aFs, const TDesC& aSourceFullName, TUint aSwitch = 0);
+ static TBool FileExists(const RFs& aFs,const TDesC& aFileName);
+ static TInt CopyFile(RFs& aFs, const TDesC& aSourceFullName, const TDesC& aTargetFullName, TUint aSwitch = CFileMan::EOverWrite);
+
+ };
+
+
+
+#endif // __T_LANGUTILS_TEST_SHAREFUNC_H__
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_langutils.script Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+PRINT Run T_LANGUTILS tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILS
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_langutilsimp.script Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+PRINT Run T_LANGUTILSIMP tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSIMP
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/T_langutilslang.script Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,4 @@
+PRINT Run T_LANGUTILSLANG tests
+//
+LOAD_SUITE T_LangUtilsServer
+RUN_TEST_STEP 100 T_LangUtilsServer T_LANGUTILSLANG
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file1.txt Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file123456789.txt Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file2.txt Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/file5.txt Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,1 @@
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutils.h Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,36 @@
+#ifndef __T_LANGUTILS_H__
+#define __T_LANGUTILS_H__
+
+//#include <w32std.h>
+#include <test/testexecutestepbase.h>
+#include <baclipb.h>
+#include <f32file.h>
+#include <s32strm.h>
+#include <s32file.h>
+#include <e32lang.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+
+class CT_LANGUTILS : public CTestStep
+ {
+public:
+ CT_LANGUTILS();
+protected:
+ TVerdict doTestStepL();
+private:
+ void TestLANGUTILS();
+ void TestGetDowngradePathL();
+ void TestGetEquivalentLanguageList();
+ void TestNearestLanguageFileV2(RFs& aFs);
+ void CopyTestFiles();
+ void CreateTestFiles2(RFs &aFs);
+ void DeleteTestFiles2(RFs &aFs);
+ void DeleteTestFiles();
+ void DeleteTestFile(const TDesC& aFullName);
+ void DeleteTestDir(const TDesC& aFullName);
+ };
+
+_LIT(KTestStep_T_LANGUTILS, "T_LANGUTILS");
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilsimp.h Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,136 @@
+#ifndef __T_LANGUTILSIMP_H__
+#define __T_LANGUTILSIMP_H__
+
+//#include <w32std.h>
+#include <test/testexecutestepbase.h>
+#include <langutil.h>
+#include "LangUtilImpl.h"
+#include "T_LangUtilsTestShareFunc.h"
+
+struct SDowngradeTest
+ {
+ TLanguage iIn[4];
+ TLanguage iOut[9];
+ };
+
+class RTestDirectoryScanner : public RDirectoryScanner
+ {
+public:
+ RTestDirectoryScanner(CDesCArray*& aMember)
+ : iOpenError(0), iFilesThatExist(aMember)
+ {
+ for (TInt i = 0; i != 26; ++i)
+ iDriveError[i] = 0;
+ }
+ virtual TInt Open(RFs&, const TDesC& aMatchPattern)
+ {
+ iMatch = aMatchPattern;
+ iIndex = 0;
+ return iOpenError;
+ }
+ virtual TInt Next(TEntry& aOut)
+ {
+ if (!iFilesThatExist)
+ return KErrEof;
+ while (iIndex < iFilesThatExist->Count())
+ {
+ TInt i = iIndex++;
+ if (0 <= (*iFilesThatExist)[i].MatchF(iMatch))
+ {
+ TPtrC fullName=(*iFilesThatExist)[i];
+ TParsePtrC name(fullName);
+ aOut.iName=name.NameAndExt();
+ if (1 < fullName.Length() && fullName[1] == ':')
+ {
+ TInt drive = fullName[0];
+ if ('a' <= drive && drive <= 'z')
+ drive -= 'a';
+ else
+ {
+ ASSERT('A' <= drive && drive <= 'Z');
+ drive -= 'A';
+ }
+ return iDriveError[drive];
+ }
+ return KErrNone;
+ }
+ }
+ return KErrEof;
+ }
+ virtual void Close() {}
+ TInt iOpenError;
+ TInt iDriveError[26];
+private:
+ CDesCArray *&iFilesThatExist;
+ TInt iIndex;
+ TFileName iMatch;
+ };
+
+
+class TTestNearestLanguageFileFinder : public TNearestLanguageFileFinder
+ {
+public:
+ TTestNearestLanguageFileFinder(const RFs& aFs)
+ : TNearestLanguageFileFinder(aFs), iTestScanner(iFilesThatExist)
+ {
+ iFilesThatExist = 0;
+ iFilesSearchedFor = 0;
+ }
+ ~TTestNearestLanguageFileFinder()
+ {
+ delete iFilesThatExist;
+ delete iFilesSearchedFor;
+ }
+ virtual TInt GetCustomResourceDriveNumber() const { return iCustomRscDrive; }
+ virtual TBool FileExists(const TDesC& aFileName) const
+ {
+ ASSERT(aFileName[1] == ':');
+ ASSERT(0 == aFileName.Left(1).CompareF(iDrivesChecked.Left(1)));
+ iDrivesChecked.Delete(0, 1);
+ ASSERT(0 <= aFileName.MatchF(iFileCheckedFor));
+ if (iFilesSearchedFor)
+ {
+ ASSERT(0 == aFileName.CompareF((*iFilesSearchedFor)[0]));
+ iFilesSearchedFor->Delete(0);
+ }
+ if (!iFilesThatExist)
+ return EFalse;
+ TInt i;
+ iFilesThatExist->Find(aFileName, i);
+ return (0 <= i && i < iFilesThatExist->Count())? ETrue : EFalse;
+ }
+ virtual RDirectoryScanner& DirectoryScanner() { return iTestScanner; }
+
+ TInt iCustomRscDrive;
+ CDesCArray* iFilesThatExist;
+ // File that is expected to go into FileExists.
+ // Can contain wildcards.
+ TFileName iFileCheckedFor;
+ // Drives expected in calls to FileExists. The first one is checked then
+ // discarded each time FileExists is called.
+ mutable TBuf<26> iDrivesChecked;
+ CDesCArray* iFilesSearchedFor;
+ RTestDirectoryScanner iTestScanner;
+ };
+
+
+class CT_LANGUTILSIMP : public CTestStep
+ {
+public:
+ CT_LANGUTILSIMP();
+protected:
+ TVerdict doTestStepL();
+private:
+ void TestLANGUTILSIMP();
+ void TestPath(const TLanguagePath& aPath, const TLanguage* aExpected, TInt aExpectedCount);
+ void TestAddLanguage();
+ void TestDowngrade(SDowngradeTest& aTest);
+ void TestMakeLanguageDowngradePath();
+ void SetUpFinderForLanguageAndDriveSearchL(TTestNearestLanguageFileFinder& aFinder);
+ void TestNearestLanguageFinder();
+
+ };
+
+_LIT(KTestStep_T_LANGUTILSIMP, "T_LANGUTILSIMP");
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilslang.h Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,22 @@
+#ifndef __T_LANGUTILSLANG_H__
+#define __T_LANGUTILSLANG_H__
+
+//#include <w32std.h>
+#include <test/testexecutestepbase.h>
+
+class CT_LANGUTILSLANG : public CTestStep
+ {
+public:
+ CT_LANGUTILSLANG();
+protected:
+ TVerdict doTestStepL();
+private:
+ void TestLANGUTILSLANG();
+ void TestNearestLang();
+ void TestIdeaLang();
+ void CreateTestFiles();
+ };
+
+_LIT(KTestStep_T_LANGUTILSLANG, "T_LANGUTILSLANG");
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilsserver.cpp Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,118 @@
+/*
+ ============================================================================
+ Name : t_TEF.cpp
+ Author : Yanchun Li
+ Copyright : Your copyright notice
+ Description : Exe source file
+ ============================================================================
+ */
+
+// Include Files
+
+#include "t_langutilsserver.h"
+#include "t_langutils.h"
+#include "t_langutilsimp.h"
+#include "t_langutilslang.h"
+
+
+/* Path to the script
+
+c:\z:\t_TEF\t_TEF_All.script
+
+*/
+
+_LIT(KServerName,"T_LangUtilsServer");
+
+CT_LangUtilsServer *CT_LangUtilsServer::NewL()
+/**
+ @return - Instance of the test server
+ Same code for Secure and non-secure variants
+ Called inside the MainL() function to create and start the
+ CTestServer derived server.
+ */
+ {
+ CT_LangUtilsServer * server = new (ELeave) CT_LangUtilsServer();
+ CleanupStack::PushL(server);
+ // CServer base class call
+ server->StartL(KServerName);
+ CleanupStack::Pop(server);
+ return server;
+ }
+
+
+LOCAL_C void MainL()
+//
+// Secure variant
+// Much simpler, uses the new Rendezvous() call to sync with the client
+//
+ {
+#if (defined __DATA_CAGING__)
+ RProcess().DataCaging(RProcess::EDataCagingOn);
+ RProcess().SecureApi(RProcess::ESecureApiOn);
+#endif
+ CActiveScheduler* sched=NULL;
+ sched=new(ELeave) CActiveScheduler;
+ CActiveScheduler::Install(sched);
+ CT_LangUtilsServer *server = NULL;
+ // Create the CTestServer derived server
+ TRAPD(err,server = CT_LangUtilsServer::NewL());
+ if(!err)
+ {
+ // Sync with the client and enter the active scheduler
+ RProcess::Rendezvous(KErrNone);
+ sched->Start();
+ }
+ delete server;
+ delete sched;
+ }
+
+/** @return - Standard Epoc error code on process exit
+ Secure variant only
+ Process entry point. Called by client using RProcess API
+*/
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ if(cleanup == NULL)
+ {
+ return KErrNoMemory;
+ }
+ TRAPD(err,MainL());
+ // This if statement is here just to shut up RVCT, which would otherwise warn
+ // that err was set but never used
+ if (err)
+ {
+ err = KErrNone;
+ }
+ delete cleanup;
+ __UHEAP_MARKEND;
+ return KErrNone;
+ }
+
+CTestStep *CT_LangUtilsServer::CreateTestStep(const TDesC& aStepName)
+/**
+ @return - A CTestStep derived instance
+ Secure and non-secure variants
+ Implementation of CTestServer pure virtual
+ */
+ {
+
+ if(aStepName == KTestStep_T_LANGUTILS)
+ {
+ return new CT_LANGUTILS();
+ }
+ else if(aStepName == KTestStep_T_LANGUTILSIMP)
+ {
+ return new CT_LANGUTILSIMP();
+ }
+ else if(aStepName == KTestStep_T_LANGUTILSLANG)
+ {
+ return new CT_LANGUTILSLANG();
+ }
+
+
+
+ return NULL;
+ }
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textandlocutils/nearestlangutils/tsrc/t_langutilsserver.h Tue Sep 07 16:39:34 2010 +0800
@@ -0,0 +1,26 @@
+/*
+ ============================================================================
+ Name : T_LangUtilsServer.h
+ Author : Yanchun Li
+ Copyright : Your copyright notice
+ Description : Exe header file
+ ============================================================================
+ */
+
+#ifndef __T_LANGUTILSSERVER_H__
+#define __T_LANGUTILSSERVER_H__
+
+// Include Files
+
+#include <test/testexecuteserverbase.h>
+
+class CT_LangUtilsServer : public CTestServer
+ {
+public:
+ static CT_LangUtilsServer* NewL();
+//from CTestServer
+ virtual CTestStep* CreateTestStep(const TDesC& aStepName);
+ };
+
+#endif // __T_LANGUTILSSERVER_H__
+