mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-03 00:46:55 +02:00
Start implementing map saver
This commit is contained in:
@ -232,6 +232,8 @@
|
|||||||
<Unit filename="filesystem/CStream.h" />
|
<Unit filename="filesystem/CStream.h" />
|
||||||
<Unit filename="filesystem/CZipLoader.cpp" />
|
<Unit filename="filesystem/CZipLoader.cpp" />
|
||||||
<Unit filename="filesystem/CZipLoader.h" />
|
<Unit filename="filesystem/CZipLoader.h" />
|
||||||
|
<Unit filename="filesystem/CZipSaver.cpp" />
|
||||||
|
<Unit filename="filesystem/CZipSaver.h" />
|
||||||
<Unit filename="filesystem/Filesystem.cpp" />
|
<Unit filename="filesystem/Filesystem.cpp" />
|
||||||
<Unit filename="filesystem/Filesystem.h" />
|
<Unit filename="filesystem/Filesystem.h" />
|
||||||
<Unit filename="filesystem/ISimpleResourceLoader.h" />
|
<Unit filename="filesystem/ISimpleResourceLoader.h" />
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
#include "CInputOutputStream.h"
|
#include "CInputOutputStream.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class which provides IO memory buffer.
|
* A class which provides IO memory buffer.
|
||||||
*/
|
*/
|
||||||
|
@ -42,9 +42,9 @@ public:
|
|||||||
virtual si64 skip(si64 delta) = 0;
|
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;
|
virtual si64 getSize() = 0;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "../../Global.h"
|
|
||||||
#include "CZipLoader.h"
|
#include "CZipLoader.h"
|
||||||
|
|
||||||
#include "../ScopeGuard.h"
|
#include "../ScopeGuard.h"
|
||||||
@ -14,6 +13,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
///CZipStream
|
||||||
CZipStream::CZipStream(std::shared_ptr<CIOApi> api, const std::string & archive, unz_file_pos filepos)
|
CZipStream::CZipStream(std::shared_ptr<CIOApi> api, const std::string & archive, unz_file_pos filepos)
|
||||||
{
|
{
|
||||||
zlib_filefunc64_def zlibApi;
|
zlib_filefunc64_def zlibApi;
|
||||||
@ -50,6 +50,7 @@ ui32 CZipStream::calculateCRC32()
|
|||||||
return info.crc;
|
return info.crc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///CZipLoader
|
||||||
CZipLoader::CZipLoader(const std::string & mountPoint, const std::string & archive, std::shared_ptr<CIOApi> api):
|
CZipLoader::CZipLoader(const std::string & mountPoint, const std::string & archive, std::shared_ptr<CIOApi> api):
|
||||||
ioApi(api),
|
ioApi(api),
|
||||||
zlibApi(ioApi->getApiStructure()),
|
zlibApi(ioApi->getApiStructure()),
|
||||||
|
@ -61,7 +61,6 @@ public:
|
|||||||
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
|
std::unordered_set<ResourceID> getFilteredFiles(std::function<bool(const ResourceID &)> filter) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
namespace ZipArchive
|
namespace ZipArchive
|
||||||
{
|
{
|
||||||
/// List all files present in archive
|
/// 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 "StdInc.h"
|
||||||
|
|
||||||
#include "MinizipExtensions.h"
|
#include "MinizipExtensions.h"
|
||||||
|
|
||||||
|
#include "CMemoryBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
///CIOApi
|
||||||
voidpf ZCALLBACK CIOApi::openFileProxy(voidpf opaque, const void * filename, int mode)
|
voidpf ZCALLBACK CIOApi::openFileProxy(voidpf opaque, const void * filename, int mode)
|
||||||
{
|
{
|
||||||
assert(opaque != nullptr);
|
assert(opaque != nullptr);
|
||||||
@ -82,7 +85,7 @@ int ZCALLBACK CIOApi::closeFileProxy(voidpf opaque, voidpf stream)
|
|||||||
|
|
||||||
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream);
|
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream);
|
||||||
|
|
||||||
delete actualStream;
|
((CIOApi *)opaque)->closeFile(actualStream);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -92,7 +95,6 @@ int ZCALLBACK CIOApi::errorFileProxy(voidpf opaque, voidpf stream)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
///CIOApi
|
|
||||||
zlib_filefunc64_def CIOApi::getApiStructure() const
|
zlib_filefunc64_def CIOApi::getApiStructure() const
|
||||||
{
|
{
|
||||||
zlib_filefunc64_def api;
|
zlib_filefunc64_def api;
|
||||||
@ -108,6 +110,12 @@ zlib_filefunc64_def CIOApi::getApiStructure() const
|
|||||||
return api;
|
return api;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CIOApi::closeFile(CInputOutputStream * stream) const
|
||||||
|
{
|
||||||
|
delete stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
///CDefaultIOApi
|
||||||
CDefaultIOApi::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.");
|
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"
|
#include "../minizip/ioapi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "CInputOutputStream.h"
|
class CInputOutputStream;
|
||||||
|
class CMemoryBuffer;
|
||||||
|
|
||||||
class DLL_LINKAGE CIOApi
|
class DLL_LINKAGE CIOApi
|
||||||
{
|
{
|
||||||
@ -32,6 +33,9 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual CInputOutputStream * openFile(const std::string & filename, int mode) const = 0;
|
virtual CInputOutputStream * openFile(const std::string & filename, int mode) const = 0;
|
||||||
|
|
||||||
|
///default implementation deletes stream object
|
||||||
|
virtual void closeFile(CInputOutputStream * stream) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static voidpf ZCALLBACK openFileProxy(voidpf opaque, const void * filename, int mode);
|
static voidpf ZCALLBACK openFileProxy(voidpf opaque, const void * filename, int mode);
|
||||||
static uLong ZCALLBACK readFileProxy(voidpf opaque, voidpf stream, void * buf, uLong size);
|
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);
|
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
|
class DLL_LINKAGE CDefaultIOApi: public CIOApi
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -55,12 +60,15 @@ protected:
|
|||||||
CInputOutputStream * openFile(const std::string & filename, int mode) const override;
|
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:
|
public:
|
||||||
explicit CZipArchive(const CIOApi * api);
|
CProxyIOApi(CInputOutputStream * buffer);
|
||||||
virtual ~CZipArchive();
|
~CProxyIOApi();
|
||||||
|
protected:
|
||||||
|
CInputOutputStream * openFile(const std::string & filename, int mode) const override;
|
||||||
|
void closeFile(CInputOutputStream * stream) const override;
|
||||||
private:
|
private:
|
||||||
|
CInputOutputStream * data;
|
||||||
};
|
};
|
||||||
|
@ -51,6 +51,8 @@ static EventCondition JsonToCondition(const JsonNode & node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
///CMapFormatJson
|
///CMapFormatJson
|
||||||
|
const std::string CMapFormatJson::HEADER_FILE_NAME = "header.json";
|
||||||
|
|
||||||
void CMapFormatJson::readTriggeredEvents(const JsonNode & input)
|
void CMapFormatJson::readTriggeredEvents(const JsonNode & input)
|
||||||
{
|
{
|
||||||
mapHeader->victoryMessage = input["victoryString"].String();
|
mapHeader->victoryMessage = input["victoryString"].String();
|
||||||
@ -183,15 +185,40 @@ void CMapLoaderJson::readPlayerInfo()
|
|||||||
}
|
}
|
||||||
|
|
||||||
///CMapSaverJson
|
///CMapSaverJson
|
||||||
CMapSaverJson::CMapSaverJson(COutputStream * stream):
|
CMapSaverJson::CMapSaverJson(CInputOutputStream * stream):
|
||||||
output(stream)
|
output(stream),
|
||||||
|
ioApi(new CProxyIOApi(output)),
|
||||||
|
saver(ioApi, "_")
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMapSaverJson::~CMapSaverJson()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void CMapSaverJson::saveMap(const std::unique_ptr<CMap>& map)
|
void CMapSaverJson::saveMap(const std::unique_ptr<CMap>& map)
|
||||||
{
|
{
|
||||||
//TODO: saveMap
|
//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 "CMapService.h"
|
||||||
#include "../JsonNode.h"
|
#include "../JsonNode.h"
|
||||||
|
|
||||||
|
#include "../filesystem/CZipSaver.h"
|
||||||
|
#include "../filesystem/CZipLoader.h"
|
||||||
|
|
||||||
class TriggeredEvent;
|
class TriggeredEvent;
|
||||||
class CInputStream;
|
|
||||||
class COutputStream;
|
|
||||||
|
|
||||||
class DLL_LINKAGE CMapFormatJson
|
class DLL_LINKAGE CMapFormatJson
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
static const std::string HEADER_FILE_NAME;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -121,7 +125,9 @@ public:
|
|||||||
*
|
*
|
||||||
* @param stream a stream to save the map to
|
* @param stream a stream to save the map to
|
||||||
*/
|
*/
|
||||||
CMapSaverJson(COutputStream * stream);
|
CMapSaverJson(CInputOutputStream * stream);
|
||||||
|
|
||||||
|
~CMapSaverJson();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually saves the VCMI/Json map into stream.
|
* Actually saves the VCMI/Json map into stream.
|
||||||
@ -129,5 +135,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
void saveMap(const std::unique_ptr<CMap> & map) override;
|
void saveMap(const std::unique_ptr<CMap> & map) override;
|
||||||
private:
|
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-unused-parameter" />
|
||||||
<Add option="-Wno-overloaded-virtual" />
|
<Add option="-Wno-overloaded-virtual" />
|
||||||
<Add option="-Wno-unused-local-typedefs" />
|
<Add option="-Wno-unused-local-typedefs" />
|
||||||
|
<Add directory="$(#zlib.include)" />
|
||||||
<Add directory="$(#boost.include)" />
|
<Add directory="$(#boost.include)" />
|
||||||
</Compiler>
|
</Compiler>
|
||||||
<Linker>
|
<Linker>
|
||||||
|
Reference in New Issue
Block a user