1
0
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:
AlexVinS 2015-08-11 21:20:13 +03:00 committed by AlexVinS
parent 0040b459c3
commit 1a8faeb0b9
12 changed files with 226 additions and 23 deletions

View File

@ -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" />

View File

@ -13,7 +13,6 @@
#include "CInputOutputStream.h"
/**
* A class which provides IO memory buffer.
*/

View File

@ -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;
};

View File

@ -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()),

View File

@ -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

View 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;
}

View 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;
};

View File

@ -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
}

View File

@ -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;
};

View File

@ -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());
}
}

View File

@ -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;
};

View File

@ -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>