mirror of
https://github.com/jpd002/Play-.git
synced 2025-04-28 21:57:57 +03:00
97 lines
3 KiB
C++
97 lines
3 KiB
C++
#include <cassert>
|
|
#include "PsfStreamProvider.h"
|
|
#include "StdStream.h"
|
|
#include "MemStream.h"
|
|
#include "StdStreamUtils.h"
|
|
|
|
std::unique_ptr<CPsfStreamProvider> CreatePsfStreamProvider(const fs::path& archivePath)
|
|
{
|
|
if(archivePath.empty())
|
|
{
|
|
return std::unique_ptr<CPsfStreamProvider>(new CPhysicalPsfStreamProvider());
|
|
}
|
|
else
|
|
{
|
|
return std::unique_ptr<CPsfStreamProvider>(new CArchivePsfStreamProvider(archivePath));
|
|
}
|
|
}
|
|
|
|
//CPhysicalPsfStreamProvider
|
|
//----------------------------------------------------------
|
|
Framework::CStream* CPhysicalPsfStreamProvider::GetStreamForPath(const CPsfPathToken& pathToken)
|
|
{
|
|
auto path = GetFilePathFromPathToken(pathToken);
|
|
return new Framework::CStdStream(Framework::CreateInputStdStream(path.native()));
|
|
}
|
|
|
|
CPsfPathToken CPhysicalPsfStreamProvider::GetPathTokenFromFilePath(const fs::path& filePath)
|
|
{
|
|
return filePath.wstring();
|
|
}
|
|
|
|
fs::path CPhysicalPsfStreamProvider::GetFilePathFromPathToken(const CPsfPathToken& pathToken)
|
|
{
|
|
return fs::path(pathToken.GetWidePath());
|
|
}
|
|
|
|
CPsfPathToken CPhysicalPsfStreamProvider::GetSiblingPath(const CPsfPathToken& pathToken, const std::string& siblingName)
|
|
{
|
|
auto path = GetFilePathFromPathToken(pathToken);
|
|
auto siblingPath = path.remove_filename() / siblingName;
|
|
return GetPathTokenFromFilePath(siblingPath);
|
|
}
|
|
|
|
//CArchivePsfStreamProvider
|
|
//----------------------------------------------------------
|
|
CArchivePsfStreamProvider::CArchivePsfStreamProvider(const fs::path& path)
|
|
{
|
|
m_archive = CPsfArchive::CreateFromPath(path);
|
|
}
|
|
|
|
CArchivePsfStreamProvider::~CArchivePsfStreamProvider()
|
|
{
|
|
}
|
|
|
|
CPsfPathToken CArchivePsfStreamProvider::GetPathTokenFromFilePath(const std::string& filePath)
|
|
{
|
|
return CPsfPathToken::WidenString(filePath);
|
|
}
|
|
|
|
std::string CArchivePsfStreamProvider::GetFilePathFromPathToken(const CPsfPathToken& pathToken)
|
|
{
|
|
return pathToken.GetNarrowPath();
|
|
}
|
|
|
|
CPsfPathToken CArchivePsfStreamProvider::GetSiblingPath(const CPsfPathToken& pathToken, const std::string& siblingName)
|
|
{
|
|
auto pathString = pathToken.GetWidePath();
|
|
auto slashPos = pathString.find_last_of(L"/");
|
|
if(slashPos == std::wstring::npos)
|
|
{
|
|
slashPos = pathString.find_last_of(L"\\");
|
|
if(slashPos == std::wstring::npos)
|
|
{
|
|
slashPos = -1;
|
|
}
|
|
}
|
|
slashPos++;
|
|
auto stem = std::wstring(std::begin(pathString), std::begin(pathString) + slashPos);
|
|
auto result = stem + CPsfPathToken::WidenString(siblingName);
|
|
return result;
|
|
}
|
|
|
|
Framework::CStream* CArchivePsfStreamProvider::GetStreamForPath(const CPsfPathToken& pathToken)
|
|
{
|
|
auto pathString = GetFilePathFromPathToken(pathToken);
|
|
std::replace(pathString.begin(), pathString.end(), '\\', '/');
|
|
const auto& fileInfo(m_archive->GetFileInfo(pathString.c_str()));
|
|
assert(fileInfo != nullptr);
|
|
if(fileInfo == nullptr)
|
|
{
|
|
throw std::runtime_error("Couldn't find file in archive.");
|
|
}
|
|
auto result = new Framework::CMemStream();
|
|
result->Allocate(fileInfo->length);
|
|
m_archive->ReadFileContents(pathString.c_str(), result->GetBuffer(), fileInfo->length);
|
|
return result;
|
|
}
|