chxavfileutil.cpp
来自「著名的 helix realplayer 基于手机 symbian 系统的 播放」· C++ 代码 · 共 1,149 行 · 第 1/3 页
CPP
1,149 行
/*****************************************************************************
* chxavfileutil.h
* ---------------
*
* Synopsis:
* File utility namespace. Misc stuff for helping to work with filenames and
* paths.
*
* Target:
* Symbian OS
*
*
* (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
*
*****************************************************************************/
// Symbian includes...
#include <eikfutil.h>
#include <f32file.h>
#include <apgcli.h>
#include <apmrec.h>
#include <sysutil.h>
#include <eikappui.h>
#include <eikapp.h>
// Helix includes...
#include "hxtypes.h"
#include "hxassert.h"
#include "hxcom.h"
#include "hxprefs.h" //IHXPreferences
// Include from this project...
#include "chxavutil.h"
#include "chxavfileutil.h"
#include "chxavcleanstring.h"
#include "chxavutil.h"
#include "chxavescapedstring.h"
#include "chxavdirectoryreader.h"
#include "chxavcleanupstack.h"
#include "hxsym_debug.h"
#include "hxapihelp.h"
#include "hxsym_leaveutil.h"
#include "hxsym_filetype.h"
#include "hxsym_mimetypes.h"
namespace CHXAvFile
{
// explictly instanciate GetFolderChildCount template here
template
TInt GetFolderChildCount(const TDesC& folderPath,
TInt& countOut, bool bWantFolders,
PFNNanoPlayerFilterType isWantedFile);
////////////////////////////////////////////////////
// get number of folders and files immediately within the
// given directory (not recursive)
//
template <typename FileFilter>
TInt GetFolderChildCount(const TDesC& folderPath,
TInt& countOut, bool bWantFolders,
FileFilter isWantedFile)
{
RFs& fs = CCoeEnv::Static()->FsSession();
CHXAvDirectoryReader reader(fs);
TInt error = KErrNone;
countOut = -1;
reader.SetSortFlags(ESortNone); // be as fast as possible; don't need sorting here
if( reader.SetToPath(folderPath) )
{
countOut = 0;
const CDir* pFiles = reader.GetFiles();
if(pFiles)
{
// only count files that are of interest and not hidden
TInt count = pFiles->Count();
for(TInt idx = 0; idx < count; ++idx)
{
TEntry entry = (*pFiles)[idx];
if( !CHXAvUtil::ShouldHideFromUser(entry) && isWantedFile(folderPath, entry.iName) )
{
++countOut;
}
}
pFiles = 0;
}
if( bWantFolders )
{
const CDir* pFolders = reader.GetDirs();
if(pFolders)
{
// add non-hidden directories to total
TInt count = pFolders->Count();
for(TInt idx = 0; idx < count; ++idx)
{
TEntry entry = (*pFolders)[idx];
if( !CHXAvUtil::ShouldHideFromUser(entry) )
{
countOut += 1;
}
}
}
}
}
else
{
error = reader.GetLastError();
}
return error;
}
bool IsNanoPlayerFileType(const TDesC& fullPath)
{
FileType fileType = GetFileType(fullPath);
return IsNanoPlayerFileType(fileType);
}
bool IsNanoPlayerFileType(const TDesC& folderPath, const TDesC& itemName)
{
TFileName* fullPath = AllocFileNameL(folderPath, itemName);
AUTO_PUSH_POP_DEL(fullPath);
FileType fileType = GetFileType(*fullPath);
return IsNanoPlayerFileType(fileType);
}
////////////////////////////////
// get fully qualified absolute path (with drive letter prefix), ensuring that it
// exists
//
// searches all available drives: first session drive (normally 'c:\'), then y to a, then z
//
// if a drive letter is supplied, only that drive will be searched; other
// drives are not searched
//
// Parameters:
//
// path - absolute (with drive) or relative (to unspecified drive) path;
// must have folder suffix if a folder is wanted
// fullPath - fully qualified absolute and verified path (with drive letter prefix)
// if return is KErrNone
//
// bAllowWildCard - returns first match if true (even if multiple matches!)
//
TInt GetFullPath(RFs& fs, const TDesC& path, TDes& fullPath, bool bAllowWildCard)
{
DPRINTF(SYMP_FILE, ("CHXAvFile::GetFullPath(): looking for '%s'\n", dbg::CharPtr(path)()));
TInt err = KErrNotFound;
fullPath = KNullDesC;
TInt idxDrive = GetDriveIndex(path);
if( (-1 != idxDrive) && path.Length() <= 3 )
{
//
// special case: confirming that drive root path (e.g. 'e:\') exists
//
// TFileFind fails if we specify root path
//
if(PathExists(path))
{
fullPath = path;
err = KErrNone;
}
}
else
{
TFindFile find(fs);
CDir* pDir = 0;
if(bAllowWildCard)
{
// search for first match
err = find. FindWildByDir(path, KNullDesC, pDir);
}
else
{
err = find.FindByDir(path, KNullDesC);
}
if (err == KErrNone)
{
if(pDir)
{
fullPath = GetFolderPath(find.File());
if( pDir->Count() > 0 )
{
// File() returns drive and path in this case; set returned path to first entry found
fullPath.Append( (*pDir)[0].iName );
}
HX_DELETE(pDir);
}
else
{
fullPath = find.File();
}
// if drive was specified for sought-after path, ensure found path matches
if( idxDrive != -1 )
{
//
// TFindFile will search for path on an alternate drive
// if it fails to find a path on a specified drive; it treats drive letter
// as meaning 'preferred' as opposed to 'required' (as we do)
//
TInt idxDriveFound = GetDriveIndex(fullPath);
if(idxDriveFound != idxDrive)
{
// path doesn't exist on drive we wanted; refuse path on alternate drive
fullPath = KNullDesC;
err = KErrNotFound;
}
}
}
}
DPRINTF(SYMP_FILE, ("GetFullPath(): found '%s'\n", dbg::CharPtr(fullPath)()));
return err;
}
////////////////////////////////////////////////////////
// alloc default name; append (N) to name until name is unique
// within the path
//
// defaultName - name of file or folder to begin with ('name' or 'name/')
// basePath - full base path
//
// e.g., New Folder, New Folder(01), New Folder(02)
//
// returns 0 if:
// a) no unique name could be found (bad base path or roque tester);
// b) not enough space to fit suggested name plus prefix (base path + default name near max TFileName)
//
// XXXLCM consider using CApaApplication::GenerateFileName
//
TFileName* AllocUniqueDefaultNameL(const TDesC& basePath,
const TDesC& defaultName,
bool bWantFolder,
const CHXAvNameDisplayTrait& nameTrait)
{
_LIT(KDuplicateNameFormat, "%S(%02d)");
const TUint k_cchSuffix = 4; //"(NN)"
const TUint k_maxTries = 100;
TFileName* pPathOut = 0;
// make sure we have a qualified name (indicating folder or file)
TFileName* pFullDefaultName = AllocFileNameL(defaultName, (bWantFolder ? CHXAvFile::ntFolder : CHXAvFile::ntFile));
AUTO_PUSH_POP_DEL(pFullDefaultName);
// break up qualified name for display and formatting
NameExt nameInfo = nameTrait.GetDisplayText(*pFullDefaultName, bWantFolder);
// max chars for 'name' in 'name.xx'
TInt cchMaxNamePart = KMaxFileName - basePath.Length() - nameInfo.second.Length();
if( !HasFolderSuffix(basePath) )
{
cchMaxNamePart -= 1; // for path sep that would be added to form full path
}
if ( cchMaxNamePart > 0 )
{
// possibly crop 'name' in 'name.xx'
if( nameInfo.first.Length() > cchMaxNamePart )
{
nameInfo.first.Set(nameInfo.first.Ptr(), cchMaxNamePart);
}
// working display name buffer
HBufC* pDisplayName = HBufC::NewMaxL(nameInfo.first.Length() + k_cchSuffix);
AUTO_PUSH_POP_DEL(pDisplayName);
TPtr ptrDisplayName = pDisplayName->Des();
// potential name to be displayed to user
ptrDisplayName.Copy(nameInfo.first);
// full path to go out
pPathOut = new (ELeave) TFileName;
AUTO_PUSH_POP(pPathOut);
bool bFound = false;
for(TInt idx = 0; idx < k_maxTries; ++idx)
{
// re-form path and see if it is unique
pPathOut->Copy(basePath);
AppendPath(*pPathOut, ptrDisplayName, CHXAvFile::ntUnspecified);
pPathOut->Append(nameInfo.second);
DPRINTF(SYMP_FILE, ("AllocUniqueDefaultFilenameL(): testing '%s'\n", dbg::CharPtr(*pPathOut)()));
if(!PathExists(*pPathOut))
{
// found a unique name
bFound = true;
break;
}
// from now on we'll be adding suffix...
// max chars for 'name' in 'name(NN).xx'
TInt cchMaxNamePartMinusSuffix = cchMaxNamePart - k_cchSuffix;
if(cchMaxNamePartMinusSuffix <= 0 )
{
// give up...
break;
}
// possibly crop 'name' in 'name(NN)'
if( nameInfo.first.Length() > cchMaxNamePartMinusSuffix )
{
nameInfo.first.Set(nameInfo.first.Ptr(), cchMaxNamePartMinusSuffix);
}
// name was not unique; try next (start with 01)
ptrDisplayName.Format(KDuplicateNameFormat, &nameInfo.first, idx + 1);
}
if( !bFound )
{
HX_DELETE(pPathOut);
}
}
return pPathOut;
}
////////////////////////////////////////////////////////////
//
// fullPath - full path to file or folder; folders must have folder suffix
//
bool PathExists(const TDesC& fullPath)
{
DPRINTF(SYMP_FILE, ("PathExists(): checking path '%s'\n", dbg::CharPtr(fullPath)()));
RFs& fs = CCoeEnv::Static()->FsSession();
//
// note: BaflUtils::PathExists() is only api that appears to correctly
// validate a root folder, e.g., 'c:\')
//
if(HasFolderSuffix(fullPath))
{
return BaflUtils::PathExists(fs, fullPath);
}
return BaflUtils::FileExists(fs, fullPath);
}
////////////////////////////////
//
// return 0-based index of drive relative to 'a'; -1 if no drive specified
//
// (note: a valid index maps to TDriveNumer)
//
// 'c:' -> 2
// 'a:\' -> 0
// 'e:\foo\bar\ -> 4
// '\foo\bar' -> -1
// 'c:hello' -> -1
//
TInt GetDriveIndex(const TDesC& path)
{
DPRINTF(SYMP_FILE, ("GetDriveIndex(): checking '%s'\n", dbg::CharPtr(path)()));
TInt idx = -1;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?