1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Complete json map format integration

This commit is contained in:
AlexVinS 2016-02-10 07:28:00 +03:00
parent 0c21efb202
commit 3c78f960cd
5 changed files with 206 additions and 120 deletions

View File

@ -13,53 +13,31 @@
#include "CMemoryBuffer.h" #include "CMemoryBuffer.h"
#include "FileStream.h" #include "FileStream.h"
///CIOApi template <class _Stream> inline uLong streamRead(voidpf opaque, voidpf stream, void * buf, uLong size)
voidpf ZCALLBACK CIOApi::openFileProxy(voidpf opaque, const void * filename, int mode)
{
assert(opaque != nullptr);
boost::filesystem::path path;
if(filename != nullptr)
path = static_cast<const boost::filesystem::path::value_type *>(filename);
return ((CIOApi *)opaque)->openFile(path, mode);
}
uLong ZCALLBACK CIOApi::readFileProxy(voidpf opaque, voidpf stream, void * buf, uLong size)
{ {
assert(opaque != nullptr); assert(opaque != nullptr);
assert(stream != nullptr); assert(stream != nullptr);
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream); _Stream * actualStream = static_cast<_Stream *>(stream);
return actualStream->read((ui8 *)buf, size); return actualStream->read((ui8 *)buf, size);
} }
uLong ZCALLBACK CIOApi::writeFileProxy(voidpf opaque, voidpf stream, const void * buf, uLong size) template <class _Stream> inline ZPOS64_T streamTell(voidpf opaque, voidpf stream)
{ {
assert(opaque != nullptr); assert(opaque != nullptr);
assert(stream != nullptr); assert(stream != nullptr);
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream); _Stream * actualStream = static_cast<_Stream *>(stream);
return (uLong)actualStream->write((const ui8 *)buf, size);
}
ZPOS64_T ZCALLBACK CIOApi::tellFileProxy(voidpf opaque, voidpf stream)
{
assert(opaque != nullptr);
assert(stream != nullptr);
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream);
return actualStream->tell(); return actualStream->tell();
} }
long ZCALLBACK CIOApi::seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) template <class _Stream> inline long streamSeek(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
{ {
assert(opaque != nullptr); assert(opaque != nullptr);
assert(stream != nullptr); assert(stream != nullptr);
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream); _Stream * actualStream = static_cast<_Stream *>(stream);
long ret = 0; long ret = 0;
switch (origin) switch (origin)
@ -82,47 +60,24 @@ long ZCALLBACK CIOApi::seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T off
default: ret = -1; default: ret = -1;
} }
if(ret == -1) if(ret == -1)
logGlobal->error("CIOApi::seekFileProxy: seek failed"); logGlobal->error("Stream seek failed");
return ret; return ret;
} }
int ZCALLBACK CIOApi::closeFileProxy(voidpf opaque, voidpf stream) template <class _Stream> inline int streamProxyClose(voidpf opaque, voidpf stream)
{ {
assert(opaque != nullptr); assert(opaque != nullptr);
assert(stream != nullptr); assert(stream != nullptr);
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream); _Stream * actualStream = static_cast<_Stream *>(stream);
((CIOApi *)opaque)->closeFile(actualStream); logGlobal->traceStream() << "Proxy stream closed";
actualStream->seek(0);
return 0; return 0;
} }
int ZCALLBACK CIOApi::errorFileProxy(voidpf opaque, voidpf stream)
{
return 0;
}
zlib_filefunc64_def CIOApi::getApiStructure() const
{
zlib_filefunc64_def api;
api.opaque = (void *) this;
api.zopen64_file = &openFileProxy;
api.zread_file = &readFileProxy;
api.zwrite_file = &writeFileProxy;
api.ztell64_file = &tellFileProxy;
api.zseek64_file = &seekFileProxy;
api.zclose_file = &closeFileProxy;
api.zerror_file = &errorFileProxy;
return api;
}
void CIOApi::closeFile(CInputOutputStream * stream) const
{
delete stream;
}
///CDefaultIOApi ///CDefaultIOApi
CDefaultIOApi::CDefaultIOApi() CDefaultIOApi::CDefaultIOApi()
{ {
@ -134,16 +89,11 @@ CDefaultIOApi::~CDefaultIOApi()
} }
zlib_filefunc64_def CDefaultIOApi::getApiStructure() const zlib_filefunc64_def CDefaultIOApi::getApiStructure()
{ {
return * FileStream::GetMinizipFilefunc(); return * FileStream::GetMinizipFilefunc();
} }
CInputOutputStream * CDefaultIOApi::openFile(const boost::filesystem::path & filename, int mode) const
{
throw new std::runtime_error("CDefaultIOApi::openFile call not expected.");
}
///CProxyIOApi ///CProxyIOApi
CProxyIOApi::CProxyIOApi(CInputOutputStream * buffer): CProxyIOApi::CProxyIOApi(CInputOutputStream * buffer):
data(buffer) data(buffer)
@ -156,7 +106,68 @@ CProxyIOApi::~CProxyIOApi()
} }
CInputOutputStream * CProxyIOApi::openFile(const boost::filesystem::path & filename, int mode) const zlib_filefunc64_def CProxyIOApi::getApiStructure()
{
zlib_filefunc64_def api;
api.opaque = this;
api.zopen64_file = &openFileProxy;
api.zread_file = &readFileProxy;
api.zwrite_file = &writeFileProxy;
api.ztell64_file = &tellFileProxy;
api.zseek64_file = &seekFileProxy;
api.zclose_file = &closeFileProxy;
api.zerror_file = &errorFileProxy;
return api;
}
voidpf ZCALLBACK CProxyIOApi::openFileProxy(voidpf opaque, const void * filename, int mode)
{
assert(opaque != nullptr);
boost::filesystem::path path;
if(filename != nullptr)
path = static_cast<const boost::filesystem::path::value_type *>(filename);
return ((CProxyIOApi *)opaque)->openFile(path, mode);
}
uLong ZCALLBACK CProxyIOApi::readFileProxy(voidpf opaque, voidpf stream, void * buf, uLong size)
{
return streamRead<CInputOutputStream>(opaque, stream, buf, size);
}
uLong ZCALLBACK CProxyIOApi::writeFileProxy(voidpf opaque, voidpf stream, const void * buf, uLong size)
{
assert(opaque != nullptr);
assert(stream != nullptr);
CInputOutputStream * actualStream = static_cast<CInputOutputStream *>(stream);
return (uLong)actualStream->write((const ui8 *)buf, size);
}
ZPOS64_T ZCALLBACK CProxyIOApi::tellFileProxy(voidpf opaque, voidpf stream)
{
return streamTell<CInputOutputStream>(opaque, stream);
}
long ZCALLBACK CProxyIOApi::seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
{
return streamSeek<CInputOutputStream>(opaque, stream, offset, origin);
}
int ZCALLBACK CProxyIOApi::closeFileProxy(voidpf opaque, voidpf stream)
{
return streamProxyClose<CInputOutputStream>(opaque, stream);
}
int ZCALLBACK CProxyIOApi::errorFileProxy(voidpf opaque, voidpf stream)
{
return 0;
}
CInputOutputStream * CProxyIOApi::openFile(const boost::filesystem::path & filename, int mode)
{ {
logGlobal->traceStream() << "CProxyIOApi: stream opened for " <<filename.string() <<" with mode "<<mode; logGlobal->traceStream() << "CProxyIOApi: stream opened for " <<filename.string() <<" with mode "<<mode;
@ -164,8 +175,80 @@ CInputOutputStream * CProxyIOApi::openFile(const boost::filesystem::path & filen
return data; return data;
} }
void CProxyIOApi::closeFile(CInputOutputStream * stream) const ///CProxyROIOApi
CProxyROIOApi::CProxyROIOApi(CInputStream * buffer):
data(buffer)
{ {
logGlobal->traceStream() << "CProxyIOApi: stream closed";
stream->seek(0);//stream is local singleton and even not owned, just seek }
CProxyROIOApi::~CProxyROIOApi()
{
}
zlib_filefunc64_def CProxyROIOApi::getApiStructure()
{
zlib_filefunc64_def api;
api.opaque = this;
api.zopen64_file = &openFileProxy;
api.zread_file = &readFileProxy;
api.zwrite_file = &writeFileProxy;
api.ztell64_file = &tellFileProxy;
api.zseek64_file = &seekFileProxy;
api.zclose_file = &closeFileProxy;
api.zerror_file = &errorFileProxy;
return api;
}
CInputStream * CProxyROIOApi::openFile(const boost::filesystem::path& filename, int mode)
{
logGlobal->traceStream() << "CProxyIOApi: stream opened for " <<filename.string() <<" with mode "<<mode;
data->seek(0);
return data;
}
voidpf ZCALLBACK CProxyROIOApi::openFileProxy(voidpf opaque, const void* filename, int mode)
{
assert(opaque != nullptr);
boost::filesystem::path path;
if(filename != nullptr)
path = static_cast<const boost::filesystem::path::value_type *>(filename);
return ((CProxyROIOApi *)opaque)->openFile(path, mode);
}
uLong ZCALLBACK CProxyROIOApi::readFileProxy(voidpf opaque, voidpf stream, void * buf, uLong size)
{
return streamRead<CInputStream>(opaque, stream, buf, size);
}
uLong ZCALLBACK CProxyROIOApi::writeFileProxy(voidpf opaque, voidpf stream, const void* buf, uLong size)
{
logGlobal->errorStream() << "Attempt to write to read-only stream";
return 0;
}
ZPOS64_T ZCALLBACK CProxyROIOApi::tellFileProxy(voidpf opaque, voidpf stream)
{
return streamTell<CInputStream>(opaque, stream);
}
long ZCALLBACK CProxyROIOApi::seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
{
return streamSeek<CInputStream>(opaque, stream, offset, origin);
}
int ZCALLBACK CProxyROIOApi::closeFileProxy(voidpf opaque, voidpf stream)
{
return streamProxyClose<CInputStream>(opaque, stream);
}
int ZCALLBACK CProxyROIOApi::errorFileProxy(voidpf opaque, voidpf stream)
{
return 0;
} }

View File

@ -19,7 +19,7 @@
#include "../minizip/zip.h" #include "../minizip/zip.h"
#include "../minizip/ioapi.h" #include "../minizip/ioapi.h"
#endif #endif
class CInputStream;
class CInputOutputStream; class CInputOutputStream;
class CMemoryBuffer; class CMemoryBuffer;
@ -28,22 +28,7 @@ class DLL_LINKAGE CIOApi
public: public:
virtual ~CIOApi(){}; virtual ~CIOApi(){};
virtual zlib_filefunc64_def getApiStructure() const; virtual zlib_filefunc64_def getApiStructure() = 0;
protected:
virtual CInputOutputStream * openFile(const boost::filesystem::path & 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);
static uLong ZCALLBACK writeFileProxy(voidpf opaque, voidpf stream, const void * buf, uLong size);
static ZPOS64_T ZCALLBACK tellFileProxy(voidpf opaque, voidpf stream);
static long ZCALLBACK seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin);
static int ZCALLBACK closeFileProxy(voidpf opaque, voidpf stream);
static int ZCALLBACK errorFileProxy(voidpf opaque, voidpf stream);
}; };
///redirects back to minizip ioapi ///redirects back to minizip ioapi
@ -54,10 +39,7 @@ public:
CDefaultIOApi(); CDefaultIOApi();
~CDefaultIOApi(); ~CDefaultIOApi();
zlib_filefunc64_def getApiStructure() const override; zlib_filefunc64_def getApiStructure() override;
protected:
CInputOutputStream * openFile(const boost::filesystem::path & filename, int mode) const override;
}; };
///redirects all file IO to single stream ///redirects all file IO to single stream
@ -66,9 +48,41 @@ class DLL_LINKAGE CProxyIOApi: public CIOApi
public: public:
CProxyIOApi(CInputOutputStream * buffer); CProxyIOApi(CInputOutputStream * buffer);
~CProxyIOApi(); ~CProxyIOApi();
protected:
CInputOutputStream * openFile(const boost::filesystem::path & filename, int mode) const override; zlib_filefunc64_def getApiStructure() override;
void closeFile(CInputOutputStream * stream) const override;
private: private:
CInputOutputStream * openFile(const boost::filesystem::path & filename, int mode);
CInputOutputStream * data; CInputOutputStream * data;
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 writeFileProxy(voidpf opaque, voidpf stream, const void * buf, uLong size);
static ZPOS64_T ZCALLBACK tellFileProxy(voidpf opaque, voidpf stream);
static long ZCALLBACK seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin);
static int ZCALLBACK closeFileProxy(voidpf opaque, voidpf stream);
static int ZCALLBACK errorFileProxy(voidpf opaque, voidpf stream);
}; };
///redirects all file IO to single stream read-only
class DLL_LINKAGE CProxyROIOApi: public CIOApi
{
public:
CProxyROIOApi(CInputStream * buffer);
~CProxyROIOApi();
zlib_filefunc64_def getApiStructure() override;
private:
CInputStream * openFile(const boost::filesystem::path & filename, int mode);
CInputStream * data;
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 writeFileProxy(voidpf opaque, voidpf stream, const void * buf, uLong size);
static ZPOS64_T ZCALLBACK tellFileProxy(voidpf opaque, voidpf stream);
static long ZCALLBACK seekFileProxy(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin);
static int ZCALLBACK closeFileProxy(voidpf opaque, voidpf stream);
static int ZCALLBACK errorFileProxy(voidpf opaque, voidpf stream);
};

View File

@ -74,8 +74,7 @@ std::unique_ptr<IMapLoader> CMapService::getMapLoader(std::unique_ptr<CInputStre
case 0x06054b50: case 0x06054b50:
case 0x04034b50: case 0x04034b50:
case 0x02014b50: case 0x02014b50:
//return std::unique_ptr<IMapLoader>(new CMapLoaderJson(stream.get())); return std::unique_ptr<IMapLoader>(new CMapLoaderJson(stream.get()));
throw std::runtime_error("Not implemented map format");
break; break;
default: default:
// Check which map format is used // Check which map format is used

View File

@ -221,18 +221,11 @@ void CMapPatcher::readPatchData()
readTriggeredEvents(input); readTriggeredEvents(input);
} }
///CMapFormatZip
CMapFormatZip::CMapFormatZip(CInputOutputStream * stream):
buffer(stream),
ioApi(new CProxyIOApi(buffer))
{
}
///CMapLoaderJson ///CMapLoaderJson
CMapLoaderJson::CMapLoaderJson(CInputOutputStream * stream): CMapLoaderJson::CMapLoaderJson(CInputStream * stream):
CMapFormatZip(stream), buffer(stream),
ioApi(new CProxyROIOApi(buffer)),
loader("", "_", ioApi) loader("", "_", ioApi)
{ {
@ -342,7 +335,7 @@ void CMapLoaderJson::readPlayerInfo(const JsonNode & input)
for(int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++) for(int player = 0; player < PlayerColor::PLAYER_LIMIT_I; player++)
{ {
PlayerInfo & info = map->players.at(player); PlayerInfo & info = mapHeader->players.at(player);
const JsonNode & playerSrc = src[GameConstants::PLAYER_COLOR_NAMES[player]]; const JsonNode & playerSrc = src[GameConstants::PLAYER_COLOR_NAMES[player]];
@ -412,15 +405,15 @@ void CMapLoaderJson::readTeams(const JsonNode& input)
PlayerColor player = PlayerColor(vstd::find_pos(GameConstants::PLAYER_COLOR_NAMES, playerData.String())); PlayerColor player = PlayerColor(vstd::find_pos(GameConstants::PLAYER_COLOR_NAMES, playerData.String()));
if(player.isValidPlayer()) if(player.isValidPlayer())
{ {
if(map->players[player.getNum()].canAnyonePlay()) if(mapHeader->players[player.getNum()].canAnyonePlay())
{ {
map->players[player.getNum()].team = TeamID(team); mapHeader->players[player.getNum()].team = TeamID(team);
} }
} }
} }
} }
for(PlayerInfo & player : map->players) for(PlayerInfo & player : mapHeader->players)
{ {
if(player.canAnyonePlay() && player.team == TeamID::NO_TEAM) if(player.canAnyonePlay() && player.team == TeamID::NO_TEAM)
player.team = TeamID(mapHeader->howManyTeams++); player.team = TeamID(mapHeader->howManyTeams++);
@ -654,7 +647,8 @@ void CMapLoaderJson::readObjects()
///CMapSaverJson ///CMapSaverJson
CMapSaverJson::CMapSaverJson(CInputOutputStream * stream): CMapSaverJson::CMapSaverJson(CInputOutputStream * stream):
CMapFormatZip(stream), buffer(stream),
ioApi(new CProxyIOApi(buffer)),
saver(ioApi, "_") saver(ioApi, "_")
{ {

View File

@ -90,16 +90,7 @@ private:
const JsonNode input; const JsonNode input;
}; };
class DLL_LINKAGE CMapFormatZip : public CMapFormatJson class DLL_LINKAGE CMapLoaderJson : public CMapFormatJson, public IMapLoader
{
public:
CMapFormatZip(CInputOutputStream * stream);
protected:
CInputOutputStream * buffer;
std::shared_ptr<CIOApi> ioApi;
};
class DLL_LINKAGE CMapLoaderJson : public CMapFormatZip, public IMapLoader
{ {
public: public:
/** /**
@ -107,7 +98,7 @@ public:
* *
* @param stream a stream containing the map data * @param stream a stream containing the map data
*/ */
CMapLoaderJson(CInputOutputStream * stream); CMapLoaderJson(CInputStream * stream);
/** /**
* Loads the VCMI/Json map file. * Loads the VCMI/Json map file.
@ -184,10 +175,13 @@ private:
const JsonNode readJson(const std::string & archiveFilename); const JsonNode readJson(const std::string & archiveFilename);
CInputStream * buffer;
std::shared_ptr<CIOApi> ioApi;
CZipLoader loader;///< object to handle zip archive operations CZipLoader loader;///< object to handle zip archive operations
}; };
class DLL_LINKAGE CMapSaverJson : public CMapFormatZip, public IMapSaver class DLL_LINKAGE CMapSaverJson : public CMapFormatJson, public IMapSaver
{ {
public: public:
/** /**
@ -255,5 +249,7 @@ private:
*/ */
void writeObjects(); void writeObjects();
CInputOutputStream * buffer;
std::shared_ptr<CIOApi> ioApi;
CZipSaver saver;///< object to handle zip archive operations CZipSaver saver;///< object to handle zip archive operations
}; };