mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	print json in compact format
This commit is contained in:
		| @@ -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" | ||||
| 					} | ||||
| 				}, | ||||
|   | ||||
| @@ -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)); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
| { | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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)) | ||||
|   | ||||
| @@ -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) | ||||
| 	{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user