mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	JsonCpp to QTJson (Part 5) (#270)
* Update Hyperion.h * Update ImageProcessorFactory.h * Update ProtoConnection.h * Update WebConfig.h * Update CMakeLists.txt * Update Hyperion.cpp * Update CMakeLists.txt * Update CMakeLists.txt * Update CgiHandler.cpp * Update CgiHandler.h * Update WebConfig.cpp * Update CMakeLists.txt * Update hyperion-remote.cpp * Update JsonConnection.cpp * Update JsonConnection.h * Update hyperiond.cpp * Update hyperiond.h * Delete JsonFactory.h * Delete JsonSchemaChecker.h * Delete JsonSchemaChecker.cpp * Update WebConfig.cpp
This commit is contained in:
		
				
					committed by
					
						 redPanther
						redPanther
					
				
			
			
				
	
			
			
			
						parent
						
							102fd611fa
						
					
				
				
					commit
					ebbb6b9440
				
			| @@ -74,7 +74,7 @@ public: | ||||
| 	}; | ||||
|  | ||||
| 	/// | ||||
| 	/// Destructor; cleans up resourcess | ||||
| 	/// Destructor; cleans up resources | ||||
| 	/// | ||||
| 	~Hyperion(); | ||||
|  | ||||
| @@ -128,7 +128,6 @@ public: | ||||
| 	 | ||||
| 	/// gets the current json config object | ||||
| 	/// @return json config | ||||
| 	const Json::Value& getJsonConfig() { return _jsonConfig; }; | ||||
| 	const QJsonObject& getQJsonConfig() { return _qjsonConfig; }; | ||||
|  | ||||
| 	/// get filename of configfile | ||||
| @@ -149,7 +148,7 @@ public: | ||||
| 	const PriorityRegister& getPriorityRegister() { return _priorityRegister; } | ||||
| 	 | ||||
| 	/// enable/disable automatic/priorized source selection | ||||
| 	/// @param enable the state | ||||
| 	/// @param enabled the state | ||||
| 	void setSourceAutoSelectEnabled(bool enabled); | ||||
| 	 | ||||
| 	/// set current input source to visible | ||||
| @@ -244,14 +243,14 @@ public slots: | ||||
| 	/// Run the specified effect on the given priority channel and optionally specify a timeout | ||||
| 	/// @param effectName Name of the effec to run | ||||
| 	///	@param priority The priority channel of the effect | ||||
| 	/// @param timout The timeout of the effect (after the timout, the effect will be cleared) | ||||
| 	/// @param timeout The timeout of the effect (after the timout, the effect will be cleared) | ||||
| 	int setEffect(const QString & effectName, int priority, int timeout = -1); | ||||
|  | ||||
| 	/// Run the specified effect on the given priority channel and optionally specify a timeout | ||||
| 	/// @param effectName Name of the effec to run | ||||
| 	/// @param args arguments of the effect script | ||||
| 	///	@param priority The priority channel of the effect | ||||
| 	/// @param timout The timeout of the effect (after the timout, the effect will be cleared) | ||||
| 	/// @param timeout The timeout of the effect (after the timout, the effect will be cleared) | ||||
| 	int setEffect(const QString & effectName, const QJsonObject & args, int priority, int timeout = -1); | ||||
|  | ||||
| public: | ||||
|   | ||||
| @@ -6,14 +6,6 @@ | ||||
| // QT includes | ||||
| #include <QJsonObject> | ||||
|  | ||||
| //	if (jsoncpp_converted_to_QtJSON) | ||||
| //	{ | ||||
| //		remove("#include <json/json.h>"); | ||||
| //	} | ||||
|  | ||||
| // Jsoncpp includes | ||||
| #include <json/json.h> | ||||
|  | ||||
| #include <hyperion/LedString.h> | ||||
|  | ||||
| // Forward class declaration | ||||
| @@ -38,8 +30,7 @@ public: | ||||
| 	/// Initialises this factory with the given led-configuration | ||||
| 	/// | ||||
| 	/// @param[in] ledString  The led configuration | ||||
| 	/// @param[in] enableBlackBorderDetector Flag indicating if the blacborder detector should be enabled | ||||
| 	/// @param[in] blackborderThreshold The threshold which the blackborder detector should use | ||||
| 	/// @param[in] blackborderConfig Contains the blackborder configuration | ||||
| 	/// | ||||
| 	void init(const LedString& ledString, const QJsonObject &blackborderConfig); | ||||
|  | ||||
|   | ||||
| @@ -17,7 +17,6 @@ | ||||
| #include <utils/VideoMode.h> | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| // jsoncpp includes | ||||
| #include <message.pb.h> | ||||
|  | ||||
| /// | ||||
|   | ||||
| @@ -1,74 +0,0 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include <istream> | ||||
| #include <fstream> | ||||
| #include <stdexcept> | ||||
| #include <sstream> | ||||
|  | ||||
| // JSON-Schema includes | ||||
| #include <utils/jsonschema/JsonSchemaChecker.h> | ||||
|  | ||||
| class JsonFactory | ||||
| { | ||||
| public: | ||||
|  | ||||
| 	static int load(const std::string& schema, const std::istream& config, Json::Value json); | ||||
|  | ||||
| 	static int load(const std::string& schema, const std::string& config, Json::Value& json) | ||||
| 	{ | ||||
| 		// Load the schema and the config trees | ||||
| 		Json::Value schemaTree = readJson(schema); | ||||
| 		Json::Value configTree = readJson(config); | ||||
|  | ||||
| 		// create the validator | ||||
| 		JsonSchemaChecker schemaChecker; | ||||
| 		schemaChecker.setSchema(schemaTree); | ||||
|  | ||||
| 		bool valid = schemaChecker.validate(configTree); | ||||
| 		for (const std::string& message : schemaChecker.getMessages()) | ||||
| 		{ | ||||
| 			std::cout << message << std::endl; | ||||
| 		} | ||||
| 		if (!valid) | ||||
| 		{ | ||||
| 			std::cerr << "Validation failed for configuration file: " << config.c_str() << std::endl; | ||||
| 			return -3; | ||||
| 		} | ||||
|  | ||||
| 		json = configTree; | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	static Json::Value readJson(const std::string& filename) | ||||
| 	{ | ||||
| 		// Open the file input stream | ||||
| 		std::ifstream ifs(filename.c_str()); | ||||
| 		return readJson(ifs); | ||||
| 	} | ||||
|  | ||||
| 	static Json::Value readJson(std::istream& stream) | ||||
| 	{ | ||||
| 		// will contains the root value after parsing. | ||||
| 		Json::Value jsonTree; | ||||
|  | ||||
| 		Json::Reader reader; | ||||
| 		if (! reader.parse(stream, jsonTree, false)) | ||||
| 		{ | ||||
| 			// report to the user the failure and their locations in the document. | ||||
| 			std::stringstream sstream; | ||||
| 			sstream << "Failed to parse configuration: " << reader.getFormattedErrorMessages().c_str(); | ||||
|  | ||||
| 			throw std::runtime_error(sstream.str()); | ||||
| 		} | ||||
| 		return jsonTree; | ||||
| 	} | ||||
|  | ||||
| 	static void writeJson(const std::string& filename, Json::Value& jsonTree) | ||||
| 	{ | ||||
| 		Json::StyledStreamWriter writer; | ||||
| 		 | ||||
| 		std::ofstream ofs(filename.c_str()); | ||||
| 		writer.write(ofs, jsonTree); | ||||
| 	} | ||||
| }; | ||||
| @@ -1,194 +0,0 @@ | ||||
| #pragma once | ||||
|  | ||||
| // stl includes | ||||
| #include <string> | ||||
| #include <list> | ||||
|  | ||||
| // jsoncpp includes | ||||
| #include <json/json.h> | ||||
|  | ||||
|  | ||||
| /// JsonSchemaChecker is a very basic implementation of json schema. | ||||
| /// The json schema definition draft can be found at | ||||
| /// http://tools.ietf.org/html/draft-zyp-json-schema-03 | ||||
| /// | ||||
| /// The following keywords are supported: | ||||
| /// - type | ||||
| /// - required | ||||
| /// - properties | ||||
| /// - items | ||||
| /// - enum | ||||
| /// - minimum | ||||
| /// - maximum | ||||
| /// - addtionalProperties | ||||
| /// - minItems | ||||
| /// - maxItems | ||||
| /// | ||||
| /// And the non-standard: | ||||
| /// - dependencies | ||||
| class JsonSchemaChecker | ||||
| { | ||||
| public: | ||||
| 	JsonSchemaChecker(); | ||||
| 	virtual ~JsonSchemaChecker(); | ||||
|  | ||||
| 	/// | ||||
| 	/// @param schema The schema to use | ||||
| 	/// @return true upon succes | ||||
| 	/// | ||||
| 	bool setSchema(const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// @brief Validate a JSON structure | ||||
| 	/// @param value The JSON value to check | ||||
| 	/// @return true when the arguments is valid according to the schema | ||||
| 	/// | ||||
| 	bool validate(const Json::Value & value, bool ignoreRequired = false); | ||||
|  | ||||
| 	/// | ||||
| 	/// @return A list of error messages | ||||
| 	/// | ||||
| 	const std::list<std::string> & getMessages() const; | ||||
|  | ||||
| private: | ||||
| 	/// | ||||
| 	/// Validates a json-value against a given schema. Results are stored in the members of this | ||||
| 	/// class (_error & _messages) | ||||
| 	/// | ||||
| 	/// @param[in] value The value to validate | ||||
| 	/// @param[in] schema The schema against which the value is validated | ||||
| 	/// | ||||
| 	void validate(const Json::Value &value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Adds the given message to the message-queue (with reference to current line-number) | ||||
| 	/// | ||||
| 	/// @param[in] message The message to add to the queue | ||||
| 	/// | ||||
| 	void setMessage(const std::string & message); | ||||
|  | ||||
| 	/// | ||||
| 	/// Retrieves all references from the json-value as specified by the schema | ||||
| 	/// | ||||
| 	/// @param[in] value The json-value | ||||
| 	/// @param[in] schema The schema | ||||
| 	/// | ||||
| 	void collectDependencies(const Json::Value & value, const Json::Value &schema); | ||||
|  | ||||
| private: | ||||
| 	// attribute check functions | ||||
| 	/// | ||||
| 	/// Checks if the given value is of the specified type. If the type does not match _error is set | ||||
| 	/// to true and an error-message is added to the message-queue | ||||
| 	/// | ||||
| 	/// @param[in] value The given value | ||||
| 	/// @param[in] schema The specified type (as json-value) | ||||
| 	/// | ||||
| 	void checkType(const Json::Value & value, const Json::Value & schema); | ||||
| 	/// | ||||
| 	/// Checks is required properties of an json-object exist and if all properties are of the | ||||
| 	/// correct format. If this is not the case _error is set to true and an error-message is added | ||||
| 	/// to the message-queue. | ||||
| 	/// | ||||
| 	/// @param[in] value The given json-object | ||||
| 	/// @param[in] schema The schema of the json-object | ||||
| 	/// | ||||
| 	void checkProperties(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Verifies the additional configured properties of an json-object. If this is not the case | ||||
| 	/// _error is set to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param value The given json-object | ||||
| 	/// @param schema The schema for the json-object | ||||
| 	/// @param ignoredProperties The properties that were ignored | ||||
| 	/// | ||||
| 	void checkAdditionalProperties(const Json::Value & value, const Json::Value & schema, const Json::Value::Members & ignoredProperties); | ||||
|  | ||||
| 	/// | ||||
| 	/// Checks if references are configued and used correctly. If this is not the case _error is set | ||||
| 	/// to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param value The given json-object | ||||
| 	/// @param schemaLink The schema of the json-object | ||||
| 	/// | ||||
| 	void checkDependencies(const Json::Value & value, const Json::Value & schemaLink); | ||||
|  | ||||
| 	/// | ||||
| 	/// Checks if the given value is larger or equal to the specified value. If this is not the case | ||||
| 	/// _error is set to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param[in] value The given value | ||||
| 	/// @param[in] schema The minimum value (as json-value) | ||||
| 	/// | ||||
| 	void checkMinimum(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Checks if the given value is smaller or equal to the specified value. If this is not the | ||||
| 	/// case _error is set to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param[in] value The given value | ||||
| 	/// @param[in] schema The maximum value (as json-value) | ||||
| 	/// | ||||
| 	void checkMaximum(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Validates all the items of an array. | ||||
| 	/// | ||||
| 	/// @param value The json-array | ||||
| 	/// @param schema The schema for the items in the array | ||||
| 	/// | ||||
| 	void checkItems(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Checks if a given array has at least a minimum number of items. If this is not the case | ||||
| 	/// _error is set to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param value The json-array | ||||
| 	/// @param schema The minimum size specification (as json-value) | ||||
| 	/// | ||||
| 	void checkMinItems(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Checks if a given array has at most a maximum number of items. If this is not the case | ||||
| 	/// _error is set to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param value The json-array | ||||
| 	/// @param schema The maximum size specification (as json-value) | ||||
| 	/// | ||||
| 	void checkMaxItems(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Checks if a given array contains only unique items. If this is not the case | ||||
| 	/// _error is set to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param value The json-array | ||||
| 	/// @param schema Bool to enable the check (as json-value) | ||||
| 	/// | ||||
| 	void checkUniqueItems(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| 	/// | ||||
| 	/// Checks if an enum value is actually a valid value for that enum. If this is not the case | ||||
| 	/// _error is set to true and an error-message is added to the message-queue. | ||||
| 	/// | ||||
| 	/// @param value The enum value | ||||
| 	/// @param schema The enum schema definition | ||||
| 	/// | ||||
| 	void checkEnum(const Json::Value & value, const Json::Value & schema); | ||||
|  | ||||
| private: | ||||
| 	/// The schema of the entire json-configuration | ||||
| 	Json::Value _schema; | ||||
| 	/// ignore the required value in json schema | ||||
| 	bool _ignoreRequired; | ||||
|  | ||||
| 	/// The current location into a json-configuration structure being checked | ||||
| 	std::list<std::string> _currentPath; | ||||
| 	/// The result messages collected during the schema verification | ||||
| 	std::list<std::string> _messages; | ||||
| 	/// Flag indicating an error occured during validation | ||||
| 	bool _error; | ||||
|  | ||||
| 	/// A list with references (string => json-value) | ||||
| 	std::map<std::string, const Json::Value *> _references; // ref 2 value | ||||
| }; | ||||
| @@ -4,7 +4,6 @@ | ||||
| #include <QObject> | ||||
| #include <QString> | ||||
| #include <string> | ||||
| #include <utils/jsonschema/JsonFactory.h> | ||||
| #include <hyperion/Hyperion.h> | ||||
|  | ||||
| class StaticFileServing; | ||||
|   | ||||
| @@ -52,6 +52,5 @@ qt5_use_modules(effectengine Core Gui) | ||||
|  | ||||
| target_link_libraries(effectengine | ||||
| 	hyperion | ||||
| 	jsoncpp | ||||
| 	${QT_LIBRARIES} | ||||
| 	${PYTHON_LIBRARIES}) | ||||
|   | ||||
| @@ -13,9 +13,6 @@ | ||||
| #include <QCryptographicHash> | ||||
| #include <QFile> | ||||
|  | ||||
| // JsonSchema include | ||||
| #include <utils/jsonschema/JsonFactory.h> | ||||
|  | ||||
| // hyperion include | ||||
| #include <hyperion/Hyperion.h> | ||||
| #include <hyperion/ImageProcessorFactory.h> | ||||
|   | ||||
| @@ -38,5 +38,4 @@ qt5_use_modules(jsonserver Network) | ||||
| target_link_libraries(jsonserver | ||||
| 	hyperion | ||||
| 	hyperion-utils | ||||
| 	jsoncpp | ||||
| 	${QT_LIBRARIES}) | ||||
|   | ||||
| @@ -46,10 +46,6 @@ add_library(hyperion-utils | ||||
| 	${CURRENT_HEADER_DIR}/RgbToRgbw.h | ||||
| 	${CURRENT_SOURCE_DIR}/RgbToRgbw.cpp | ||||
|  | ||||
| 	${CURRENT_HEADER_DIR}/jsonschema/JsonFactory.h | ||||
| 	${CURRENT_HEADER_DIR}/jsonschema/JsonSchemaChecker.h | ||||
| 	${CURRENT_SOURCE_DIR}/jsonschema/JsonSchemaChecker.cpp | ||||
|  | ||||
| 	${CURRENT_HEADER_DIR}/jsonschema/QJsonFactory.h | ||||
| 	${CURRENT_HEADER_DIR}/jsonschema/QJsonSchemaChecker.h | ||||
| 	${CURRENT_SOURCE_DIR}/jsonschema/QJsonSchemaChecker.cpp | ||||
|   | ||||
| @@ -1,465 +0,0 @@ | ||||
| // stdlib includes | ||||
| #include <cassert> | ||||
| #include <iterator> | ||||
| #include <sstream> | ||||
| #include <algorithm> | ||||
|  | ||||
| // Utils-Jsonschema includes | ||||
| #include <utils/jsonschema/JsonSchemaChecker.h> | ||||
|  | ||||
| JsonSchemaChecker::JsonSchemaChecker() | ||||
| { | ||||
| 	// empty | ||||
| } | ||||
|  | ||||
| JsonSchemaChecker::~JsonSchemaChecker() | ||||
| { | ||||
| 	// empty | ||||
| } | ||||
|  | ||||
| bool JsonSchemaChecker::setSchema(const Json::Value & schema) | ||||
| { | ||||
| 	_schema = schema; | ||||
|  | ||||
| 	// TODO: check the schema | ||||
|  | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool JsonSchemaChecker::validate(const Json::Value & value, bool ignoreRequired) | ||||
| { | ||||
| 	// initialize state | ||||
| 	_ignoreRequired = ignoreRequired; | ||||
| 	_error = false; | ||||
| 	_messages.clear(); | ||||
| 	_currentPath.clear(); | ||||
| 	_currentPath.push_back("[root]"); | ||||
| 	_references.clear(); | ||||
|  | ||||
| 	// collect dependencies | ||||
| 	collectDependencies(value, _schema); | ||||
|  | ||||
| 	// validate | ||||
| 	validate(value, _schema); | ||||
|  | ||||
| 	return !_error; | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::collectDependencies(const Json::Value & value, const Json::Value &schema) | ||||
| { | ||||
| 	assert (schema.isObject()); | ||||
|  | ||||
| 	// check if id is present | ||||
| 	if (schema.isMember("id")) | ||||
| 	{ | ||||
| 		// strore reference | ||||
| 		assert (schema["id"].isString()); | ||||
| 		std::ostringstream ref; | ||||
| 		ref << "$(" << schema["id"].asString() << ")"; | ||||
| 		_references[ref.str()] = &value; | ||||
| 	} | ||||
|  | ||||
| 	// check the current json value | ||||
| 	if (schema.isMember("properties")) | ||||
| 	{ | ||||
| 		const Json::Value & properties = schema["properties"]; | ||||
| 		assert(properties.isObject()); | ||||
|  | ||||
| 		for (Json::Value::const_iterator j = properties.begin(); j != properties.end(); ++j) | ||||
| 		{ | ||||
| 			std::string property = j.memberName(); | ||||
| 			if (value.isMember(property)) | ||||
| 			{ | ||||
| 				collectDependencies(value[property], properties[property]); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::validate(const Json::Value & value, const Json::Value &schema) | ||||
| { | ||||
| 	assert (schema.isObject()); | ||||
|  | ||||
| 	// check the current json value | ||||
| 	for (Json::Value::const_iterator i = schema.begin(); i != schema.end(); ++i) | ||||
| 	{ | ||||
| 		std::string attribute = i.memberName(); | ||||
| 		const Json::Value & attributeValue = *i; | ||||
|  | ||||
| 		if (attribute == "type") | ||||
| 			checkType(value, attributeValue); | ||||
| 		else if (attribute == "properties") | ||||
| 			checkProperties(value, attributeValue); | ||||
| 		else if (attribute == "additionalProperties") | ||||
| 		{ | ||||
| 			// ignore the properties which are handled by the properties attribute (if present) | ||||
| 			Json::Value::Members ignoredProperties; | ||||
| 			if (schema.isMember("properties")) { | ||||
| 				const Json::Value & props = schema["properties"]; | ||||
| 				ignoredProperties = props.getMemberNames(); | ||||
| 			} | ||||
|  | ||||
| 			checkAdditionalProperties(value, attributeValue, ignoredProperties); | ||||
| 		} | ||||
| 		else if (attribute == "dependencies") | ||||
| 			checkDependencies(value, attributeValue); | ||||
| 		else if (attribute == "minimum") | ||||
| 			checkMinimum(value, attributeValue); | ||||
| 		else if (attribute == "maximum") | ||||
| 			checkMaximum(value, attributeValue); | ||||
| 		else if (attribute == "items") | ||||
| 			checkItems(value, attributeValue); | ||||
| 		else if (attribute == "minItems") | ||||
| 			checkMinItems(value, attributeValue); | ||||
| 		else if (attribute == "maxItems") | ||||
| 			checkMaxItems(value, attributeValue); | ||||
| 		else if (attribute == "uniqueItems") | ||||
| 			checkUniqueItems(value, attributeValue); | ||||
| 		else if (attribute == "enum") | ||||
| 			checkEnum(value, attributeValue); | ||||
| 		else if (attribute == "required") | ||||
| 			; // nothing to do. value is present so always oke | ||||
| 		else if (attribute == "id") | ||||
| 			; // references have already been collected | ||||
| 		else | ||||
| 		{ | ||||
| 			// no check function defined for this attribute | ||||
| 			setMessage(std::string("No check function defined for attribute ") + attribute); | ||||
| 			continue; | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::setMessage(const std::string & message) | ||||
| { | ||||
| 	std::ostringstream oss; | ||||
| 	std::copy(_currentPath.begin(), _currentPath.end(), std::ostream_iterator<std::string>(oss, "")); | ||||
| 	oss << ": " << message; | ||||
| 	_messages.push_back(oss.str()); | ||||
| } | ||||
|  | ||||
| const std::list<std::string> & JsonSchemaChecker::getMessages() const | ||||
| { | ||||
| 	return _messages; | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkType(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isString()); | ||||
|  | ||||
| 	std::string type = schema.asString(); | ||||
| 	bool wrongType = false; | ||||
| 	if (type == "string") | ||||
| 		wrongType = !value.isString(); | ||||
| 	else if (type == "number") | ||||
| 		wrongType = !value.isNumeric(); | ||||
| 	else if (type == "integer") | ||||
| 		wrongType = !value.isIntegral(); | ||||
| 	else if (type == "double") | ||||
| 		wrongType = !value.isDouble(); | ||||
| 	else if (type == "boolean") | ||||
| 		wrongType = !value.isBool(); | ||||
| 	else if (type == "object") | ||||
| 		wrongType = !value.isObject(); | ||||
| 	else if (type == "array") | ||||
| 		wrongType = !value.isArray(); | ||||
| 	else if (type == "null") | ||||
| 		wrongType = !value.isNull(); | ||||
| 	else if (type == "enum") | ||||
| 		wrongType = !value.isString(); | ||||
| 	else if (type == "any") | ||||
| 		wrongType = false; | ||||
| //	else | ||||
| //		assert(false); | ||||
|  | ||||
| 	if (wrongType) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		setMessage(type + " expected"); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkProperties(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isObject()); | ||||
|  | ||||
| 	if (!value.isObject()) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		setMessage("properies attribute is only valid for objects"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	for (Json::Value::const_iterator i = schema.begin(); i != schema.end(); ++i) | ||||
| 	{ | ||||
| 		std::string property = i.memberName(); | ||||
| 		const Json::Value & propertyValue = *i; | ||||
|  | ||||
| 		assert(propertyValue.isObject()); | ||||
|  | ||||
| 		_currentPath.push_back(std::string(".") + property); | ||||
| 		if (value.isMember(property)) | ||||
| 		{ | ||||
| 			validate(value[property], propertyValue); | ||||
| 		} | ||||
| 		else if (propertyValue.get("required", false).asBool() && !_ignoreRequired) | ||||
| 		{ | ||||
| 			_error = true; | ||||
| 			setMessage("missing member"); | ||||
| 		} | ||||
| 		_currentPath.pop_back(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkAdditionalProperties(const Json::Value & value, const Json::Value & schema, const Json::Value::Members & ignoredProperties) | ||||
| { | ||||
| 	if (!value.isObject()) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		setMessage("additional properies attribute is only valid for objects"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	for (Json::Value::const_iterator i = value.begin(); i != value.end(); ++i) | ||||
| 	{ | ||||
| 		std::string property = i.memberName(); | ||||
| 		if (std::find(ignoredProperties.begin(), ignoredProperties.end(), property) == ignoredProperties.end()) | ||||
| 		{ | ||||
| 			// property has no property definition. check against the definition for additional properties | ||||
| 			_currentPath.push_back(std::string(".") + property); | ||||
| 			if (schema.isBool()) | ||||
| 			{ | ||||
| 				if (schema.asBool() == false) | ||||
| 				{ | ||||
| 					_error = true; | ||||
| 					setMessage("no schema definition"); | ||||
| 				} | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				validate(value[property], schema); | ||||
| 			} | ||||
| 			_currentPath.pop_back(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkDependencies(const Json::Value & value, const Json::Value & schemaLink) | ||||
| { | ||||
| 	if (!value.isObject()) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		setMessage("dependencies attribute is only valid for objects"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	assert(schemaLink.isString()); | ||||
| 	std::map<std::string, const Json::Value *>::iterator iter = _references.find(schemaLink.asString()); | ||||
| 	if (iter == _references.end()) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		std::ostringstream oss; | ||||
| 		oss << "reference " << schemaLink.asString() << " could not be resolved"; | ||||
| 		setMessage(oss.str()); | ||||
| 		return; | ||||
| 	} | ||||
| 	const Json::Value & schema = *(iter->second); | ||||
|  | ||||
| 	std::list<std::string> requiredProperties; | ||||
| 	if (schema.isString()) | ||||
| 	{ | ||||
| 		requiredProperties.push_back(schema.asString()); | ||||
| 	} | ||||
| 	else if (schema.isArray()) | ||||
| 	{ | ||||
| 		for (Json::UInt i = 0; i < schema.size(); ++i) | ||||
| 		{ | ||||
| 			assert(schema[i].isString()); | ||||
| 			requiredProperties.push_back(schema[i].asString()); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		std::ostringstream oss; | ||||
| 		oss << "Exepected reference " << schemaLink.asString() << " to resolve to a string or array"; | ||||
| 		setMessage(oss.str()); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	for (std::list<std::string>::const_iterator i = requiredProperties.begin(); i != requiredProperties.end(); ++i) | ||||
| 	{ | ||||
| 		if (!value.isMember(*i)) | ||||
| 		{ | ||||
| 			_error = true; | ||||
| 			std::ostringstream oss; | ||||
| 			oss << "missing member " << *i; | ||||
| 			setMessage(oss.str()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkMinimum(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isNumeric()); | ||||
|  | ||||
| 	if (!value.isNumeric()) | ||||
| 	{ | ||||
| 		// only for numeric | ||||
| 		_error = true; | ||||
| 		setMessage("minimum check only for numeric fields"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (value.asDouble() < schema.asDouble()) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		std::ostringstream oss; | ||||
| 		oss << "value is too small (minimum=" << schema.asDouble() << ")"; | ||||
| 		setMessage(oss.str()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkMaximum(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isNumeric()); | ||||
|  | ||||
| 	if (!value.isNumeric()) | ||||
| 	{ | ||||
| 		// only for numeric | ||||
| 		_error = true; | ||||
| 		setMessage("maximum check only for numeric fields"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (value.asDouble() > schema.asDouble()) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		std::ostringstream oss; | ||||
| 		oss << "value is too large (maximum=" << schema.asDouble() << ")"; | ||||
| 		setMessage(oss.str()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkItems(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isObject()); | ||||
|  | ||||
| 	if (!value.isArray()) | ||||
| 	{ | ||||
| 		// only for arrays | ||||
| 		_error = true; | ||||
| 		setMessage("items only valid for arrays"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	for(Json::ArrayIndex i = 0; i < value.size(); ++i) | ||||
| 	{ | ||||
| 		// validate each item | ||||
| 		std::ostringstream oss; | ||||
| 		oss << "[" << i << "]"; | ||||
| 		_currentPath.push_back(oss.str()); | ||||
| 		validate(value[i], schema); | ||||
| 		_currentPath.pop_back(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkMinItems(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isIntegral()); | ||||
|  | ||||
| 	if (!value.isArray()) | ||||
| 	{ | ||||
| 		// only for arrays | ||||
| 		_error = true; | ||||
| 		setMessage("minItems only valid for arrays"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	int minimum = schema.asInt(); | ||||
|  | ||||
| 	if (static_cast<int>(value.size()) < minimum) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		std::ostringstream oss; | ||||
| 		oss << "array is too small (minimum=" << minimum << ")"; | ||||
| 		setMessage(oss.str()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkMaxItems(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isIntegral()); | ||||
|  | ||||
| 	if (!value.isArray()) | ||||
| 	{ | ||||
| 		// only for arrays | ||||
| 		_error = true; | ||||
| 		setMessage("maxItems only valid for arrays"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	int maximum = schema.asInt(); | ||||
|  | ||||
| 	if (static_cast<int>(value.size()) > maximum) | ||||
| 	{ | ||||
| 		_error = true; | ||||
| 		std::ostringstream oss; | ||||
| 		oss << "array is too large (maximum=" << maximum << ")"; | ||||
| 		setMessage(oss.str()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkUniqueItems(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isBool()); | ||||
|  | ||||
| 	if (!value.isArray()) | ||||
| 	{ | ||||
| 		// only for arrays | ||||
| 		_error = true; | ||||
| 		setMessage("uniqueItems only valid for arrays"); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (schema.asBool() == true) | ||||
| 	{ | ||||
| 		// make sure no two items are identical | ||||
|  | ||||
| 		for(Json::UInt i = 0; i < value.size(); ++i) | ||||
| 		{ | ||||
| 			for (Json::UInt j = i+1; j < value.size(); ++j) | ||||
| 			{ | ||||
| 				if (value[i] == value[j]) | ||||
| 				{ | ||||
| 					// found a value twice | ||||
| 					_error = true; | ||||
| 					setMessage("array must have unique values"); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonSchemaChecker::checkEnum(const Json::Value & value, const Json::Value & schema) | ||||
| { | ||||
| 	assert(schema.isArray()); | ||||
|  | ||||
| 	for(Json::ArrayIndex i = 0; i < schema.size(); ++i) | ||||
| 	{ | ||||
| 		if (schema[i] == value) | ||||
| 		{ | ||||
| 			// found enum value. done. | ||||
| 			return; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// nothing found | ||||
| 	_error = true; | ||||
| 	std::ostringstream oss; | ||||
| 	oss << "Unknown enum value (allowed values are: "; | ||||
| 	std::string values = Json::FastWriter().write(schema); | ||||
| 	oss << values.substr(0, values.size()-1); // The writer append a new line which we don't want | ||||
| 	oss << ")"; | ||||
| 	setMessage(oss.str()); | ||||
| } | ||||
| @@ -11,7 +11,7 @@ | ||||
| CgiHandler::CgiHandler (Hyperion * hyperion, QString baseUrl, QObject * parent) | ||||
| 	: QObject(parent) | ||||
| 	, _hyperion(hyperion) | ||||
| 	, _hyperionConfig(_hyperion->getJsonConfig()) | ||||
| 	, _hyperionConfig(_hyperion->getQJsonConfig()) | ||||
| 	, _baseUrl(baseUrl) | ||||
| { | ||||
| } | ||||
| @@ -44,10 +44,10 @@ void CgiHandler::cmd_cfg_jsonserver(const QStringList & args, QtHttpReply * repl | ||||
| 	if ( args.at(0) == "cfg_jsonserver" ) | ||||
| 	{ | ||||
| 		quint16 jsonPort = 19444; | ||||
| 		if (_hyperionConfig.isMember("jsonServer")) | ||||
| 		if (_hyperionConfig.contains("jsonServer")) | ||||
| 		{ | ||||
| 			const Json::Value & jsonConfig = _hyperionConfig["jsonServer"]; | ||||
| 			jsonPort = jsonConfig.get("port", jsonPort).asUInt(); | ||||
| 			const QJsonObject jsonConfig = _hyperionConfig["jsonServer"].toObject(); | ||||
| 			jsonPort = jsonConfig["port"].toInt(jsonPort); | ||||
| 		} | ||||
|  | ||||
| 		// send result as reply | ||||
|   | ||||
| @@ -5,7 +5,6 @@ | ||||
| #include <QString> | ||||
| #include <QStringList> | ||||
|  | ||||
| #include <utils/jsonschema/JsonFactory.h> | ||||
| #include <hyperion/Hyperion.h> | ||||
|  | ||||
| #include "QtHttpReply.h" | ||||
| @@ -28,7 +27,7 @@ public: | ||||
| private: | ||||
| 	Hyperion*             _hyperion; | ||||
| 	QtHttpReply *         _reply; | ||||
| 	const Json::Value    &_hyperionConfig; | ||||
| 	const QJsonObject    &_hyperionConfig; | ||||
| 	const QString     _baseUrl; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -11,16 +11,16 @@ WebConfig::WebConfig(QObject * parent) | ||||
| 	Logger* log = Logger::getInstance("WEBSERVER"); | ||||
| 	_port       = WEBCONFIG_DEFAULT_PORT; | ||||
| 	_baseUrl    = WEBCONFIG_DEFAULT_PATH; | ||||
| 	const Json::Value &config = _hyperion->getJsonConfig(); | ||||
| 	const QJsonObject config = _hyperion->getQJsonConfig(); | ||||
| 	 | ||||
| 	bool webconfigEnable = true;  | ||||
|  | ||||
| 	if (config.isMember("webConfig")) | ||||
| 	if (config.contains("webConfig")) | ||||
| 	{ | ||||
| 		const Json::Value & webconfigConfig = config["webConfig"]; | ||||
| 		webconfigEnable = webconfigConfig.get("enable", true).asBool(); | ||||
| 		_port = webconfigConfig.get("port", _port).asUInt(); | ||||
| 		_baseUrl = QString::fromStdString( webconfigConfig.get("document_root", _baseUrl.toStdString()).asString() ); | ||||
| 		const QJsonObject webconfigConfig = config["webConfig"].toObject(); | ||||
| 		webconfigEnable = webconfigConfig["enable"].toBool(true); | ||||
| 		_port = webconfigConfig["port"].toInt(_port); | ||||
| 		_baseUrl = webconfigConfig["document_root"].toString(_baseUrl); | ||||
| 	} | ||||
|  | ||||
| 	if (_baseUrl != ":/webconfig") | ||||
|   | ||||
| @@ -28,7 +28,6 @@ add_executable(${PROJECT_NAME} | ||||
| target_link_libraries(${PROJECT_NAME} | ||||
| 	effectengine | ||||
| 	commandline | ||||
| 	jsoncpp | ||||
| 	${QT_LIBRARIES}) | ||||
|  | ||||
| qt5_use_modules(${PROJECT_NAME} Gui Core Network) | ||||
|   | ||||
| @@ -1,9 +1,14 @@ | ||||
| // stl includes | ||||
| #include <stdexcept> | ||||
| #include <cassert> | ||||
| #include <sstream> | ||||
| #include <iostream> | ||||
|  | ||||
| // Qt includes | ||||
| #include <QRgb> | ||||
| #include <QJsonObject> | ||||
| #include <QJsonArray> | ||||
| #include <QJsonDocument> | ||||
|  | ||||
| // hyperion-remote includes | ||||
| #include "JsonConnection.h" | ||||
| @@ -41,26 +46,28 @@ JsonConnection::~JsonConnection() | ||||
|  | ||||
| void JsonConnection::setColor(std::vector<QColor> colors, int priority, int duration) | ||||
| { | ||||
| 	std::cout << "Set color to " << colors[0].red() << " " << colors[0].green() << " " << colors[0].blue() << (colors.size() > 1 ? " + ..." : "") << std::endl; | ||||
| 	qDebug() << "Set color to " << colors[0].red() << " " << colors[0].green() << " " << colors[0].blue() << (colors.size() > 1 ? " + ..." : ""); | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "color"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("color"); | ||||
| 	command["priority"] = priority; | ||||
| 	Json::Value & rgbValue = command["color"]; | ||||
| 	QJsonArray rgbValue; | ||||
| 	for (const QColor & color : colors) | ||||
| 	{ | ||||
| 		rgbValue.append(color.red()); | ||||
| 		rgbValue.append(color.green()); | ||||
| 		rgbValue.append(color.blue()); | ||||
| 	} | ||||
| 	command["color"] = rgbValue; | ||||
| 	 | ||||
| 	if (duration > 0) | ||||
| 	{ | ||||
| 		command["duration"] = duration; | ||||
| 	} | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -68,7 +75,7 @@ void JsonConnection::setColor(std::vector<QColor> colors, int priority, int dura | ||||
|  | ||||
| void JsonConnection::setImage(QImage &image, int priority, int duration) | ||||
| { | ||||
| 	std::cout << "Set image has size: " << image.width() << "x" << image.height() << std::endl; | ||||
| 	qDebug() << "Set image has size: " << image.width() << "x" << image.height(); | ||||
|  | ||||
| 	// ensure the image has RGB888 format | ||||
| 	image = image.convertToFormat(QImage::Format_ARGB32_Premultiplied); | ||||
| @@ -87,19 +94,19 @@ void JsonConnection::setImage(QImage &image, int priority, int duration) | ||||
| 	const QByteArray base64Image = binaryImage.toBase64(); | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "image"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("image"); | ||||
| 	command["priority"] = priority; | ||||
| 	command["imagewidth"] = image.width(); | ||||
| 	command["imageheight"] = image.height(); | ||||
| 	command["imagedata"] = base64Image.data(); | ||||
| 	command["imagedata"] = QString(base64Image.data()); | ||||
| 	if (duration > 0) | ||||
| 	{ | ||||
| 		command["duration"] = duration; | ||||
| 	} | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -110,26 +117,47 @@ void JsonConnection::setEffect(const QString &effectName, const QString & effect | ||||
|     qDebug() << "Start effect " << effectName; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "effect"; | ||||
| 	QJsonObject command, effect; | ||||
| 	command["command"] = QString("effect"); | ||||
| 	command["priority"] = priority; | ||||
| 	Json::Value & effect = command["effect"]; | ||||
| 	effect["name"] = effectName.toStdString(); | ||||
| 	effect["name"] = effectName; | ||||
| 	 | ||||
| 	if (effectArgs.size() > 0) | ||||
| 	{ | ||||
| 		Json::Reader reader; | ||||
| 		if (!reader.parse(effectArgs.toStdString(), effect["args"], false)) | ||||
| 		QJsonParseError error; | ||||
| 		QJsonDocument doc = QJsonDocument::fromJson(effectArgs.toUtf8() ,&error); | ||||
| 		 | ||||
| 		if (error.error != QJsonParseError::NoError) | ||||
| 		{ | ||||
| 			throw std::runtime_error("Error in effect arguments: " + reader.getFormattedErrorMessages()); | ||||
| 			// report to the user the failure and their locations in the document. | ||||
| 			int errorLine(0), errorColumn(0); | ||||
| 			 | ||||
| 			for( int i=0, count=qMin( error.offset,effectArgs.size()); i<count; ++i ) | ||||
| 			{ | ||||
| 				++errorColumn; | ||||
| 				if(effectArgs.at(i) == '\n' ) | ||||
| 				{ | ||||
| 					errorColumn = 0; | ||||
| 					++errorLine; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			std::stringstream sstream; | ||||
| 			sstream << "Error in effect arguments: " << error.errorString().toStdString() << " at Line: " << errorLine << ", Column: " << errorColumn; | ||||
| 			throw std::runtime_error(sstream.str()); | ||||
| 		} | ||||
| 		 | ||||
| 		effect["args"] = doc.object(); | ||||
| 		command["effect"] = effect; | ||||
| 	} | ||||
| 	 | ||||
| 	if (duration > 0) | ||||
| 	{ | ||||
| 		command["duration"] = duration; | ||||
| 	} | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -137,25 +165,26 @@ void JsonConnection::setEffect(const QString &effectName, const QString & effect | ||||
|  | ||||
| QString JsonConnection::getServerInfo() | ||||
| { | ||||
| 	std::cout << "Get server info" << std::endl; | ||||
| 	qDebug() << "Get server info"; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "serverinfo"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("serverinfo"); | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	if (parseReply(reply)) | ||||
| 	{ | ||||
| 		if (!reply.isMember("info") || !reply["info"].isObject()) | ||||
| 		if (!reply.contains("info") || !reply["info"].isObject()) | ||||
| 		{ | ||||
| 			throw std::runtime_error("No info available in result"); | ||||
| 		} | ||||
|  | ||||
| 		const Json::Value & info = reply["info"]; | ||||
| 		return QString(info.toStyledString().c_str()); | ||||
| 		QJsonDocument doc(reply["info"].toObject()); | ||||
| 		QString info(doc.toJson(QJsonDocument::Indented)); | ||||
| 		return info; | ||||
| 	} | ||||
|  | ||||
| 	return QString(); | ||||
| @@ -163,15 +192,15 @@ QString JsonConnection::getServerInfo() | ||||
|  | ||||
| void JsonConnection::clear(int priority) | ||||
| { | ||||
| 	std::cout << "Clear priority channel " << priority << std::endl; | ||||
| 	qDebug() << "Clear priority channel " << priority; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "clear"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("clear"); | ||||
| 	command["priority"] = priority; | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -179,14 +208,14 @@ void JsonConnection::clear(int priority) | ||||
|  | ||||
| void JsonConnection::clearAll() | ||||
| { | ||||
| 	std::cout << "Clear all priority channels" << std::endl; | ||||
| 	qDebug() << "Clear all priority channels"; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "clearall"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("clearall"); | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -197,14 +226,14 @@ void JsonConnection::setComponentState(const QString & component, const bool sta | ||||
| 	qDebug() << (state ? "Enable" : "Disable") << "Component" << component; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "componentstate"; | ||||
| 	Json::Value & parameter = command["componentstate"]; | ||||
| 	parameter["component"] = component.toStdString(); | ||||
| 	QJsonObject command, parameter; | ||||
| 	command["command"] = QString("componentstate"); | ||||
| 	parameter["component"] = component; | ||||
| 	parameter["state"] = state; | ||||
| 	command["componentstate"] = parameter; | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -213,12 +242,12 @@ void JsonConnection::setComponentState(const QString & component, const bool sta | ||||
| void JsonConnection::setSource(int priority) | ||||
| { | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "sourceselect"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("sourceselect"); | ||||
| 	command["priority"] = priority; | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -227,12 +256,12 @@ void JsonConnection::setSource(int priority) | ||||
| void JsonConnection::setSourceAutoSelect() | ||||
| { | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "sourceselect"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("sourceselect"); | ||||
| 	command["auto"] = true; | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -241,26 +270,27 @@ void JsonConnection::setSourceAutoSelect() | ||||
| QString JsonConnection::getConfig(std::string type) | ||||
| { | ||||
| 	assert( type == "schema" || type == "config" ); | ||||
| 	std::cout << "Get configuration file from Hyperion Server" << std::endl; | ||||
| 	qDebug() << "Get configuration file from Hyperion Server"; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "config"; | ||||
| 	command["subcommand"] = (type == "schema")? "getschema" : "getconfig"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("config"); | ||||
| 	command["subcommand"] = (type == "schema") ? QString("getschema") : QString("getconfig"); | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	if (parseReply(reply)) | ||||
| 	{ | ||||
| 		if (!reply.isMember("result") || !reply["result"].isObject()) | ||||
| 		if (!reply.contains("result") || !reply["result"].isObject()) | ||||
| 		{ | ||||
| 			throw std::runtime_error("No configuration file available in result"); | ||||
| 		} | ||||
| 		 | ||||
| 		const Json::Value & config = reply["result"]; | ||||
| 		return QString(config.toStyledString().c_str()); | ||||
| 		QJsonDocument doc(reply["result"].toObject()); | ||||
| 		QString result(doc.toJson(QJsonDocument::Indented)); | ||||
| 		return result; | ||||
| 	} | ||||
|  | ||||
| 	return QString(); | ||||
| @@ -269,22 +299,41 @@ QString JsonConnection::getConfig(std::string type) | ||||
| void JsonConnection::setConfig(const QString &jsonString) | ||||
| { | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "config"; | ||||
| 	command["subcommand"] = "setconfig"; | ||||
| 	QJsonObject command; | ||||
| 	command["command"] = QString("config"); | ||||
| 	command["subcommand"] = QString("setconfig"); | ||||
| 	 | ||||
| 	 | ||||
| 	Json::Value & config = command["config"]; | ||||
| 	if (jsonString.size() > 0) | ||||
| 	{ | ||||
| 		Json::Reader reader; | ||||
| 		if (!reader.parse(jsonString.toStdString(), config, false)) | ||||
| 		QJsonParseError error; | ||||
| 		QJsonDocument doc = QJsonDocument::fromJson(jsonString.toUtf8() ,&error); | ||||
| 		 | ||||
| 		if (error.error != QJsonParseError::NoError) | ||||
| 		{ | ||||
| 			throw std::runtime_error("Error in configset arguments: " + reader.getFormattedErrorMessages()); | ||||
| 			// report to the user the failure and their locations in the document. | ||||
| 			int errorLine(0), errorColumn(0); | ||||
| 			 | ||||
| 			for( int i=0, count=qMin( error.offset,jsonString.size()); i<count; ++i ) | ||||
| 			{ | ||||
| 				++errorColumn; | ||||
| 				if(jsonString.at(i) == '\n' ) | ||||
| 				{ | ||||
| 					errorColumn = 0; | ||||
| 					++errorLine; | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			std::stringstream sstream; | ||||
| 			sstream << "Error in configset arguments: " << error.errorString().toStdString() << " at Line: " << errorLine << ", Column: " << errorColumn; | ||||
| 			throw std::runtime_error(sstream.str()); | ||||
| 		} | ||||
| 		 | ||||
| 		command["config"] = doc.object(); | ||||
| 	} | ||||
| 	 | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -301,16 +350,15 @@ void JsonConnection::setTransform(const QString &transformId, | ||||
| 								  QColor blacklevel, | ||||
| 								  QColor whitelevel) | ||||
| { | ||||
| 	std::cout << "Set color transforms" << std::endl; | ||||
| 	qDebug() << "Set color transforms"; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "transform"; | ||||
| 	Json::Value & transform = command["transform"]; | ||||
| 	QJsonObject command, transform; | ||||
| 	command["command"] = QString("transform"); | ||||
|  | ||||
| 	if (!transformId.isNull()) | ||||
| 	{ | ||||
| 		transform["id"] = transformId.toStdString(); | ||||
| 		transform["id"] = transformId; | ||||
| 	} | ||||
|  | ||||
| 	if (saturation != nullptr) | ||||
| @@ -340,38 +388,44 @@ void JsonConnection::setTransform(const QString &transformId, | ||||
| 	 | ||||
| 	if (threshold.isValid()) | ||||
| 	{ | ||||
| 		Json::Value & v = transform["threshold"]; | ||||
| 		v.append(threshold.red()); | ||||
| 		v.append(threshold.green()); | ||||
| 		v.append(threshold.blue()); | ||||
| 		QJsonArray t; | ||||
| 		t.append(threshold.red()); | ||||
| 		t.append(threshold.green()); | ||||
| 		t.append(threshold.blue()); | ||||
| 		transform["threshold"] = t; | ||||
| 	} | ||||
|  | ||||
| 	if (gamma.isValid()) | ||||
| 	{ | ||||
| 		Json::Value & v = transform["gamma"]; | ||||
| 		v.append(gamma.red()); | ||||
| 		v.append(gamma.green()); | ||||
| 		v.append(gamma.blue()); | ||||
| 		QJsonArray g; | ||||
| 		g.append(gamma.red()); | ||||
| 		g.append(gamma.green()); | ||||
| 		g.append(gamma.blue()); | ||||
| 		transform["gamma"] = g; | ||||
| 	} | ||||
|  | ||||
| 	if (blacklevel.isValid()) | ||||
| 	{ | ||||
| 		Json::Value & v = transform["blacklevel"]; | ||||
| 		v.append(blacklevel.red()); | ||||
| 		v.append(blacklevel.green()); | ||||
| 		v.append(blacklevel.blue()); | ||||
| 		QJsonArray b; | ||||
| 		b.append(blacklevel.red()); | ||||
| 		b.append(blacklevel.green()); | ||||
| 		b.append(blacklevel.blue()); | ||||
| 		transform["blacklevel"] = b; | ||||
| 	} | ||||
|  | ||||
| 	if (whitelevel.isValid()) | ||||
| 	{ | ||||
| 		Json::Value & v = transform["whitelevel"]; | ||||
| 		v.append(whitelevel.red()); | ||||
| 		v.append(whitelevel.green()); | ||||
| 		v.append(whitelevel.blue()); | ||||
| 		QJsonArray w; | ||||
| 		w.append(whitelevel.red()); | ||||
| 		w.append(whitelevel.green()); | ||||
| 		w.append(whitelevel.blue()); | ||||
| 		transform["whitelevel"] = w; | ||||
| 	} | ||||
| 	 | ||||
| 	command["transform"] = transform; | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| @@ -382,62 +436,67 @@ void JsonConnection::setAdjustment(const QString &adjustmentId, | ||||
| 								   const QColor & greenAdjustment, | ||||
| 								   const QColor & blueAdjustment) | ||||
| { | ||||
| 	std::cout << "Set color adjustments" << std::endl; | ||||
| 	qDebug() << "Set color adjustments"; | ||||
|  | ||||
| 	// create command | ||||
| 	Json::Value command; | ||||
| 	command["command"] = "adjustment"; | ||||
| 	Json::Value & adjust = command["adjustment"]; | ||||
| 	QJsonObject command, adjust; | ||||
| 	command["command"] = QString("adjustment"); | ||||
|  | ||||
| 	if (!adjustmentId.isNull()) | ||||
| 	{ | ||||
| 		adjust["id"] = adjustmentId.toStdString(); | ||||
| 		adjust["id"] = adjustmentId; | ||||
| 	} | ||||
| 	 | ||||
| 	if (redAdjustment.isValid()) | ||||
| 	{ | ||||
| 		Json::Value & v = adjust["redAdjust"]; | ||||
| 		v.append(redAdjustment.red()); | ||||
| 		v.append(redAdjustment.green()); | ||||
| 		v.append(redAdjustment.blue()); | ||||
| 		QJsonArray red; | ||||
| 		red.append(redAdjustment.red()); | ||||
| 		red.append(redAdjustment.green()); | ||||
| 		red.append(redAdjustment.blue()); | ||||
| 		adjust["redAdjust"] = red; | ||||
| 	} | ||||
|  | ||||
| 	if (greenAdjustment.isValid()) | ||||
| 	{ | ||||
| 		Json::Value & v = adjust["greenAdjust"]; | ||||
| 		v.append(greenAdjustment.red()); | ||||
| 		v.append(greenAdjustment.green()); | ||||
| 		v.append(greenAdjustment.blue()); | ||||
| 		QJsonArray green; | ||||
| 		green.append(greenAdjustment.red()); | ||||
| 		green.append(greenAdjustment.green()); | ||||
| 		green.append(greenAdjustment.blue()); | ||||
| 		adjust["greenAdjust"] = green; | ||||
| 	} | ||||
|  | ||||
| 	if (blueAdjustment.isValid()) | ||||
| 	{ | ||||
| 		Json::Value & v = adjust["blueAdjust"]; | ||||
| 		v.append(blueAdjustment.red()); | ||||
| 		v.append(blueAdjustment.green()); | ||||
| 		v.append(blueAdjustment.blue()); | ||||
| 		QJsonArray blue; | ||||
| 		blue.append(blueAdjustment.red()); | ||||
| 		blue.append(blueAdjustment.green()); | ||||
| 		blue.append(blueAdjustment.blue()); | ||||
| 		adjust["blueAdjust"] = blue; | ||||
| 	} | ||||
| 	 | ||||
| 	command["adjustment"] = adjust; | ||||
|  | ||||
| 	// send command message | ||||
| 	Json::Value reply = sendMessage(command); | ||||
| 	QJsonObject reply = sendMessage(command); | ||||
|  | ||||
| 	// parse reply message | ||||
| 	parseReply(reply); | ||||
| } | ||||
|  | ||||
| Json::Value JsonConnection::sendMessage(const Json::Value & message) | ||||
| QJsonObject JsonConnection::sendMessage(const QJsonObject & message) | ||||
| { | ||||
| 	// serialize message (FastWriter already appends a newline) | ||||
| 	std::string serializedMessage = Json::FastWriter().write(message); | ||||
| 	// serialize message | ||||
| 	QJsonDocument writer(message); | ||||
| 	QByteArray serializedMessage = writer.toJson(QJsonDocument::Compact) + "\n"; | ||||
|  | ||||
| 	// print command if requested | ||||
| 	if (_printJson) | ||||
| 	{ | ||||
| 		std::cout << "Command: " << serializedMessage; | ||||
| 		std::cout << "Command: " << serializedMessage.constData(); | ||||
| 	} | ||||
|  | ||||
| 	// write message | ||||
| 	_socket.write(serializedMessage.c_str()); | ||||
| 	_socket.write(serializedMessage); | ||||
| 	if (!_socket.waitForBytesWritten()) | ||||
| 	{ | ||||
| 		throw std::runtime_error("Error while writing data to host"); | ||||
| @@ -464,26 +523,26 @@ Json::Value JsonConnection::sendMessage(const Json::Value & message) | ||||
| 	} | ||||
|  | ||||
| 	// parse reply data | ||||
| 	Json::Reader jsonReader; | ||||
| 	Json::Value reply; | ||||
| 	if (!jsonReader.parse(serializedReply.constData(), serializedReply.constData() + bytes, reply)) | ||||
| 	QJsonParseError error; | ||||
| 	QJsonDocument reply = QJsonDocument::fromJson(serializedReply ,&error); | ||||
| 	if (error.error != QJsonParseError::NoError) | ||||
| 	{ | ||||
| 		throw std::runtime_error("Error while parsing reply: invalid json"); | ||||
| 	} | ||||
|  | ||||
| 	return reply; | ||||
| 	return reply.object(); | ||||
| } | ||||
|  | ||||
| bool JsonConnection::parseReply(const Json::Value &reply) | ||||
| bool JsonConnection::parseReply(const QJsonObject &reply) | ||||
| { | ||||
| 	bool success = false; | ||||
| 	std::string reason = "No error info"; | ||||
| 	QString reason = "No error info"; | ||||
|  | ||||
| 	try | ||||
| 	{ | ||||
| 		success = reply.get("success", false).asBool(); | ||||
| 		success = reply["success"].toBool(false); | ||||
| 		if (!success) | ||||
| 			reason = reply.get("error", reason).asString(); | ||||
| 			reason = reply["error"].toString(reason); | ||||
| 	} | ||||
| 	catch (const std::runtime_error &) | ||||
| 	{ | ||||
| @@ -492,7 +551,7 @@ bool JsonConnection::parseReply(const Json::Value &reply) | ||||
|  | ||||
| 	if (!success) | ||||
| 	{ | ||||
| 		throw std::runtime_error("Error: " + reason); | ||||
| 		throw std::runtime_error("Error: " + reason.toStdString()); | ||||
| 	} | ||||
|  | ||||
| 	return success; | ||||
|   | ||||
| @@ -7,12 +7,7 @@ | ||||
| #include <QColor> | ||||
| #include <QImage> | ||||
| #include <QTcpSocket> | ||||
| #include <QMap> | ||||
|  | ||||
| // jsoncpp includes | ||||
| #include <json/json.h> | ||||
|  | ||||
| // hyperion-remote includes | ||||
| #include <QJsonObject> | ||||
|  | ||||
| /// | ||||
| /// Connection class to setup an connection to the hyperion server and execute commands | ||||
| @@ -54,7 +49,7 @@ public: | ||||
| 	/// | ||||
| 	/// Start the given effect | ||||
| 	/// | ||||
| 	/// @param effect The name of the effect | ||||
| 	/// @param effectName The name of the effect | ||||
| 	/// @param effectArgs The arguments to use instead of the default ones | ||||
| 	/// @param priority The priority | ||||
| 	/// @param duration The duration in milliseconds | ||||
| @@ -164,7 +159,7 @@ private: | ||||
| 	/// | ||||
| 	/// @return The returned reply | ||||
| 	/// | ||||
| 	Json::Value sendMessage(const Json::Value & message); | ||||
| 	QJsonObject sendMessage(const QJsonObject & message); | ||||
|  | ||||
| 	/// | ||||
| 	/// Parse a reply message | ||||
| @@ -173,7 +168,7 @@ private: | ||||
| 	/// | ||||
| 	/// @return true if the reply indicates success | ||||
| 	/// | ||||
| 	bool parseReply(const Json::Value & reply); | ||||
| 	bool parseReply(const QJsonObject & reply); | ||||
|  | ||||
| private: | ||||
| 	/// Flag for printing all send and received json-messages to the standard out | ||||
|   | ||||
| @@ -2,6 +2,7 @@ | ||||
| #include <clocale> | ||||
| #include <initializer_list> | ||||
| #include <limits> | ||||
| #include <iostream> | ||||
|  | ||||
| // Qt includes | ||||
| #include <QCoreApplication> | ||||
|   | ||||
| @@ -17,7 +17,6 @@ | ||||
|  | ||||
| #include "HyperionConfig.h" | ||||
|  | ||||
| #include <utils/jsonschema/JsonFactory.h> // DEPRECATED | Remove this only when the conversion have been completed from JsonCpp to QTJson | ||||
| #include <utils/jsonschema/QJsonFactory.h> | ||||
| #include <utils/Components.h> | ||||
|  | ||||
| @@ -163,7 +162,24 @@ void HyperionDaemon::loadConfig(const QString & configFile) | ||||
| 	QJsonSchemaChecker schemaChecker; | ||||
| 	schemaChecker.setSchema(schemaJson.object()); | ||||
|  | ||||
| 	_config  = JsonFactory::readJson(configFile.toStdString()); // DEPRECATED | Remove this only when the conversion have been completed from JsonCpp to QTJson | ||||
| 	// ----------------- DEPRECATED BEGIN ----------------- | ||||
| 	// NOTE: Remove this code block when the conversion have been completed from JsonCpp to QTJson | ||||
| 	 | ||||
| 		std::ifstream ifs(configFile.toStdString().c_str()); | ||||
| 		 | ||||
| 		Json::Reader reader; | ||||
| 		 | ||||
| 		if (! reader.parse(ifs, _config, false)) | ||||
| 		{ | ||||
| 			// report to the user the failure and their locations in the document. | ||||
| 			std::stringstream sstream; | ||||
| 			sstream << "Failed to parse configuration: " << reader.getFormattedErrorMessages().c_str(); | ||||
|  | ||||
| 			throw std::runtime_error(sstream.str()); | ||||
| 		} | ||||
| 	 | ||||
| 	// ----------------- DEPRECATED END ----------------- | ||||
|  | ||||
| 	_qconfig = QJsonFactory::readJson(configFile); | ||||
| 	if (!schemaChecker.validate(_qconfig)) | ||||
| 	{ | ||||
|   | ||||
| @@ -40,6 +40,15 @@ | ||||
|  | ||||
| #include <utils/Logger.h> | ||||
|  | ||||
| 	// ----------------- DEPRECATED BEGIN ----------------- | ||||
| 	// NOTE: Remove this code block when the conversion have been completed from JsonCpp to QTJson | ||||
|  | ||||
| 	#include <json/json.h> | ||||
| 	#include <istream> | ||||
| 	#include <fstream> | ||||
|  | ||||
| 	// ----------------- DEPRECATED END ----------------- | ||||
|  | ||||
| #include <kodivideochecker/KODIVideoChecker.h> | ||||
| #include <jsonserver/JsonServer.h> | ||||
| #include <protoserver/ProtoServer.h> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user