class BaflUtils |
Provides simple-to-use file system utilities.
The functions listed in "Copying, renaming, and deleting files" create and use a CFileMan object. They are useful for one-off calls, but for repeated use it is more efficient to use CFileMan directly.
Note that there is a very similiar group of functions available in EikFileUtils, which may be easier to use in GUI applications, as they do not require a file server session to be passed.
CFileMan EikFileUtils
Private Member Functions | |
---|---|
void | DoCopyFileL ( RFs &, const TDesC &, const TDesC &, TUint ) |
void | DoDeleteFileL ( RFs &, const TDesC &, TUint ) |
void | DoRenameFileL ( RFs &, const TDesC &, const TDesC &, TUint ) |
IMPORT_C void | AbbreviateFileName | ( | const TFileName & | aOriginalFileName, |
TDes & | aAbbreviatedFileName | |||
) | [static] |
Abbreviates a file name.
If aOriginalFileName is less than the maximum length of aAbbreviatedFileName, then the name is simply copied to aAbbreviatedFileName.
If this is not so, then the left-most characters of aOriginalFileName are copied to aAbbreviatedFileName, up to aAbbreviatedFileName's maximum length-1. aAbbreviatedFileName's first character is set to be an ellipsis.
IMPORT_C TInt | CheckFolder | ( | RFs & | aFs, |
const TDesC & | aFolderName | |||
) | [static] |
Checks that the specified folder can be opened.
IMPORT_C TInt | CheckWhetherFullNameRefersToFolder | ( | const TDesC & | aFullName, |
TBool & | aIsFolder | |||
) | [static] |
Checks if a string is a valid folder name.
IMPORT_C TInt | CopyFile | ( | RFs & | aFs, |
const TDesC & | aSourceFullName, | |||
const TDesC & | aTargetFullName, | |||
TUint | aSwitch = CFileMan::EOverWrite | |||
) | [static] |
Copies one or more files.
RFs & aFs | File server session |
const TDesC & aSourceFullName | Path indicating the file(s) to be copied. Any path components that are not specified here will be taken from the session path. |
const TDesC & aTargetFullName | Path indicating the directory into which the file(s) are to be copied |
TUint aSwitch = CFileMan::EOverWrite |
IMPORT_C void | CopyWithTruncation | ( | TDes & | aDest, |
const TDesC & | aSrc, | |||
TChar | aTruncationSymbol = KBaflCharTruncation | |||
) | [static] |
TDes & aDest | |
const TDesC & aSrc | |
TChar aTruncationSymbol = KBaflCharTruncation |
IMPORT_C TInt | DeleteFile | ( | RFs & | aFs, |
const TDesC & | aSourceFullName, | |||
TUint | aSwitch = 0 | |||
) | [static] |
Deletes one or more files.
IMPORT_C TInt | DiskIsReadOnly | ( | RFs & | aFs, |
const TDesC & | aFullName, | |||
TBool & | aIsReadOnly | |||
) | [static] |
Checks if the specified drive is read-only. Checks that the KMediaAttWriteProtected and EMediaRom flags are both set.
void | DoCopyFileL | ( | RFs & | aFs, |
const TDesC & | aSourceFullName, | |||
const TDesC & | aTargetFullName, | |||
TUint | aSwitch | |||
) | [private, static] |
void | DoDeleteFileL | ( | RFs & | aFs, |
const TDesC & | aSourceFullName, | |||
TUint | aSwitch | |||
) | [private, static] |
void | DoRenameFileL | ( | RFs & | aFs, |
const TDesC & | aOldFullName, | |||
const TDesC & | aNewFullName, | |||
TUint | aSwitch | |||
) | [private, static] |
IMPORT_C TFileName | DriveAndPathFromFullName | ( | const TDesC & | aFullName | ) | [static] |
Gets the drive letter and path from a file name.
This is in the form: drive-letter:\path\. The drive letter is folded using class TCharF .
const TDesC & aFullName | File name |
IMPORT_C TInt | DriveIsReadOnlyInternal | ( | RFs & | aFs, |
const TDesC & | aFullName, | |||
TBool & | aIsReadOnlyInternal | |||
) | [static] |
Checks if the specified drive is read-only and is an internal drive i.e. non-removable. Checks that the KMediaAttWriteProtected and KDriveAttInternal flags are both set.
IMPORT_C void | EnsurePathExistsL | ( | RFs & | aFs, |
const TDesC & | aFileName | |||
) | [static] |
IMPORT_C TPtrC | ExtractAppNameFromFullName | ( | const TFullName & | aName | ) | [static] |
const TFullName & aName |
IMPORT_C TBool | FileExists | ( | const RFs & | aFs, |
const TDesC & | aFileName | |||
) | [static] |
IMPORT_C TBool | FolderExists | ( | RFs & | aFs, |
const TDesC & | aFolderName | |||
) | [static] |
Tests whether a folder exists.
The folder is specified in a path. The path can omit the drive letter, in which case the drive letter is taken from the session path.
If the path is badly formed, for instance if it contains illegal characters, or any directory name consists of a single or double dot, or any directory name includes wildcard characters, the function returns EFalse.
If a filename is included in the path, it is ignored (the existence of the file will not be checked). However if included, it must not be badly formed - this will cause the function to return EFalse. If no filename is specified, the path should end in a backslash.
Examples of valid paths (returning ETrue): C:\; \; C:.txt; C:\; .dat
Examples of invalid paths (returning EFalse): C:\; ..\; C:*card\; C:>File.txt
IMPORT_C TFileName | FolderNameFromFullName | ( | const TDesC & | aFullName | ) | [static] |
Gets the folder name from a path.
A valid full name should have a drive associated with it e.g ("a:\\" - "z:\\")("a:" - "z:")("c:\\system\data\file.txt") Invalid entry will have no drive and cause a panic EBafPanicBadOpenArg For example, if the path is "c:\documents\word\mydoc1", then "word" is returned. "c:" then "c:" is returned "c:\\" then "c:\" is returned "c:\\mydoc1.txt then "c:" is returned
const TDesC & aFullName | A path. |
IMPORT_C void | GetDiskListL | ( | const RFs & | aFs, |
CDesCArray & | aArray | |||
) | [static] |
Retrieves a list of all drives on the system.
The file server is interrogated for a list of the drive letters for all available drives.
On emulator: The removable media is represented by drive X: .
On hardware: The removable media is represented by drives D: E: F: and G: .
const RFs & aFs | A connected session with the file server. |
CDesCArray & aArray | On return, contains the drive letters that correspond to the available drives. The drive letters are uppercase and are in alphabetical order. |
IMPORT_C void | GetDowngradePathL | ( | const RFs & | aFs, |
const TLanguage | aCurrentLanguage, | |||
RArray < TLanguage > & | aLanguageArray | |||
) | [static] |
Gets the full language downgrade path for a particular locale.
const RFs & aFs | A connected session with the file server. |
const TLanguage aCurrentLanguage | The language of the locale for which the language downgrade path is required. This language will always be returned as the first language in aLanguageArray. To get the downgrade path for the language of the current locale, specify the language returned by User::Language(). |
RArray < TLanguage > & aLanguageArray | On return, contains the language downgrade path. |
IMPORT_C void | GetEquivalentLanguageList | ( | TLanguage | aLang, |
TLanguagePath & | aEquivalents | |||
) | [static] |
TLanguage aLang | |
TLanguagePath & aEquivalents |
IMPORT_C TInt | GetSystemDrive | ( | TDriveNumber & | aDriveNumber | ) | [static] |
TDriveNumber & aDriveNumber |
IMPORT_C TLanguage | IdealLanguage | ( | ) | [static] |
Get the ideal language of the thread. This interface is intended for the use of UIKON only.
IMPORT_C void | InitialiseHAL | ( | RFs & | aFs | ) | [static] |
Initialise the HAL settings from. 9.1 This function is empty
RFs & aFs |
IMPORT_C void | InitialiseScreenCalibration | ( | RFs & | aFs | ) | [static] |
RFs & aFs |
IMPORT_C TBool | IsFirstDriveForSocket | ( | TDriveUnit | aDriveUnit | ) | [static] |
Tests whether the specified drive corresponds to the primary partition in a removable media slot.
The function assumes that the D: drive corresponds to the primary partition on socket 0, and that the E: drive corresponds to the primary partition on socket 1 (a socket is a slot for removable media). This mapping may not always be the case because it is set up in the variant layer of the Symbian OS.
This function assumes that the drive mappings are contiguous, starting from drive D: .
On emulator: The removable media is represented by drive X: only.
TDriveUnit aDriveUnit | The drive to check. |
IMPORT_C TInt | IsFolder | ( | const RFs & | aFs, |
const TDesC & | aFullName, | |||
TBool & | aIsFolder | |||
) | [static] |
Checks if the specified item is a folder.
IMPORT_C TInt | MostSignificantPartOfFullName | ( | const TDesC & | aFullName, |
TFileName & | aMostSignificantPart | |||
) | [static] |
Gets the folder name if the specified item is a valid folder name, otherwise gets the file name.
IMPORT_C void | NearestLanguageFile | ( | const RFs & | aFs, |
TFileName & | aName | |||
) | [static] |
Searches for the file with the correct language extension for the language of the current locale, or failing this, the best matching file.
BaflUtils::NearestLanguageFile(const RFs& aFs,TFileName& aName, TLanguage& aLanguage)
IMPORT_C void | NearestLanguageFile | ( | const RFs & | aFs, |
TFileName & | aName, | |||
TLanguage & | aLanguage | |||
) | [static] |
This function gets the list of languages that are 'equivalent' to the given language. We say language L1 is equivalent to language L2 if speakers of L2 can readily understand L1 without intentional study or extraordinary effort.
L1, L2, L3, ..., Ln, ELangNone @codeend In which L2, ..., Ln are equivalents of L1, and ELangNone marks the end of an entry. The list is ordered. Compared with L3, L2 is nearer to L1. When choosing an equivalent of L1, L2 shall be preferred over L3, L3 shall be preferred over L4, and so on. L1 is always returned as the nearest equivalent of L1 itself. BaflUtils::NearestLanguageFileV2 searches language specific resource files according to the 'equivalent' relationship returned by this function. @param aLang The language whose equivalents needs to be found out. @param aEquivalents On return, this array contains the ordered list of languages that are equivalent to the given language. If there is no entry for the given language in the table, this array will contain two elements on return: the first is the given language itself and the 2nd one is ELangNone. For any language that has equivalents defined, content of he corresponding entry is returned. @see BaflUtils::NearestLanguageFileV2 */ EXPORT_C void BaflUtils::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 } /** NearestLanguageFileV2 is very similar to the existing 'NearestLanguageFile' function. The only difference between NearestLanguageFile and NearestLanguageFileV2 is the order in which language specific resource files are searched for. NearestLanguageFile searches language specific resource files in the order defined by the 'downgrade path' of the given language. Content of the downgrade path is dependent on the current active locale, and parts of it is runtime configurable. NearestLanguageFileV2 searches for language specific resource files in the order defined by the 'language equivalence table', which is a static data table fixed at build time. There is one entry in the table for each language that has one or more equivalents. @param aFs An active file server session. @param aName Name of the language-neutral resource file name which consist of an optional drive specification, followed by an optional path name, followed by basename for filename, followed by a period and extension. On return, in case of a match, this is replaced by the language-specific version which consists of the last two characters of the extension plus any preceding numeric characters being replaced by the language code. Remains unchanged when there's no match @param aLanguage On return, in case of a match, this is replaced by the corresponding language. In case of no match, it is set to ELangNone. @see TLanguage @see BaflUtils::GetEquivalentLanguageList */ EXPORT_C void BaflUtils::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; } } // TLibAssocBase EXPORT_C TLibAssocBase::TLibAssocBase(const RLibrary& aLib,TAny* aPtr) : iLibrary(aLib),iPtr(aPtr) /** Constructs the object taking the specified DLL and a class instance. @param aLib A reference to a DLL that has already been opened. @param aPtr An untyped pointer to an object to be associated with the DLL. Typically, this object will have been created using the ordinal 1 function from that DLL. */ {} EXPORT_C void TLibAssocBase::Set(const RLibrary& aLib,TAny* aPtr) /** Implements TLibAssoc::Set(). @param aLib A reference to a DLL that has already been opened. @param aClass A pointer to an object to be associated with the DLL. Typically, this object will have been created using the ordinal 1 function from that DLL. @see TLibAssoc::Set */ { __ASSERT_ALWAYS(iLibrary.Handle()==KNullHandle&&iPtr==NULL,Panic(EBafPanicLibAssocAlreadySet)); iLibrary=aLib; iPtr=aPtr; } EXPORT_C void TLibAssocBase::DoUnload(TAny* aThis) /** Calls Close() on the associated DLL. @param aThis An untyped pointer to a TLibAssoc type. */ { TLibAssocBase& l=*(TLibAssocBase*)aThis; l.iPtr=NULL; l.iLibrary.Close(); } // // class BaflUtils // EXPORT_C void BaflUtils::CopyWithTruncation(TDes& aDest,const TDesC& aSrc,TChar aTruncationSymbol) /** Copies a descriptor, abbreviating it to fit the destination descriptor. If aSrc is less than the maximum length of aDest, then the string is simply copied to aDest. If this is not so, then the left-most characters of aSrc are copied to aDest, up to aDest's maximum length-1. aDest's final character is set to be aTruncationSymbol. @param aDest On return, the truncated string @param aSrc The string to truncate @param aTruncationSymbol The truncation character to add */ { // static TInt maxLength=aDest.MaxLength(); if (aSrc.Length()<=maxLength) aDest.Copy(aSrc); else { aDest.Copy(aSrc.Left(maxLength-1)); aDest.Append(aTruncationSymbol); } } EXPORT_C TBool BaflUtils::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); } EXPORT_C TBool BaflUtils::PathExists(RFs& aFs,const TDesC& aPath) /** Tests whether a path exists. The path should contain a drive letter and a directory, or EFalse is returned. EFalse is also returned if it contains a filename or filename extension. If the path is badly formed, for instance if it contains illegal characters, or any directory name consists of a single or double dot, or any directory name includes wildcard characters, the function returns EFalse. @param aFs A connected session with the file server. @param aPath The path to test for. It should end in a backslash. @return ETrue if the path exists, EFalse if not. EFalse is also returned if the specified path is badly formed. */ { // static TParse parse; TInt retcode; retcode = parse.Set(aPath, NULL, NULL); if (retcode != KErrNone) return EFalse; if ((! parse.DrivePresent()) || (parse.NameOrExtPresent())) return EFalse; if (parse.Path().Length() == 0) return EFalse; TFileName dirName = parse.DriveAndPath(); if (dirName.Length() > KMaxFileName) return(EFalse); RDir dir; retcode = dir.Open(aFs,dirName,0); if (retcode == KErrNone) dir.Close(); return (retcode == KErrNone); } EXPORT_C void BaflUtils::EnsurePathExistsL(RFs& aFileSession,const TDesC& aFileName) /** Makes one or more directories, if they do not already exist. Any valid path component in the specified path that does not already exist is created as a directory. If the specified path already exists, the function returns normally. @param aFs File server session @param aFileName Path to ensure exists @see RFs::MkDirAll() */ { // static TInt error=aFileSession.MkDirAll(aFileName); if (error!=KErrAlreadyExists) User::LeaveIfError(error); } EXPORT_C TPtrC BaflUtils::ExtractAppNameFromFullName(const TFullName &aName) /** Gets the application name from a full thread name. @param aName Thread name @return Application name @see RThread */ { // static - return the app name (after first :: before next ::, if any) from a full thread name TChar delimiter=':'; TInt start=aName.Locate(delimiter); if (start<0) start=0; // should never happen else if (aName.Length()>start+2) start+=2; TPtrC rest=aName.Mid(start); TInt end=rest.Locate(delimiter); return end<0 ? rest : rest.Left(end); } 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); } 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); } 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; } /** Get the value of the system drive. The system drive can be set to one of the built-in read/write drives. Which drive is used is hardware-dependent. On some hardware, there may not be a system drive. The system drive is used as the drive on which localisable files are searched for. This enables a phone to be localised dynamically, using files not in the ROM. @param aDriveNumber On return, contains the drive number of the system drive. @return KErrNone is always returned. @deprecated This method has been replaced by (and now internally calls) RFs:GetSystemDrive, which always returns a valid drive number. @see BaflUtils::NearestLanguageFile @see RFs::GetSystemDrive */ EXPORT_C TInt BaflUtils::GetSystemDrive(TDriveNumber& aDriveNumber) { aDriveNumber = RFs::GetSystemDrive(); return KErrNone; } /** Set most appropriate extension language code for filename and set corresponding language. Symbian uses numeric values to identify natural languages as specified by the TLanguage enumeration defined in e32const.h. These values are used at the end of filename extensions to identify the languages pertaining to files which have language specific variants such as resource files. For instance filename.r01 and filename.r02 would be the English and French versions of the resource file filename.rsc. Language codes can be between 2 to 5 digits in length. Starting from Symbian OS v7.0 this function constructs and uses a language downgrade path which consists of up to sixteen TLanguage values the first of which is the ideal language followed by the language of the current locale. Up to the next three can be customised using TLocale::SetLanguageDowngrade(). The rest of the language downgrade path is based on a table of language near equivalence which is internal to Symbian. This function searches the custom resource drive (if set, retrieved from HAL) and then searches the optional drive specified in aName or 'Z:' if none is specified in aName. The custom resource drive is retrieved from the HAL attribute ECustomResourceDrive if set, if not set it will retrieve the legacy value set in the legacy HAL attribute ESystemDrive. No custom resource drive is searched if neither are set. Note - setting the custom resource drive will reduce the performance of this routine which will adversely affect device performance e.g. at boot up. On NAND Flash based devices use of a composite Z: drive file system made up of multiple ROM images is the preferred mechanism for customising language resources on devices in Symbian OS 9.2 onwards, see Developer Library Base Porting Guide Porting: background information NAND flash NAND Flash image format. Thus use of the custom resource drive HAL attribute is effectively obsolete. The last two characters of aName are removed along with any digits which appear before them. Then language codes specified in the constructed language downgrade path are appended in turn to aName as a match is searched for in the file system. In case no match is found using the constructed language downgradepath then files in the specified directory are searched for a suitable extension with preference given to the one specified if present. In cases where a match takes place the aName and aLanguage arguments are updated otherwise aName is left unchanged and aLanguage is set to ELangNone. Here are some examples of correct and incorrect function usage with different aName inputs, file system state and downgrade paths as follows: @code Following files exist: C:\\abc.rsc - Language Neutral resource file. C:\\abc.r01 - Resource file for the English language. C:\\abc.r10 - Resource file for the American-English language. C:\\abc.r160 - Resource file for the English as appropriate in Japan. Constructed Downgrade Language Path cases: - Case 1. (ELangAmerican -> ELangEnglish -> ELangNone). - Case 2. (ELangEnglish_Japan -> ELangEnglish -> ELangNone). - Case 3. Same as case 1, However "C:\\abc.r10" is deleted prior to the function call. - Case 4. Same as case 1, However both "C:\\abc.r01" and "C:\\abc.r10" are deleted prior to the function call.
Input aName . . . . Output aName. . . aLanguage . . . . . Description -------------------------------------------------------------------------------------------------------------------- "C:\\abc.rsc" . . . "C:\\abc.r10" . . ELangAmerican . . . Match on first language (Case 1) "C:\\abc.r10" . . . "C:\\abc.r10" . . ELangAmerican . . . Match, However it's not the intended use of . . . . . . . . . . . . . . . . . . . . . . . . . . . . . the function (Case 1) "C:\\abc.r" . . . . "C:\\abc.r" . . . ELangNone . . . . . The no. of characters in the suffix is less than . . . . . . . . . . . . . . . . . . . . . . . . . . . . . KInvNameAndMinSuffixLength(2)(Case 1) "C:\\abc.". . . . . "C:\\abc.". . . . ELangNone . . . . . Invalid Suffix: The filename ends with a period(Case 1) "C:\\abc.r123456" . "C:\\abc.r123456" ELangNone . . . . . Invalid Suffix: The no. of digits in the suffix is greater . . . . . . . . . . . . . . . . . . . . . . . . . . . . . than KMaxSuffixLength(5) (Case 1) "C:\\abc.10". . . . "C:\\abc.10 . . . ELangNone . . . . . Invalid Suffix: There's no proceeding alphabetical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . characters in the suffix (Case 1) "\\abc.rsc" . . . . "\\abc.rsc" . . . ELangNone . . . . . No drive so Z: search, no match (Case 1) "C:\\abc.rsc" . . . "C:\\abc.r160". . ELangEnglish_Japan. Match for language file 3 digits long (Case 2) "C:\\abc.rsc" . . . "C:\\abc.r01" . . ELangEnglish. . . . Match on second language (Case 3) "C:\\abc.rsc" . . . "C:\\abc.rsc" . . ELangNone . . . . . No corresponding langauge file match found (Case 4) ---------------------------------------------------------------------------------------------------------------------
TLanguage BaflUtils::GetDowngradePathL TLocale::SetLanguageDowngrade
const RFs & aFs | File server session. |
TFileName & aName | Optional drive specification, followed by optional path name, followed by basename for filename, followed by period and extension. On return, in case of a match, this is replaced by the language-specific version which consists of the last two characters of the extension plus any preceding numeric characters being replaced by the language code. Remains unchanged when there's no match |
TLanguage & aLanguage | On return, in case of a match, this is replaced by the corresponding language. In case of no match it's set to ELangNone. |
IMPORT_C void | NearestLanguageFileV2 | ( | const RFs & | aFs, |
TFileName & | aName, | |||
TLanguage & | aLanguage | |||
) | [static] |
IMPORT_C TInt | Parse | ( | const TDesC & | aName | ) | [static] |
Checks if a specified file name can be parsed.
const TDesC & aName | Name to parse |
IMPORT_C TBool | PathExists | ( | RFs & | aFs, |
const TDesC & | aFileName | |||
) | [static] |
IMPORT_C void | PersistLocale | ( | ) | [static] |
Saves the locale settings in TLocale and the currency symbol to file. 9.1 Persistence and initialisation of system locale data will be performed transparently by a separate executable (InilialiseLocale.exe) wich should be loaded as part of the system start procedure.
IMPORT_C void | PersistScreenCalibration | ( | const TDigitizerCalibration & | aScreenCalibration | ) | [static] |
const TDigitizerCalibration & aScreenCalibration |
IMPORT_C void | ReleaseIdealLanguage | ( | ) | [static] |
Releases the ideal language store if it has been allocated. This interface is intended for the use of UIKON only.
IMPORT_C void | RemoveSystemDirectory | ( | CDir & | aDir | ) | [static] |
Removes "System" from a list of directory entries.
CDir & aDir | Array of directory entries. |
IMPORT_C TInt | RenameFile | ( | RFs & | aFs, |
const TDesC & | aOldFullName, | |||
const TDesC & | aNewFullName, | |||
TUint | aSwitch = CFileMan::EOverWrite | |||
) | [static] |
Renames or moves one or more files or directories.
RFs & aFs | File server session |
const TDesC & aOldFullName | Path specifying the file(s) to be renamed. |
const TDesC & aNewFullName | Path specifying the new name for the files and/or the new directory. Any directories specified in this path that do not exist will be created. |
TUint aSwitch = CFileMan::EOverWrite |
IMPORT_C TFileName | RootFolderPath | ( | const TBuf < 1 > | aDriveLetter | ) | [static] |
Gets the root folder for the specified drive.
If aDriveLetter is an alphabet(lowercase or uppercase) then it will return the TFileName which is simply the drive letter plus ":\" If this is not the case, the function will panic with panic code EBafPanicBadOpenArg
const TBuf < 1 > aDriveLetter | Drive letter |
IMPORT_C TInt | SetIdealLanguage | ( | TLanguage | aLanguage | ) | [static] |
Set the ideal language for the thread. This interface is intended for the use of UIKON only.
TLanguage aLanguage | Ideal language. |
IMPORT_C TInt | SortByTable | ( | CDir & | aDir, |
CBaflFileSortTable * | aTable | |||
) | [static] |
Sorts files by UID.
The caller supplies a table which specifies the order in which files are to be sorted. The files whose UID3 is the first UID in the table appear first. The files whose UID3 is the UID specified second appear next, and so on. Files whose UID3 is not specified in the table, and directories, appear at the end of the list, with directories preceding the files, and with files sorted in ascending order of UID3.
This function is used for customising how lists of application files are sorted.
CDir & aDir | The array of files and directories to sort. |
CBaflFileSortTable * aTable | A sort order table containing the UIDs to use in the sort. |
IMPORT_C TBool | UidTypeMatches | ( | const TUidType & | aFileUid, |
const TUidType & | aMatchUid | |||
) | [static] |
Tests whether two UID types match.
A match is made if each UID in aMatchUid is either identical to the corresponding one in aFileUid, or is KNullUid.
IMPORT_C void | UpdateDiskListL | ( | const RFs & | aFs, |
CDesCArray & | aArray, | |||
TBool | aIncludeRom, | |||
TDriveNumber | aDriveNumber | |||
) | [static] |
Retrieves a list of all drives present on the system.
The file server is interrogated for a list of the drive letters for all available drives. The drive letter that corresponds to aDriveNumber is added to the list regardless of whether it is present, or is corrupt. Also, the C: drive is forced onto the list, even if corrupt or not present.
On emulator: The removable media is represented by drive X: and is forced onto the list unless removed (F5,F4).
On hardware: The removable media is represented by drives D: E: F: and G: and is forced onto the list regardless of whether it is present, or is corrupt.
const RFs & aFs | A connected session with the file server. |
CDesCArray & aArray | On return, contains the drive letters that correspond to the available drives. The drive letters are uppercase and are in alphabetical order. |
TBool aIncludeRom | Specify ETrue if the ROM drive should be included in the list, EFalse if not. |
TDriveNumber aDriveNumber | The drive to force into the list, e.g. the drive in the default path. |
IMPORT_C TInt | ValidateFolderNameTypedByUserL | ( | const RFs & | aFs, |
const TDesC & | aFolderNameTypedByUser, | |||
const TDesC & | aCurrentPath, | |||
TFileName & | aNewFolderFullName | |||
) | [static] |
Checks if a folder name (without drive or path) is valid and returns the full name of the folder.
Copyright ©2010 Nokia Corporation and/or its subsidiary(-ies).
All rights
reserved. Unless otherwise stated, these materials are provided under the terms of the Eclipse Public License
v1.0.