From ebbb6b9440565cb460c6997d4332cb081a30be1e Mon Sep 17 00:00:00 2001 From: Paulchen Panther Date: Tue, 11 Oct 2016 19:51:20 +0200 Subject: [PATCH] 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 --- include/hyperion/Hyperion.h | 9 +- include/hyperion/ImageProcessorFactory.h | 11 +- include/protoserver/ProtoConnection.h | 1 - include/utils/jsonschema/JsonFactory.h | 74 --- include/utils/jsonschema/JsonSchemaChecker.h | 194 -------- include/webconfig/WebConfig.h | 1 - libsrc/effectengine/CMakeLists.txt | 1 - libsrc/hyperion/Hyperion.cpp | 3 - libsrc/jsonserver/CMakeLists.txt | 1 - libsrc/utils/CMakeLists.txt | 4 - libsrc/utils/jsonschema/JsonSchemaChecker.cpp | 465 ------------------ libsrc/webconfig/CgiHandler.cpp | 8 +- libsrc/webconfig/CgiHandler.h | 3 +- libsrc/webconfig/WebConfig.cpp | 12 +- src/hyperion-remote/CMakeLists.txt | 1 - src/hyperion-remote/JsonConnection.cpp | 291 ++++++----- src/hyperion-remote/JsonConnection.h | 13 +- src/hyperion-remote/hyperion-remote.cpp | 1 + src/hyperiond/hyperiond.cpp | 20 +- src/hyperiond/hyperiond.h | 9 + 20 files changed, 223 insertions(+), 899 deletions(-) delete mode 100644 include/utils/jsonschema/JsonFactory.h delete mode 100644 include/utils/jsonschema/JsonSchemaChecker.h delete mode 100644 libsrc/utils/jsonschema/JsonSchemaChecker.cpp diff --git a/include/hyperion/Hyperion.h b/include/hyperion/Hyperion.h index c2ba3992..81d0da6a 100644 --- a/include/hyperion/Hyperion.h +++ b/include/hyperion/Hyperion.h @@ -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: diff --git a/include/hyperion/ImageProcessorFactory.h b/include/hyperion/ImageProcessorFactory.h index 7b23edfe..5957d4f8 100644 --- a/include/hyperion/ImageProcessorFactory.h +++ b/include/hyperion/ImageProcessorFactory.h @@ -6,14 +6,6 @@ // QT includes #include -// if (jsoncpp_converted_to_QtJSON) -// { -// remove("#include "); -// } - -// Jsoncpp includes -#include - #include // 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); diff --git a/include/protoserver/ProtoConnection.h b/include/protoserver/ProtoConnection.h index 8a6e3b3e..732a4625 100644 --- a/include/protoserver/ProtoConnection.h +++ b/include/protoserver/ProtoConnection.h @@ -17,7 +17,6 @@ #include #include -// jsoncpp includes #include /// diff --git a/include/utils/jsonschema/JsonFactory.h b/include/utils/jsonschema/JsonFactory.h deleted file mode 100644 index 319d7169..00000000 --- a/include/utils/jsonschema/JsonFactory.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include - -// JSON-Schema includes -#include - -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); - } -}; diff --git a/include/utils/jsonschema/JsonSchemaChecker.h b/include/utils/jsonschema/JsonSchemaChecker.h deleted file mode 100644 index a6f4ebd7..00000000 --- a/include/utils/jsonschema/JsonSchemaChecker.h +++ /dev/null @@ -1,194 +0,0 @@ -#pragma once - -// stl includes -#include -#include - -// jsoncpp includes -#include - - -/// 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 & 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 _currentPath; - /// The result messages collected during the schema verification - std::list _messages; - /// Flag indicating an error occured during validation - bool _error; - - /// A list with references (string => json-value) - std::map _references; // ref 2 value -}; diff --git a/include/webconfig/WebConfig.h b/include/webconfig/WebConfig.h index 5c4d4e82..379459d2 100644 --- a/include/webconfig/WebConfig.h +++ b/include/webconfig/WebConfig.h @@ -4,7 +4,6 @@ #include #include #include -#include #include class StaticFileServing; diff --git a/libsrc/effectengine/CMakeLists.txt b/libsrc/effectengine/CMakeLists.txt index 7ae723b4..ba7313f2 100644 --- a/libsrc/effectengine/CMakeLists.txt +++ b/libsrc/effectengine/CMakeLists.txt @@ -52,6 +52,5 @@ qt5_use_modules(effectengine Core Gui) target_link_libraries(effectengine hyperion - jsoncpp ${QT_LIBRARIES} ${PYTHON_LIBRARIES}) diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index f82c3f24..7d8ff359 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -13,9 +13,6 @@ #include #include -// JsonSchema include -#include - // hyperion include #include #include diff --git a/libsrc/jsonserver/CMakeLists.txt b/libsrc/jsonserver/CMakeLists.txt index f40baadb..e394f6ee 100644 --- a/libsrc/jsonserver/CMakeLists.txt +++ b/libsrc/jsonserver/CMakeLists.txt @@ -38,5 +38,4 @@ qt5_use_modules(jsonserver Network) target_link_libraries(jsonserver hyperion hyperion-utils - jsoncpp ${QT_LIBRARIES}) diff --git a/libsrc/utils/CMakeLists.txt b/libsrc/utils/CMakeLists.txt index 0e355632..cd0a8762 100644 --- a/libsrc/utils/CMakeLists.txt +++ b/libsrc/utils/CMakeLists.txt @@ -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 diff --git a/libsrc/utils/jsonschema/JsonSchemaChecker.cpp b/libsrc/utils/jsonschema/JsonSchemaChecker.cpp deleted file mode 100644 index 24a2c00a..00000000 --- a/libsrc/utils/jsonschema/JsonSchemaChecker.cpp +++ /dev/null @@ -1,465 +0,0 @@ -// stdlib includes -#include -#include -#include -#include - -// Utils-Jsonschema includes -#include - -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(oss, "")); - oss << ": " << message; - _messages.push_back(oss.str()); -} - -const std::list & 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::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 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::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(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(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()); -} diff --git a/libsrc/webconfig/CgiHandler.cpp b/libsrc/webconfig/CgiHandler.cpp index 380f3fdb..9079ab6c 100644 --- a/libsrc/webconfig/CgiHandler.cpp +++ b/libsrc/webconfig/CgiHandler.cpp @@ -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 diff --git a/libsrc/webconfig/CgiHandler.h b/libsrc/webconfig/CgiHandler.h index c3735d8d..6181fba7 100644 --- a/libsrc/webconfig/CgiHandler.h +++ b/libsrc/webconfig/CgiHandler.h @@ -5,7 +5,6 @@ #include #include -#include #include #include "QtHttpReply.h" @@ -28,7 +27,7 @@ public: private: Hyperion* _hyperion; QtHttpReply * _reply; - const Json::Value &_hyperionConfig; + const QJsonObject &_hyperionConfig; const QString _baseUrl; }; diff --git a/libsrc/webconfig/WebConfig.cpp b/libsrc/webconfig/WebConfig.cpp index aca89ef9..9e776dba 100644 --- a/libsrc/webconfig/WebConfig.cpp +++ b/libsrc/webconfig/WebConfig.cpp @@ -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") diff --git a/src/hyperion-remote/CMakeLists.txt b/src/hyperion-remote/CMakeLists.txt index 828612ea..fc2aeed5 100644 --- a/src/hyperion-remote/CMakeLists.txt +++ b/src/hyperion-remote/CMakeLists.txt @@ -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) diff --git a/src/hyperion-remote/JsonConnection.cpp b/src/hyperion-remote/JsonConnection.cpp index 653fe255..229098ad 100644 --- a/src/hyperion-remote/JsonConnection.cpp +++ b/src/hyperion-remote/JsonConnection.cpp @@ -1,9 +1,14 @@ // stl includes #include #include +#include +#include // Qt includes #include +#include +#include +#include // hyperion-remote includes #include "JsonConnection.h" @@ -41,26 +46,28 @@ JsonConnection::~JsonConnection() void JsonConnection::setColor(std::vector 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 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 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 #include #include -#include - -// jsoncpp includes -#include - -// hyperion-remote includes +#include /// /// 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 diff --git a/src/hyperion-remote/hyperion-remote.cpp b/src/hyperion-remote/hyperion-remote.cpp index b8cd2730..d21bbab2 100644 --- a/src/hyperion-remote/hyperion-remote.cpp +++ b/src/hyperion-remote/hyperion-remote.cpp @@ -2,6 +2,7 @@ #include #include #include +#include // Qt includes #include diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index 6cd86d33..c549d224 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -17,7 +17,6 @@ #include "HyperionConfig.h" -#include // DEPRECATED | Remove this only when the conversion have been completed from JsonCpp to QTJson #include #include @@ -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)) { diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h index d7acff16..8084a8d8 100644 --- a/src/hyperiond/hyperiond.h +++ b/src/hyperiond/hyperiond.h @@ -40,6 +40,15 @@ #include + // ----------------- DEPRECATED BEGIN ----------------- + // NOTE: Remove this code block when the conversion have been completed from JsonCpp to QTJson + + #include + #include + #include + + // ----------------- DEPRECATED END ----------------- + #include #include #include