virtual Status GetFileInfo(const VfsPath& pathname, FileInfo* pfileInfo) const { ScopedLock s; VfsDirectory* directory; VfsFile* file; Status ret = vfs_Lookup(pathname, &m_rootDirectory, directory, &file); if(!pfileInfo) // just indicate if the file exists without raising warnings. return ret; WARN_RETURN_STATUS_IF_ERR(ret); *pfileInfo = FileInfo(file->Name(), file->Size(), file->MTime()); return INFO::OK; }
virtual Status RemoveFile(const VfsPath& pathname) { ScopedLock s; m_fileCache.Remove(pathname); VfsDirectory* directory; VfsFile* file; RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); directory->RemoveFile(file->Name()); return INFO::OK; }
virtual Status LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size) { ScopedLock s; const bool isCacheHit = m_fileCache.Retrieve(pathname, fileContents, size); if(!isCacheHit) { VfsDirectory* directory; VfsFile* file; // per 2010-05-01 meeting, this shouldn't raise 'scary error // dialogs', which might fail to display the culprit pathname // instead, callers should log the error, including pathname. RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); fileContents = DummySharedPtr((u8*)0); size = file->Size(); if(size != 0) // (the file cache can't handle zero-length allocations) { if(size < m_cacheSize/2) // (avoid evicting lots of previous data) fileContents = m_fileCache.Reserve(size); if(fileContents) { RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size())); m_fileCache.Add(pathname, fileContents, size); } else { RETURN_STATUS_IF_ERR(AllocateAligned(fileContents, size, maxSectorSize)); RETURN_STATUS_IF_ERR(file->Loader()->Load(file->Name(), fileContents, file->Size())); } } } stats_io_user_request(size); stats_cache(isCacheHit? CR_HIT : CR_MISS, size); m_trace->NotifyLoad(pathname, size); return INFO::OK; }
std::wstring FileDescription(const VfsFile& file) { wchar_t timestamp[25]; const time_t mtime = file.MTime(); wcsftime(timestamp, ARRAY_SIZE(timestamp), L"%a %b %d %H:%M:%S %Y", localtime(&mtime)); wchar_t buf[200]; swprintf_s(buf, ARRAY_SIZE(buf), L"(%c; %6lu; %ls) %ls", file.Loader()->LocationCode(), (unsigned long)file.Size(), timestamp, file.Name().string().c_str()); return buf; }