mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Start implementing map saver
This commit is contained in:
parent
0040b459c3
commit
1a8faeb0b9
@ -232,6 +232,8 @@
|
||||
<Unit filename="filesystem/CStream.h" />
|
||||
<Unit filename="filesystem/CZipLoader.cpp" />
|
||||
<Unit filename="filesystem/CZipLoader.h" />
|
||||
<Unit filename="filesystem/CZipSaver.cpp" />
|
||||
<Unit filename="filesystem/CZipSaver.h" />
|
||||
<Unit filename="filesystem/Filesystem.cpp" />
|
||||
<Unit filename="filesystem/Filesystem.h" />
|
||||
<Unit filename="filesystem/ISimpleResourceLoader.h" />
|
||||
|
@ -13,7 +13,6 @@
|
||||
|
||||
#include "CInputOutputStream.h"
|
||||
|
||||
|
||||
/**
|
||||
* A class which provides IO memory buffer.
|
||||
*/
|
||||
|
@ -42,9 +42,9 @@ public:
|
||||
virtual si64 skip(si64 delta) = 0;
|
||||
|
||||
/**
|
||||
* Gets the length in bytes of the stream.
|
||||
* Gets the length of the stream.
|
||||
*
|
||||
* @return the length in bytes of the stream.
|
||||
* @return the length in bytes
|
||||
*/
|
||||
virtual si64 getSize() = 0;
|
||||
};
|
||||
|
@ -1,5 +1,4 @@
|
||||
#include "StdInc.h"
|
||||
#include "../../Global.h"
|
||||
#include "CZipLoader.h"
|
||||
|
||||
#include "../ScopeGuard.h"
|
||||
@ -14,6 +13,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
///CZipStream
|
||||
CZipStream::CZipStream(std::shared_ptr<CIOApi> api, const std::string & archive, unz_file_pos filepos)
|
||||
{
|
||||
zlib_filefunc64_def zlibApi;
|
||||
@ -50,6 +50,7 @@ ui32 CZipStream::calculateCRC32()
|
||||
return info.crc;
|
||||
}
|
||||
|
||||
///CZipLoader
|
||||
CZipLoader::CZipLoader(const std::string & mountPoint, const std::string & archive, std::shared_ptr<CIOApi> api):
|
||||
ioApi(api),
|
||||
zlibApi(ioApi->getApiStructure()),
|
||||
|
@ -61,7 +61,6 @@ public:
|
||||
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
|
||||
};
|
||||
|
||||
|
||||
namespace ZipArchive
|
||||
{
|
||||
/// List all files present in archive
|
||||
|
79
lib/filesystem/CZipSaver.cpp
Normal file
79
lib/filesystem/CZipSaver.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* CZipSaver.cpp, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "CZipSaver.h"
|
||||
|
||||
///CZipOutputStream
|
||||
CZipOutputStream::CZipOutputStream(zipFile archive, const std::string & archiveFilename):
|
||||
handle(archive)
|
||||
{
|
||||
//zip_fileinfo fileInfo;
|
||||
|
||||
zipOpenNewFileInZip(handle,
|
||||
archiveFilename.c_str(),
|
||||
nullptr,//todo: use fileInfo,
|
||||
nullptr,
|
||||
0,
|
||||
nullptr,
|
||||
0,
|
||||
"",
|
||||
Z_DEFLATED,
|
||||
Z_DEFAULT_COMPRESSION);
|
||||
}
|
||||
|
||||
CZipOutputStream::~CZipOutputStream()
|
||||
{
|
||||
zipCloseFileInZip(handle);
|
||||
}
|
||||
|
||||
|
||||
si64 CZipOutputStream::write(const ui8 * data, si64 size)
|
||||
{
|
||||
int ret = zipWriteInFileInZip(handle, (const void*)data, (unsigned)size);
|
||||
|
||||
if (ret == ZIP_OK)
|
||||
return size;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
///CZipSaver
|
||||
CZipSaver::CZipSaver(std::shared_ptr<CIOApi> api, const std::string & path):
|
||||
ioApi(api),
|
||||
zipApi(ioApi->getApiStructure()),
|
||||
handle(nullptr)
|
||||
{
|
||||
|
||||
|
||||
handle = zipOpen2_64(path.c_str(), APPEND_STATUS_CREATE, nullptr, &zipApi);
|
||||
|
||||
if (handle == nullptr)
|
||||
throw new std::runtime_error("Failed to create archive");
|
||||
}
|
||||
|
||||
CZipSaver::~CZipSaver()
|
||||
{
|
||||
if(handle != nullptr)
|
||||
zipClose(handle, nullptr);
|
||||
}
|
||||
|
||||
std::unique_ptr<COutputStream> CZipSaver::addFile(const std::string & archiveFilename)
|
||||
{
|
||||
if(activeStream != nullptr)
|
||||
throw new std::runtime_error("CZipSaver::addFile: stream already opened");
|
||||
|
||||
std::unique_ptr<COutputStream> stream(new CZipOutputStream(handle, archiveFilename));
|
||||
|
||||
activeStream = stream.get();
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
53
lib/filesystem/CZipSaver.h
Normal file
53
lib/filesystem/CZipSaver.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
/*
|
||||
* CZipSaver.h, part of VCMI engine
|
||||
*
|
||||
* Authors: listed in file AUTHORS in main folder
|
||||
*
|
||||
* License: GNU General Public License v2.0 or later
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
#include "COutputStream.h"
|
||||
|
||||
#include "MinizipExtensions.h"
|
||||
|
||||
class DLL_LINKAGE CZipOutputStream: public COutputStream
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief constructs zip stream from already opened file
|
||||
* @param archive archive handle, must be opened
|
||||
* @param archiveFilename name of file to write
|
||||
*/
|
||||
explicit CZipOutputStream(zipFile archive, const std::string & archiveFilename);
|
||||
~CZipOutputStream();
|
||||
|
||||
si64 write(const ui8 * data, si64 size) override;
|
||||
|
||||
si64 seek(si64 position) override {return -1;};
|
||||
si64 tell() override {return 0;};
|
||||
si64 skip(si64 delta) override {return 0;};
|
||||
si64 getSize() override {return 0;};
|
||||
private:
|
||||
zipFile handle;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CZipSaver
|
||||
{
|
||||
public:
|
||||
explicit CZipSaver(std::shared_ptr<CIOApi> api, const std::string & path);
|
||||
virtual ~CZipSaver();
|
||||
|
||||
std::unique_ptr<COutputStream> addFile(const std::string & archiveFilename);
|
||||
private:
|
||||
std::shared_ptr<CIOApi> ioApi;
|
||||
zlib_filefunc64_def zipApi;
|
||||
|
||||
zipFile handle;
|
||||
|
||||
///due to minizip design only one file stream may opened at a time
|
||||
COutputStream * activeStream;
|
||||
};
|
@ -8,9 +8,12 @@
|
||||
*
|
||||
*/
|
||||
#include "StdInc.h"
|
||||
|
||||
#include "MinizipExtensions.h"
|
||||
|
||||
#include "CMemoryBuffer.h"
|
||||
|
||||
|
||||
///CIOApi
|
||||
voidpf ZCALLBACK CIOApi::openFileProxy(voidpf opaque, const void * filename, int mode)
|
||||
{
|
||||
assert(opaque != nullptr);
|
||||
@ -82,7 +85,7 @@ int ZCALLBACK CIOApi::closeFileProxy(voidpf opaque, voidpf stream)
|
||||
|
||||
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream);
|
||||
|
||||
delete actualStream;
|
||||
((CIOApi *)opaque)->closeFile(actualStream);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -92,7 +95,6 @@ int ZCALLBACK CIOApi::errorFileProxy(voidpf opaque, voidpf stream)
|
||||
return 0;
|
||||
}
|
||||
|
||||
///CIOApi
|
||||
zlib_filefunc64_def CIOApi::getApiStructure() const
|
||||
{
|
||||
zlib_filefunc64_def api;
|
||||
@ -108,6 +110,12 @@ zlib_filefunc64_def CIOApi::getApiStructure() const
|
||||
return api;
|
||||
}
|
||||
|
||||
void CIOApi::closeFile(CInputOutputStream * stream) const
|
||||
{
|
||||
delete stream;
|
||||
}
|
||||
|
||||
///CDefaultIOApi
|
||||
CDefaultIOApi::CDefaultIOApi()
|
||||
{
|
||||
|
||||
@ -132,12 +140,28 @@ CInputOutputStream * CDefaultIOApi::openFile(const std::string& filename, int mo
|
||||
throw new std::runtime_error("CDefaultIOApi::openFile call not expected.");
|
||||
}
|
||||
|
||||
CZipArchive::CZipArchive(const CIOApi* api)
|
||||
///CProxyIOApi
|
||||
CProxyIOApi::CProxyIOApi(CInputOutputStream * buffer):
|
||||
data(buffer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CZipArchive::~CZipArchive()
|
||||
CProxyIOApi::~CProxyIOApi()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CInputOutputStream * CProxyIOApi::openFile(const std::string& filename, int mode) const
|
||||
{
|
||||
logGlobal->traceStream() << "CProxyIOApi: stream opened for" <<filename<<" with mode "<<mode;
|
||||
|
||||
data->seek(0);
|
||||
return data;//todo: check that only one "copy" is opened
|
||||
}
|
||||
|
||||
void CProxyIOApi::closeFile(CInputOutputStream * stream) const
|
||||
{
|
||||
logGlobal->traceStream() << "CProxyIOApi: stream closed";
|
||||
stream->seek(0);//stream is local singleton and even not owned, just seek
|
||||
}
|
||||
|
@ -20,7 +20,8 @@
|
||||
#include "../minizip/ioapi.h"
|
||||
#endif
|
||||
|
||||
#include "CInputOutputStream.h"
|
||||
class CInputOutputStream;
|
||||
class CMemoryBuffer;
|
||||
|
||||
class DLL_LINKAGE CIOApi
|
||||
{
|
||||
@ -32,6 +33,9 @@ public:
|
||||
protected:
|
||||
virtual CInputOutputStream * openFile(const std::string & filename, int mode) const = 0;
|
||||
|
||||
///default implementation deletes stream object
|
||||
virtual void closeFile(CInputOutputStream * stream) const;
|
||||
|
||||
private:
|
||||
static voidpf ZCALLBACK openFileProxy(voidpf opaque, const void * filename, int mode);
|
||||
static uLong ZCALLBACK readFileProxy(voidpf opaque, voidpf stream, void * buf, uLong size);
|
||||
@ -42,7 +46,8 @@ private:
|
||||
static int ZCALLBACK errorFileProxy(voidpf opaque, voidpf stream);
|
||||
};
|
||||
|
||||
|
||||
///redirects back to minizip ioapi
|
||||
//todo: replace with Virtual FileSystem interface
|
||||
class DLL_LINKAGE CDefaultIOApi: public CIOApi
|
||||
{
|
||||
public:
|
||||
@ -55,12 +60,15 @@ protected:
|
||||
CInputOutputStream * openFile(const std::string & filename, int mode) const override;
|
||||
};
|
||||
|
||||
class CZipArchive
|
||||
///redirects all file IO to single stream
|
||||
class DLL_LINKAGE CProxyIOApi: public CIOApi
|
||||
{
|
||||
public:
|
||||
explicit CZipArchive(const CIOApi * api);
|
||||
virtual ~CZipArchive();
|
||||
|
||||
CProxyIOApi(CInputOutputStream * buffer);
|
||||
~CProxyIOApi();
|
||||
protected:
|
||||
CInputOutputStream * openFile(const std::string & filename, int mode) const override;
|
||||
void closeFile(CInputOutputStream * stream) const override;
|
||||
private:
|
||||
|
||||
CInputOutputStream * data;
|
||||
};
|
||||
|
@ -51,6 +51,8 @@ static EventCondition JsonToCondition(const JsonNode & node)
|
||||
}
|
||||
|
||||
///CMapFormatJson
|
||||
const std::string CMapFormatJson::HEADER_FILE_NAME = "header.json";
|
||||
|
||||
void CMapFormatJson::readTriggeredEvents(const JsonNode & input)
|
||||
{
|
||||
mapHeader->victoryMessage = input["victoryString"].String();
|
||||
@ -183,15 +185,40 @@ void CMapLoaderJson::readPlayerInfo()
|
||||
}
|
||||
|
||||
///CMapSaverJson
|
||||
CMapSaverJson::CMapSaverJson(COutputStream * stream):
|
||||
output(stream)
|
||||
CMapSaverJson::CMapSaverJson(CInputOutputStream * stream):
|
||||
output(stream),
|
||||
ioApi(new CProxyIOApi(output)),
|
||||
saver(ioApi, "_")
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CMapSaverJson::~CMapSaverJson()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CMapSaverJson::saveMap(const std::unique_ptr<CMap>& map)
|
||||
{
|
||||
//TODO: saveMap
|
||||
this->map = map.get();
|
||||
}
|
||||
|
||||
void CMapSaverJson::saveHeader()
|
||||
{
|
||||
JsonNode header;
|
||||
//TODO: save header
|
||||
|
||||
header["name"].String() = map->name;
|
||||
|
||||
std::ostringstream out;
|
||||
out << header;
|
||||
out.flush();
|
||||
|
||||
{
|
||||
auto s = out.str();
|
||||
auto stream = saver.addFile(HEADER_FILE_NAME);
|
||||
|
||||
stream->write((const ui8*)s.c_str(), s.size());
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,16 @@
|
||||
#include "CMapService.h"
|
||||
#include "../JsonNode.h"
|
||||
|
||||
#include "../filesystem/CZipSaver.h"
|
||||
#include "../filesystem/CZipLoader.h"
|
||||
|
||||
class TriggeredEvent;
|
||||
class CInputStream;
|
||||
class COutputStream;
|
||||
|
||||
|
||||
class DLL_LINKAGE CMapFormatJson
|
||||
{
|
||||
public:
|
||||
static const std::string HEADER_FILE_NAME;
|
||||
|
||||
protected:
|
||||
|
||||
@ -121,7 +125,9 @@ public:
|
||||
*
|
||||
* @param stream a stream to save the map to
|
||||
*/
|
||||
CMapSaverJson(COutputStream * stream);
|
||||
CMapSaverJson(CInputOutputStream * stream);
|
||||
|
||||
~CMapSaverJson();
|
||||
|
||||
/**
|
||||
* Actually saves the VCMI/Json map into stream.
|
||||
@ -129,5 +135,9 @@ public:
|
||||
*/
|
||||
void saveMap(const std::unique_ptr<CMap> & map) override;
|
||||
private:
|
||||
COutputStream * output;
|
||||
void saveHeader();
|
||||
|
||||
CInputOutputStream * output;
|
||||
std::shared_ptr<CIOApi> ioApi;
|
||||
CZipSaver saver;
|
||||
};
|
||||
|
@ -47,6 +47,7 @@
|
||||
<Add option="-Wno-unused-parameter" />
|
||||
<Add option="-Wno-overloaded-virtual" />
|
||||
<Add option="-Wno-unused-local-typedefs" />
|
||||
<Add directory="$(#zlib.include)" />
|
||||
<Add directory="$(#boost.include)" />
|
||||
</Compiler>
|
||||
<Linker>
|
||||
|
Loading…
Reference in New Issue
Block a user