Selaa lähdekoodia

print json in compact format

Henning Koehler 8 vuotta sitten
vanhempi
sitoutus
6ae103dd63
6 muutettua tiedostoa jossa 71 lisäystä ja 37 poistoa
  1. 4 13
      config/heroes/castle.json
  2. 4 4
      lib/CHeroHandler.cpp
  3. 27 14
      lib/JsonDetail.cpp
  4. 5 1
      lib/JsonDetail.h
  5. 29 4
      lib/JsonNode.cpp
  6. 2 1
      lib/JsonNode.h

+ 4 - 13
config/heroes/castle.json

@@ -17,7 +17,7 @@
 					"valueType" : "PERCENT_TO_BASE",
 					"updater" : {
 						"type" : "GROWS_WITH_LEVEL",
-						"parameters" : [100]
+						"parameters" : [ 100 ]
 					}
 				}
 			}
@@ -36,10 +36,7 @@
 		"specialty" : {
 			"base" : {
 				"limiter" : {
-					"parameters" : [
-						"archer",
-						true
-					],
+					"parameters" : [ "archer", true ],
 					"type" : "CREATURE_TYPE_LIMITER"
 				}
 			},
@@ -48,10 +45,7 @@
 					"subtype" : "primSkill.attack",
 					"type" : "PRIMARY_SKILL",
 					"updater" : {
-						"parameters" : [
-							6,
-							2
-						],
+						"parameters" : [ 6, 2 ],
 						"type" : "GROWS_WITH_LEVEL"
 					}
 				},
@@ -59,10 +53,7 @@
 					"subtype" : "primSkill.defence",
 					"type" : "PRIMARY_SKILL",
 					"updater" : {
-						"parameters" : [
-							3,
-							2
-						],
+						"parameters" : [ 3, 2 ],
 						"type" : "GROWS_WITH_LEVEL"
 					}
 				},

+ 4 - 4
lib/CHeroHandler.cpp

@@ -537,7 +537,7 @@ void CHeroHandler::beforeValidate(JsonNode & object)
 {
 	//handle "base" specialty info
 	const JsonNode & specialtyNode = object["specialty"];
-	if(specialtyNode.getType() == JsonNode::DATA_STRUCT)
+	if(specialtyNode.getType() == JsonNode::JsonType::DATA_STRUCT)
 	{
 		const JsonNode & base = specialtyNode["base"];
 		if(!base.isNull())
@@ -577,7 +577,7 @@ void CHeroHandler::loadHeroSpecialty(CHero * hero, const JsonNode & node)
 	}
 	//new(er) format, using bonus system
 	const JsonNode & specialtyNode = node["specialty"];
-	if(specialtyNode.getType() == JsonNode::DATA_VECTOR)
+	if(specialtyNode.getType() == JsonNode::JsonType::DATA_VECTOR)
 	{
 		//deprecated middle-aged format
 		for(const JsonNode & specialty : node["specialty"].Vector())
@@ -586,7 +586,7 @@ void CHeroHandler::loadHeroSpecialty(CHero * hero, const JsonNode & node)
 				hero->specialty.push_back(prepSpec(JsonUtils::parseBonus(bonus)));
 		}
 	}
-	else if(specialtyNode.getType() == JsonNode::DATA_STRUCT)
+	else if(specialtyNode.getType() == JsonNode::JsonType::DATA_STRUCT)
 	{
 		//proper new format
 		for(auto keyValue : specialtyNode["bonuses"].Struct())
@@ -792,7 +792,7 @@ void CHeroHandler::afterLoadFinalization()
 			specNode["bonuses"].Struct();
 			for(int i = 0; i < specVec.size(); i++)
 				specNode["bonuses"][specNames[i]] = specVec[i];
-			logMod->trace("\"specialty\" : %s", specNode.toJson());
+			logMod->trace("\"specialty\" : %s", specNode.toJson(true));
 		}
 	}
 }

+ 27 - 14
lib/JsonDetail.cpp

@@ -32,19 +32,22 @@ void JsonWriter::writeContainer(Iterator begin, Iterator end)
 
 	while (begin != end)
 	{
-		out<<",\n";
+		out << (compactMode ? ", " : ",\n");
 		writeEntry(begin++);
 	}
 
-	out<<"\n";
+	out << (compactMode ? "" : "\n");
 	prefix.resize(prefix.size()-1);
 }
 
 void JsonWriter::writeEntry(JsonMap::const_iterator entry)
 {
-	if (!entry->second.meta.empty())
-		out << prefix << " // " << entry->second.meta << "\n";
-	out << prefix;
+	if(!compactMode)
+	{
+		if (!entry->second.meta.empty())
+			out << prefix << " // " << entry->second.meta << "\n";
+		out << prefix;
+	}
 	writeString(entry->first);
 	out << " : ";
 	writeNode(entry->second);
@@ -52,9 +55,12 @@ void JsonWriter::writeEntry(JsonMap::const_iterator entry)
 
 void JsonWriter::writeEntry(JsonVector::const_iterator entry)
 {
-	if (!entry->meta.empty())
-		out << prefix << " // " << entry->meta << "\n";
-	out << prefix;
+	if(!compactMode)
+	{
+		if (!entry->meta.empty())
+			out << prefix << " // " << entry->meta << "\n";
+		out << prefix;
+	}
 	writeNode(*entry);
 }
 
@@ -94,6 +100,10 @@ void JsonWriter::writeString(const std::string &string)
 
 void JsonWriter::writeNode(const JsonNode &node)
 {
+	bool originalMode = compactMode;
+	if(compact && !compactMode && node.isCompact())
+		compactMode = true;
+
 	switch(node.getType())
 	{
 		break; case JsonNode::JsonType::DATA_NULL:
@@ -112,21 +122,24 @@ void JsonWriter::writeNode(const JsonNode &node)
 			writeString(node.String());
 
 		break; case JsonNode::JsonType::DATA_VECTOR:
-			out << "[" << "\n";
+			out << "[" << (compactMode ? " " : "\n");
 			writeContainer(node.Vector().begin(), node.Vector().end());
-			out << prefix << "]";
+			out << (compactMode ? " " : prefix) << "]";
 
 		break; case JsonNode::JsonType::DATA_STRUCT:
-			out << "{" << "\n";
+			out << "{" << (compactMode ? " " : "\n");
 			writeContainer(node.Struct().begin(), node.Struct().end());
-			out << prefix << "}";
+			out << (compactMode ? " " : prefix) << "}";
+
 		break; case JsonNode::JsonType::DATA_INTEGER:
 			out << node.Integer();
 	}
+
+	compactMode = originalMode;
 }
 
-JsonWriter::JsonWriter(std::ostream & output)
-	: out(output)
+JsonWriter::JsonWriter(std::ostream & output, bool compact)
+	: out(output), compact(compact)
 {
 }
 

+ 5 - 1
lib/JsonDetail.h

@@ -16,6 +16,10 @@ class JsonWriter
 	//prefix for each line (tabulation)
 	std::string prefix;
 	std::ostream & out;
+	//sets whether compact nodes are written in single-line format
+	bool compact;
+	//tracks whether we are currently using single-line format
+	bool compactMode = false;
 public:
 	template<typename Iterator>
 	void writeContainer(Iterator begin, Iterator end);
@@ -23,7 +27,7 @@ public:
 	void writeEntry(JsonVector::const_iterator entry);
 	void writeString(const std::string & string);
 	void writeNode(const JsonNode & node);
-	JsonWriter(std::ostream & output);
+	JsonWriter(std::ostream & output, bool compact = false);
 };
 
 //Tiny string class that uses const char* as data for speed, members are private

+ 29 - 4
lib/JsonNode.cpp

@@ -232,6 +232,31 @@ bool JsonNode::isEmpty() const
 	}
 }
 
+bool JsonNode::isCompact() const
+{
+	switch(type)
+	{
+		case JsonType::DATA_VECTOR:
+			for(JsonNode & elem : *data.Vector)
+			{
+				if(!elem.isCompact())
+					return false;
+			}
+			return true;
+		case JsonType::DATA_STRUCT:
+			{
+				int propertyCount = data.Struct->size();
+				if(propertyCount == 0)
+					return true;
+				else if(propertyCount == 1)
+					return data.Struct->begin()->second.isCompact();
+			}
+			return false;
+		default:
+			return true;
+	}
+}
+
 void JsonNode::clear()
 {
 	setType(JsonType::DATA_NULL);
@@ -385,10 +410,10 @@ JsonNode & JsonNode::resolvePointer(const std::string &jsonPointer)
 	return ::resolvePointer(*this, jsonPointer);
 }
 
-std::string JsonNode::toJson() const
+std::string JsonNode::toJson(bool compact) const
 {
 	std::ostringstream out;
-	JsonWriter writer(out);
+	JsonWriter writer(out, compact);
 	writer.writeNode(*this);
 	out << "\n";
 	return out.str();
@@ -901,10 +926,10 @@ JsonNode JsonUtils::intersect(const JsonNode & a, const JsonNode & b, bool prune
 
 JsonNode JsonUtils::difference(const JsonNode & node, const JsonNode & base)
 {
-	if(node.getType() == JsonNode::DATA_STRUCT && base.getType() == JsonNode::DATA_STRUCT)
+	if(node.getType() == JsonNode::JsonType::DATA_STRUCT && base.getType() == JsonNode::JsonType::DATA_STRUCT)
 	{
 		// subtract individual properties
-		JsonNode result(JsonNode::DATA_STRUCT);
+		JsonNode result(JsonNode::JsonType::DATA_STRUCT);
 		for(auto property : node.Struct())
 		{
 			if(vstd::contains(base.Struct(), property.first))

+ 2 - 1
lib/JsonNode.h

@@ -76,6 +76,7 @@ public:
 	bool isNull() const;
 	bool isNumber() const;
 	bool isEmpty() const;
+	bool isCompact() const;
 	/// removes all data from node and sets type to null
 	void clear();
 
@@ -111,7 +112,7 @@ public:
 	JsonNode & operator[](std::string child);
 	const JsonNode & operator[](std::string child) const;
 
-	std::string toJson() const;
+	std::string toJson(bool compact = false) const;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{