Skip to content

Commit

Permalink
#5108: Move ArchivedMapResource implementation to .cpp file.
Browse files Browse the repository at this point in the history
Prevent saving of read-only resources.
  • Loading branch information
codereader committed Nov 29, 2020
1 parent 07aed61 commit 4bd351d
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 63 deletions.
1 change: 1 addition & 0 deletions radiantcore/Makefile.am
Expand Up @@ -144,6 +144,7 @@ libradiantcore_la_SOURCES = Radiant.cpp \
map/namespace/ComplexName.cpp \
map/namespace/Namespace.cpp \
map/namespace/NamespaceFactory.cpp \
map/ArchivedMapResource.cpp \
map/AutoSaver.cpp \
map/CounterManager.cpp \
map/EditingStopwatch.cpp \
Expand Down
81 changes: 81 additions & 0 deletions radiantcore/map/ArchivedMapResource.cpp
@@ -0,0 +1,81 @@
#include "ArchivedMapResource.h"

#include "i18n.h"
#include "ifilesystem.h"

namespace map
{

ArchivedMapResource::ArchivedMapResource(const std::string& archivePath, const std::string& filePathWithinArchive) :
MapResource(filePathWithinArchive),
_archivePath(archivePath),
_filePathWithinArchive(filePathWithinArchive)
{}

bool ArchivedMapResource::isReadOnly()
{
return true;
}

void ArchivedMapResource::save(const MapFormatPtr& mapFormat)
{
assert(false);
rError() << "ArchivedMapResources cannot be saved." << std::endl;
}

stream::MapResourceStream::Ptr ArchivedMapResource::openMapfileStream()
{
ensureArchiveOpened();

return openFileInArchive(_filePathWithinArchive);
}

stream::MapResourceStream::Ptr ArchivedMapResource::openInfofileStream()
{
ensureArchiveOpened();

try
{
auto infoFilename = _filePathWithinArchive.substr(0, _filePathWithinArchive.rfind('.'));
infoFilename += GetInfoFileExtension();

return openFileInArchive(infoFilename);
}
catch (const OperationException& ex)
{
// Info file load file does not stop us, just issue a warning
rWarning() << ex.what() << std::endl;
return stream::MapResourceStream::Ptr();
}
}

stream::MapResourceStream::Ptr ArchivedMapResource::openFileInArchive(const std::string& filePathWithinArchive)
{
assert(_archive);

auto archiveFile = _archive->openTextFile(filePathWithinArchive);

if (!archiveFile)
{
throw OperationException(fmt::format(_("Could not open file in archive: {0}"), _archivePath));
}

return stream::MapResourceStream::OpenFromArchiveFile(archiveFile);
}

void ArchivedMapResource::ensureArchiveOpened()
{
if (_archive)
{
return;
}

_archive = GlobalFileSystem().openArchiveInAbsolutePath(_archivePath);

if (!_archive)
{
throw OperationException(fmt::format(_("Could not open archive: {0}"), _archivePath));
}
}

}
79 changes: 16 additions & 63 deletions radiantcore/map/ArchivedMapResource.h
@@ -1,13 +1,20 @@
#pragma once

#include "i18n.h"
#include "ifilesystem.h"
#include "iarchive.h"
#include "MapResource.h"
#include "stream/MapResourceStream.h"

namespace map
{

/**
* MapResource specialising on loading map files from archives
* just as PK4 files, which may be located outside the VFS search
* paths.
*
* ArchivedMapResources are read-only and don't implement the save()
* methods.
*/
class ArchivedMapResource :
public MapResource
{
Expand All @@ -18,73 +25,19 @@ class ArchivedMapResource :
IArchive::Ptr _archive;

public:
ArchivedMapResource(const std::string& archivePath, const std::string& filePathWithinArchive) :
MapResource(filePathWithinArchive),
_archivePath(archivePath),
_filePathWithinArchive(filePathWithinArchive)
{}
ArchivedMapResource(const std::string& archivePath, const std::string& filePathWithinArchive);

virtual bool isReadOnly() override
{
return true;
}
virtual bool isReadOnly() override;
virtual void save(const MapFormatPtr& mapFormat = MapFormatPtr()) override;

protected:
virtual stream::MapResourceStream::Ptr openMapfileStream() override
{
ensureArchiveOpened();

return openFileInArchive(_filePathWithinArchive);
}

virtual stream::MapResourceStream::Ptr openInfofileStream() override
{
ensureArchiveOpened();

try
{
auto infoFilename = _filePathWithinArchive.substr(0, _filePathWithinArchive.rfind('.'));
infoFilename += GetInfoFileExtension();

return openFileInArchive(infoFilename);
}
catch (const OperationException& ex)
{
// Info file load file does not stop us, just issue a warning
rWarning() << ex.what() << std::endl;
return stream::MapResourceStream::Ptr();
}
}
virtual stream::MapResourceStream::Ptr openMapfileStream() override;
virtual stream::MapResourceStream::Ptr openInfofileStream() override;

private:
stream::MapResourceStream::Ptr openFileInArchive(const std::string& filePathWithinArchive)
{
assert(_archive);

auto archiveFile = _archive->openTextFile(filePathWithinArchive);

if (!archiveFile)
{
throw OperationException(fmt::format(_("Could not open file in archive: {0}"), _archivePath));
}

return stream::MapResourceStream::OpenFromArchiveFile(archiveFile);
}

void ensureArchiveOpened()
{
if (_archive)
{
return;
}

_archive = GlobalFileSystem().openArchiveInAbsolutePath(_archivePath);
stream::MapResourceStream::Ptr openFileInArchive(const std::string& filePathWithinArchive);

if (!_archive)
{
throw OperationException(fmt::format(_("Could not open archive: {0}"), _archivePath));
}
}
void ensureArchiveOpened();
};

}
6 changes: 6 additions & 0 deletions radiantcore/map/Map.cpp
Expand Up @@ -339,6 +339,12 @@ bool Map::save(const MapFormatPtr& mapFormat)
{
if (_saveInProgress) return false; // safeguard

if (_resource->isReadOnly())
{
rError() << "This map is read-only and cannot be saved." << std::endl;
return false;
}

_saveInProgress = true;

emitMapEvent(MapSaving);
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/DarkRadiantCore.vcxproj
Expand Up @@ -101,6 +101,7 @@
<ClCompile Include="..\..\radiantcore\map\algorithm\MapImporter.cpp" />
<ClCompile Include="..\..\radiantcore\map\algorithm\Models.cpp" />
<ClCompile Include="..\..\radiantcore\map\algorithm\Skins.cpp" />
<ClCompile Include="..\..\radiantcore\map\ArchivedMapResource.cpp" />
<ClCompile Include="..\..\radiantcore\map\AutoSaver.cpp" />
<ClCompile Include="..\..\radiantcore\map\CounterManager.cpp" />
<ClCompile Include="..\..\radiantcore\map\EditingStopwatch.cpp" />
Expand Down
3 changes: 3 additions & 0 deletions tools/msvc/DarkRadiantCore.vcxproj.filters
Expand Up @@ -1003,6 +1003,9 @@
<ClCompile Include="..\..\radiantcore\map\MapResourceLoader.cpp">
<Filter>src\map</Filter>
</ClCompile>
<ClCompile Include="..\..\radiantcore\map\ArchivedMapResource.cpp">
<Filter>src\map</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\radiantcore\modulesystem\ModuleLoader.h">
Expand Down

0 comments on commit 4bd351d

Please sign in to comment.