chxavfilestore.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,202 行 · 第 1/3 页
CPP
1,202 行
// fill out entry info based on current path
//
void CHXAvFileStore::RefreshEntryInfoL()
{
if( 0 == m_suspendRefreshSem )
{
TInt err = KErrNone;
CHXAvDirectoryReader reader;
if(reader.SetToPath(GetFullPath()))
{
m_bNeedRefresh = false;
m_entryInfo.Resize(0);
const bool bIncludeChildFolders = true;
RefreshEntryInfoHelper(reader.GetFiles(), bIncludeChildFolders);
RefreshEntryInfoHelper(reader.GetDirs(), bIncludeChildFolders);
}
else
{
// path invalid? external delete?
err = reader.GetLastError();
}
HXSYM_LEAVE_IF_ERR(err);
}
}
////////////////////////////////////////////////////////////
// path - relative to root or absolute
// name - relative to given path
//
// caller must close file object
//
FILE* CHXAvFileStore::OpenFileL(const TDesC& path,
const TDesC& fileName,
const char* pMode)
{
HX_ASSERT(pMode);
TFileName* pPath = AllocFullPathL(path, fileName);
AUTO_PUSH_POP_DEL(pPath);
CHXAvFile::EnsureClearReadOnlyAttributeL(*pPath);
FILE* pFile = ::fopen( CHXAvStringUtils::DescToString(*pPath), pMode);
return pFile;
}
////////////////////////////////////////////////////////////
// returns KErrDiskFull if there is not enough disk space to
// make the copy
//
// Epoc copy-file APIs normally require that EFileShareReadersOnly flag was used
// to open the source file; fopen(..., "r") apparently does not result in
// EFileShareReadersOnly being set (probably only EFileRead);
// here's a work-around
//
// call this after copyfile fails with KErrInUse
//
// args:
//
// pathDest - path relative to root or absoluted
// fileNameDest - name relative to pathDest
//
TInt CHXAvFileStore::CopyFileAlternateL(const TDesC& pathDest,
const TDesC& fileNameDest,
const TDesC& fullPathSource,
bool bAllowOverwrite)
{
TFileName* pFullPathDest = AllocFullPathL(pathDest, fileNameDest);
AUTO_PUSH_POP_DEL(pFullPathDest);
DPRINTF(SYMP_FILE, ("FileStore::CopyFileAlternateL(): copying '%s' -> '%s'\n", dbg::CharPtr(fullPathSource)(), dbg::CharPtr(*pFullPathDest)()));
TInt idxDestDrive = CHXAvFile::GetDriveIndex(*pFullPathDest);
TInt err = CHXAvFile::CheckDiskSpaceForCopyL(fullPathSource, idxDestDrive);
if(KErrNone == err)
{
RFile source;
RFile target;
// buffer for reading source file data
const TUint k_cbCopyBuffer = 64 * 1024; // 64K buffer (mimics CFileMan copy)
HBufC8* pCopyBuffer = HBufC8::NewL(k_cbCopyBuffer);
AUTO_PUSH_POP_DEL(pCopyBuffer);
CEikonEnv* pEnv = CEikonEnv::Static();
// open source
err = source.Open(pEnv->FsSession(), fullPathSource, EFileRead|EFileShareAny);
if(KErrNone == err)
{
CleanupClosePushL(source);
if( bAllowOverwrite && CHXAvFile::PathExists(*pFullPathDest) )
{
// make sure file is deleted (so create will succeed)
HXSYM_LEAVE_IF_ERR(DeleteFileL(*pFullPathDest));
}
// (re-)create target; fails if file exists
err = target.Create(pEnv->FsSession(), *pFullPathDest, EFileWrite|EFileShareExclusive);
if(KErrNone == err)
{
CleanupClosePushL(target);
m_cbFileOp = 0;
OnFileOpStart(FileStoreOperationObserver::otCopy, fullPathSource, *pFullPathDest);
// copy bits
TPtr8 ptr = pCopyBuffer->Des();
err = source.Read(ptr);
if( KErrNone == err )
{
while(pCopyBuffer->Length() != 0)
{
err = target.Write(*pCopyBuffer);
if( KErrNone != err )
{
break;
}
m_cbFileOp += pCopyBuffer->Length();
// notify observer each time we copy a chunk; provide chance to cancel operation
bool bContinue = OnFileOpTick(FileStoreOperationObserver::otCopy, fullPathSource, *pFullPathDest, m_cbFileOp);
if( !bContinue )
{
// user cancel
err = KErrCancel;
break;
}
err = source.Read(ptr);
if( KErrNone != err )
{
break;
}
}
if( KErrNone == err )
{
err = target.Flush();
}
}
target.Close();
CleanupStack::PopAndDestroy(); // target
if( KErrNone != err )
{
DPRINTF(SYMP_FILE, ("FileStore::CopyFileAlternateL(): failed; deleting target file (err = 0x%08x\n)", err));
// delete destination - copy was not completed
HXSYM_LEAVE_IF_ERR(DeleteFileL(*pFullPathDest));
}
else
{
// succeded - set file attributes
HXSYM_LEAVE_IF_ERR(m_pFileMan->Attribs(*pFullPathDest,
KEntryAttNormal/*set*/,
KEntryAttReadOnly/*clear*/, TTime(0)));
}
OnFileOpEnd(FileStoreOperationObserver::otCopy, err, fullPathSource, *pFullPathDest);
}
CleanupStack::PopAndDestroy(); // source
}
}
return err;
}
////////////////////////////////////////////////////////////
// returns KErrDiskFull if there is not enough disk space to
// make the copy
//
// args:
//
// pathDest - path relative to root or absolute
// fileNameDest - name relative to pathDest
//
TInt CHXAvFileStore::CopyFileL(const TDesC& pathDest,
const TDesC& fileNameDest,
const TDesC& fullPathSource,
bool bAllowOverwrite)
{
TFileName* pFullPathDest = AllocFullPathL(pathDest, fileNameDest);
AUTO_PUSH_POP_DEL(pFullPathDest);
TUint flag = (bAllowOverwrite ? CFileMan::EOverWrite : 0);
DPRINTF(SYMP_FILE, ("FileStore::CopyFileL(): copying '%s' -> '%s'\n", dbg::CharPtr(fullPathSource)(), dbg::CharPtr(*pFullPathDest)()));
TInt err = KErrGeneral;
if( 0 == pFullPathDest->CompareF(fullPathSource) )
{
// copy to self; nothing to do; ignore
err = KErrNone;
}
else
{
TInt idxDestDrive = CHXAvFile::GetDriveIndex(*pFullPathDest);
err = CHXAvFile::CheckDiskSpaceForCopyL(fullPathSource, idxDestDrive);
if( err == KErrNone )
{
// fileman copy fails (KErrInUse) if file not opened with EFileShareReadersOnly
#if defined(ASYNC_COPYMOVE)
err = m_pFileMan->Copy(fullPathSource, *pFullPathDest, flag, m_pFileOpCompletion->Status());
m_pFileOpCompletion->Activate();
#else
err = m_pFileMan->Copy(fullPathSource, *pFullPathDest, flag);
#endif
}
}
return err;
}
////////////////////////////////////////////////////////////
// folder - folder relative to current path;
// leading path delimiter is optional
//
TInt CHXAvFileStore::CreateChildFolderL(const TDesC& folder, bool bAllowOverwrite)
{
// alloc fully qualified folder name
TFileName* pName = CHXAvFile::AllocFileNameL(GetFullPath(), folder, CHXAvFile::ntFolder);
AUTO_PUSH_POP_DEL(pName);
if( bAllowOverwrite && CHXAvFile::PathExists(*pName) )
{
// make sure existing folder is deleted (so create will succeed)
HXSYM_LEAVE_IF_ERR(DeleteFileL(*pName));
}
RFs& fs = CCoeEnv::Static()->FsSession();
TInt err = fs.MkDir(*pName); //note: see also MkDirAll
if(KErrNone == err)
{
// just in case (we should get event notification from the fs watcher)
m_bNeedRefresh = true;
}
return err;
}
////////////////////////////////////////////
// folder - folder relative to current path;
// path delimiters (prefix and suffix) are optional
//
void CHXAvFileStore::SwitchToChildFolderL(const TDesC& folder)
{
DPRINTF(SYMP_FILE, ("FileStore::SwitchToChildFolderL(): '%s'\n", dbg::CharPtr(folder)()));
TFileName* pPath = CHXAvFile::AllocFileNameL(m_curPath, folder, CHXAvFile::ntFolder);
AUTO_PUSH_POP_DEL(pPath);
SetCurrentPathL(*pPath);
}
////////////////////////////////////////////////////////////
// switch current path to parent folder
void CHXAvFileStore::SwitchToParentFolderL()
{
DPRINTF(SYMP_FILE, ("FileStore::SwitchToParentFolderL()\n"));
HX_ASSERT(!IsAtRoot());
TPtrC parent = CHXAvFile::GetParentFolder(m_curPath);
SetCurrentPathL(parent);
}
////////////////////////////////////////////////////////////
//
TInt CHXAvFileStore::DeleteFileL(const TDesC& fullPath, CHXAvFile::NameType type)
{
return DeleteFileL(fullPath, KNullDesC, type);
}
////////////////////////////////////////////////////////////
// delete a file or folder from disk; if successful, mark
// current list as needing refresh
//
// pathDest - full or relative base path
// name - name of file or folder to append
// type - type of file system entry; ntUnspecified if type can safely be deduced from 'name'
//
TInt CHXAvFileStore::DeleteFileL(const TDesC& pathDest, const TDesC& name, CHXAvFile::NameType type)
{
TInt err = KErrGeneral;
TFileName* pFullPath = AllocFullPathL(pathDest, name);
AUTO_PUSH_POP_DEL(pFullPath);
bool bIsFolder = false;
if( type == CHXAvFile::ntFolder )
{
bIsFolder = true;
CHXAvFile::EnsureFolderSuffix(*pFullPath);
}
else if( type == CHXAvFile::ntUnspecified )
{
bIsFolder = CHXAvFile::HasFolderSuffix(*pFullPath);
}
CHXAvFile::EnsureClearReadOnlyAttributeL(*pFullPath);
if( bIsFolder )
{
HX_ASSERT(CHXAvFile::HasFolderSuffix(*pFullPath));
err = m_pFileMan->RmDir(*pFullPath);
}
else
{
HX_ASSERT(!CHXAvFile::HasFolderSuffix(*pFullPath));
err = m_pFileMan->Delete(*pFullPath);
}
if(KErrNone == err)
{
// just in case (we should get event notification from the fs watcher)
m_bNeedRefresh = IsImmediateChild(*pFullPath) || IsParent(*pFullPath);
}
return err;
}
////////////////////////////////////////////////////////////
// delete a file or folder from disk; if successful, markd current
// list as needing refresh
//
// idxItem - index of item in current folder path
//
TInt CHXAvFileStore::DeleteItemL(TInt idxItem)
{
TInt err = KErrGeneral;
TFileName* pFullPath = AllocFullPathL(idxItem);
AUTO_PUSH_POP_DEL(pFullPath);
CHXAvFile::EnsureClearReadOnlyAttributeL(*pFullPath);
HX_ASSERT(idxItem < m_entryInfo.Nelements());
const TEntry& entry = m_entryInfo[idxItem].m_entry;
if( entry.IsDir() )
{
HX_ASSERT(CHXAvFile::HasFolderSuffix(*pFullPath));
err = m_pFileMan->RmDir(*pFullPath);
}
else
{
HX_ASSERT(!CHXAvFile::HasFolderSuffix(*pFullPath));
err = m_pFileMan->Delete(*pFullPath);
}
if(KErrNone == err)
{
// just in case (we should get event notification from the fs watcher)
m_bNeedRefresh = true;
}
return err;
}
////////////////////////////////////////////////////////////
// path - relative to root or absolute (if drive specified)
// idxItem - index of item in _current_ folder path
//
// * call this before certain unchecking methods
//
// return: true if fully qualified filename formed from
// input parameters would fit safely in a TFileName buffer
//
bool CHXAvFileStore::IsSafeFileNameLengthL(const TDesC& path, TInt idxItem)
{
TFileName* pPath = AllocFullPathL(path, KNullDesC, CHXAvFile::ntFolder);
AUTO_PUSH_POP_DEL(pPath);
HX_ASSERT(idxItem < m_entryInfo.Nelements());
const TEntry& entry = m_entryInfo[idxItem].m_entry;
TInt cchRequired = pPath->Length() + entry.iName.Length();
if( entry.IsDir() )
{
cchRequired += 1; // account for folder suffix that will need to be added
}
return cchRequired <= KMaxFileName;
}
////////////////////////////////////////////////////////////
// see IsSafeFileNameLengthL() override
bool CHXAvFileStore::IsSafeFileNameLengthL(const TDesC& path,
const TDesC& name,
CHXAvFile::NameType type)
{
TFileName* pPath = AllocFullPathL(path, KNullDesC, CHXAvFile::ntFolder);
AUTO_PUSH_POP_DEL(pPath);
TInt cchRequired = pPath->Length() + name.Length();
if( (CHXAvFile::ntFolder == type) && !CHXAvFile::HasFolderSuffix(name) )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?