mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Implemented 'strict' json support
This commit is contained in:
parent
d1c274f93f
commit
41493d6f67
@ -405,6 +405,7 @@ set(lib_HEADERS
|
||||
filesystem/ResourcePath.h
|
||||
|
||||
json/JsonBonus.h
|
||||
json/JsonFormatException.h
|
||||
json/JsonNode.h
|
||||
json/JsonParser.h
|
||||
json/JsonRandom.h
|
||||
|
@ -14,6 +14,11 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct Bonus;
|
||||
class ILimiter;
|
||||
class CSelector;
|
||||
class CAddInfo;
|
||||
|
||||
namespace JsonUtils
|
||||
{
|
||||
DLL_LINKAGE std::shared_ptr<Bonus> parseBonus(const JsonVector & ability_vec);
|
||||
|
20
lib/json/JsonFormatException.h
Normal file
20
lib/json/JsonFormatException.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* JsonFormatException.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
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class JsonFormatException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
using runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
VCMI_LIB_NAMESPACE_END
|
@ -79,8 +79,12 @@ JsonNode::JsonNode(const std::string & string)
|
||||
{}
|
||||
|
||||
JsonNode::JsonNode(const std::byte *data, size_t datasize)
|
||||
:JsonNode(data, datasize, JsonParsingSettings())
|
||||
{}
|
||||
|
||||
JsonNode::JsonNode(const std::byte *data, size_t datasize, const JsonParsingSettings & parserSettings)
|
||||
{
|
||||
JsonParser parser(reinterpret_cast<const char*>(data), datasize);
|
||||
JsonParser parser(reinterpret_cast<const char*>(data), datasize, parserSettings);
|
||||
*this = parser.parse("<unknown>");
|
||||
}
|
||||
|
||||
@ -88,7 +92,7 @@ JsonNode::JsonNode(const JsonPath & fileURI)
|
||||
{
|
||||
auto file = CResourceHandler::get()->load(fileURI)->readAll();
|
||||
|
||||
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second);
|
||||
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second, JsonParsingSettings());
|
||||
*this = parser.parse(fileURI.getName());
|
||||
}
|
||||
|
||||
@ -96,7 +100,7 @@ JsonNode::JsonNode(const JsonPath & fileURI, const std::string & idx)
|
||||
{
|
||||
auto file = CResourceHandler::get(idx)->load(fileURI)->readAll();
|
||||
|
||||
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second);
|
||||
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second, JsonParsingSettings());
|
||||
*this = parser.parse(fileURI.getName());
|
||||
}
|
||||
|
||||
@ -104,7 +108,7 @@ JsonNode::JsonNode(const JsonPath & fileURI, bool &isValidSyntax)
|
||||
{
|
||||
auto file = CResourceHandler::get()->load(fileURI)->readAll();
|
||||
|
||||
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second);
|
||||
JsonParser parser(reinterpret_cast<char*>(file.first.get()), file.second, JsonParsingSettings());
|
||||
*this = parser.parse(fileURI.getName());
|
||||
isValidSyntax = parser.isValid();
|
||||
}
|
||||
|
@ -17,10 +17,23 @@ class JsonNode;
|
||||
using JsonMap = std::map<std::string, JsonNode>;
|
||||
using JsonVector = std::vector<JsonNode>;
|
||||
|
||||
struct Bonus;
|
||||
class CSelector;
|
||||
class CAddInfo;
|
||||
class ILimiter;
|
||||
struct JsonParsingSettings
|
||||
{
|
||||
enum class JsonFormatMode
|
||||
{
|
||||
JSON, // strict implementation of json format
|
||||
JSONC, // json format that also allows comments that start from '//'
|
||||
//JSON5 // TODO?
|
||||
};
|
||||
|
||||
JsonFormatMode mode = JsonFormatMode::JSONC;
|
||||
|
||||
/// Maximum depth of elements
|
||||
uint32_t maxDepth = 30;
|
||||
|
||||
/// If set to true, parser will throw on any encountered error
|
||||
bool strict = false;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE JsonNode
|
||||
{
|
||||
@ -58,6 +71,7 @@ public:
|
||||
|
||||
/// Create tree from Json-formatted input
|
||||
explicit JsonNode(const std::byte * data, size_t datasize);
|
||||
explicit JsonNode(const std::byte * data, size_t datasize, const JsonParsingSettings & parserSettings);
|
||||
|
||||
/// Create tree from JSON file
|
||||
explicit JsonNode(const JsonPath & fileURI);
|
||||
|
@ -11,12 +11,14 @@
|
||||
#include "StdInc.h"
|
||||
#include "JsonParser.h"
|
||||
|
||||
#include "JsonFormatException.h"
|
||||
#include "../TextOperations.h"
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
JsonParser::JsonParser(const char * inputString, size_t stringSize):
|
||||
JsonParser::JsonParser(const char * inputString, size_t stringSize, const JsonParsingSettings & settings):
|
||||
input(inputString, stringSize),
|
||||
settings(settings),
|
||||
lineCount(1),
|
||||
lineStart(0),
|
||||
pos(0)
|
||||
@ -105,9 +107,13 @@ bool JsonParser::extractWhitespace(bool verbose)
|
||||
}
|
||||
pos++;
|
||||
}
|
||||
|
||||
if (pos >= input.size() || input[pos] != '/')
|
||||
break;
|
||||
|
||||
if (settings.mode == JsonParsingSettings::JsonFormatMode::JSON)
|
||||
error("Comments are not permitted in json!", true);
|
||||
|
||||
pos++;
|
||||
if (pos == input.size())
|
||||
break;
|
||||
@ -346,9 +352,8 @@ bool JsonParser::extractElement(JsonNode &node, char terminator)
|
||||
|
||||
if (input[pos] == terminator)
|
||||
{
|
||||
//FIXME: MOD COMPATIBILITY: Too many of these right now, re-enable later
|
||||
//if (comma)
|
||||
//error("Extra comma found!", true);
|
||||
if (comma)
|
||||
error("Extra comma found!", true);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -456,6 +461,9 @@ bool JsonParser::extractFloat(JsonNode &node)
|
||||
|
||||
bool JsonParser::error(const std::string &message, bool warning)
|
||||
{
|
||||
if (settings.strict)
|
||||
throw JsonFormatException(message);
|
||||
|
||||
std::ostringstream stream;
|
||||
std::string type(warning?" warning: ":" error: ");
|
||||
|
||||
|
@ -16,6 +16,8 @@ VCMI_LIB_NAMESPACE_BEGIN
|
||||
//Internal class for string -> JsonNode conversion
|
||||
class JsonParser
|
||||
{
|
||||
const JsonParsingSettings settings;
|
||||
|
||||
std::string errors; // Contains description of all encountered errors
|
||||
std::string_view input; // Input data
|
||||
ui32 lineCount; // Currently parsed line, starting from 1
|
||||
@ -44,7 +46,7 @@ class JsonParser
|
||||
bool error(const std::string &message, bool warning=false);
|
||||
|
||||
public:
|
||||
JsonParser(const char * inputString, size_t stringSize);
|
||||
JsonParser(const char * inputString, size_t stringSize, const JsonParsingSettings & settings);
|
||||
|
||||
/// do actual parsing. filename is name of file that will printed to console if any errors were found
|
||||
JsonNode parse(const std::string & fileName);
|
||||
|
@ -14,6 +14,8 @@
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
struct Bonus;
|
||||
|
||||
namespace spells
|
||||
{
|
||||
namespace effects
|
||||
|
Loading…
Reference in New Issue
Block a user