summaryrefslogtreecommitdiffstats
path: root/xbmc/interfaces/json-rpc/JSONUtils.h
diff options
context:
space:
mode:
Diffstat (limited to 'xbmc/interfaces/json-rpc/JSONUtils.h')
-rw-r--r--xbmc/interfaces/json-rpc/JSONUtils.h490
1 files changed, 490 insertions, 0 deletions
diff --git a/xbmc/interfaces/json-rpc/JSONUtils.h b/xbmc/interfaces/json-rpc/JSONUtils.h
new file mode 100644
index 0000000..150e23b
--- /dev/null
+++ b/xbmc/interfaces/json-rpc/JSONUtils.h
@@ -0,0 +1,490 @@
+/*
+ * Copyright (C) 2005-2018 Team Kodi
+ * This file is part of Kodi - https://kodi.tv
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * See LICENSES/README.md for more information.
+ */
+
+#pragma once
+
+#include "JSONRPCUtils.h"
+#include "playlists/SmartPlayList.h"
+#include "utils/JSONVariantParser.h"
+#include "utils/JSONVariantWriter.h"
+#include "utils/SortUtils.h"
+#include "utils/StringUtils.h"
+#include "utils/Variant.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <vector>
+
+class CDateTime;
+
+namespace JSONRPC
+{
+ /*!
+ \brief Possible value types of a parameter or return type
+ */
+ enum JSONSchemaType
+ {
+ NullValue = 0x01,
+ StringValue = 0x02,
+ NumberValue = 0x04,
+ IntegerValue = 0x08,
+ BooleanValue = 0x10,
+ ArrayValue = 0x20,
+ ObjectValue = 0x40,
+ AnyValue = 0x80
+ };
+
+ /*!
+ \ingroup jsonrpc
+ \brief Helper class containing utility methods to handle
+ json rpc method calls.*/
+ class CJSONUtils
+ {
+ public:
+ static void MillisecondsToTimeObject(int time, CVariant &result)
+ {
+ int ms = time % 1000;
+ result["milliseconds"] = ms;
+ time = (time - ms) / 1000;
+
+ int s = time % 60;
+ result["seconds"] = s;
+ time = (time - s) / 60;
+
+ int m = time % 60;
+ result["minutes"] = m;
+ time = (time -m) / 60;
+
+ result["hours"] = time;
+ }
+
+ protected:
+ static void HandleLimits(const CVariant &parameterObject, CVariant &result, int size, int &start, int &end)
+ {
+ if (size < 0)
+ size = 0;
+
+ start = (int)parameterObject["limits"]["start"].asInteger();
+ end = (int)parameterObject["limits"]["end"].asInteger();
+ end = (end <= 0 || end > size) ? size : end;
+ start = start > end ? end : start;
+
+ result["limits"]["start"] = start;
+ result["limits"]["end"] = end;
+ result["limits"]["total"] = size;
+ }
+
+ static bool ParseSorting(const CVariant &parameterObject, SortBy &sortBy, SortOrder &sortOrder, SortAttribute &sortAttributes)
+ {
+ std::string method = parameterObject["sort"]["method"].asString();
+ std::string order = parameterObject["sort"]["order"].asString();
+ StringUtils::ToLower(method);
+ StringUtils::ToLower(order);
+
+ // parse the sort attributes
+ sortAttributes = SortAttributeNone;
+ if (parameterObject["sort"]["ignorearticle"].asBoolean())
+ sortAttributes = static_cast<SortAttribute>(sortAttributes | SortAttributeIgnoreArticle);
+ if (parameterObject["sort"]["useartistsortname"].asBoolean())
+ sortAttributes = static_cast<SortAttribute>(sortAttributes | SortAttributeUseArtistSortName);
+
+ // parse the sort order
+ sortOrder = SortUtils::SortOrderFromString(order);
+ if (sortOrder == SortOrderNone)
+ return false;
+
+ // parse the sort method
+ sortBy = SortUtils::SortMethodFromString(method);
+
+ return true;
+ }
+
+ static void ParseLimits(const CVariant &parameterObject, int &limitStart, int &limitEnd)
+ {
+ limitStart = (int)parameterObject["limits"]["start"].asInteger();
+ limitEnd = (int)parameterObject["limits"]["end"].asInteger();
+ }
+
+ /*!
+ \brief Checks if the given object contains a parameter
+ \param parameterObject Object to check for a parameter
+ \param key Possible name of the parameter
+ \param position Possible position of the parameter
+ \return True if the parameter is available otherwise false
+
+ Checks the given object for a parameter with the given key (if
+ the given object is not an array) or for a parameter at the
+ given position (if the given object is an array).
+ */
+ static inline bool ParameterExists(const CVariant& parameterObject,
+ const std::string& key,
+ unsigned int position)
+ {
+ return IsValueMember(parameterObject, key) ||
+ (parameterObject.isArray() && parameterObject.size() > position);
+ }
+
+ /*!
+ \brief Checks if the given object contains a value
+ with the given key
+ \param value Value to check for the member
+ \param key Key of the member to check for
+ \return True if the given object contains a member with
+ the given key otherwise false
+ */
+ static inline bool IsValueMember(const CVariant& value, const std::string& key)
+ {
+ return value.isMember(key);
+ }
+
+ /*!
+ \brief Returns the json value of a parameter
+ \param parameterObject Object containing all provided parameters
+ \param key Possible name of the parameter
+ \param position Possible position of the parameter
+ \return Json value of the parameter with the given name or at the
+ given position
+
+ Returns the value of the parameter with the given key (if
+ the given object is not an array) or of the parameter at the
+ given position (if the given object is an array).
+ */
+ static inline CVariant GetParameter(const CVariant& parameterObject,
+ const std::string& key,
+ unsigned int position)
+ {
+ return IsValueMember(parameterObject, key) ? parameterObject[key] : parameterObject[position];
+ }
+
+ /*!
+ \brief Returns the json value of a parameter or the given
+ default value
+ \param parameterObject Object containing all provided parameters
+ \param key Possible name of the parameter
+ \param position Possible position of the parameter
+ \param fallback Default value of the parameter
+ \return Json value of the parameter with the given name or at the
+ given position or the default value if the parameter does not exist
+
+ Returns the value of the parameter with the given key (if
+ the given object is not an array) or of the parameter at the
+ given position (if the given object is an array). If the
+ parameter does not exist the given default value is returned.
+ */
+ static inline CVariant GetParameter(const CVariant& parameterObject,
+ const std::string& key,
+ unsigned int position,
+ const CVariant& fallback)
+ {
+ return IsValueMember(parameterObject, key)
+ ? parameterObject[key]
+ : ((parameterObject.isArray() && parameterObject.size() > position)
+ ? parameterObject[position]
+ : fallback);
+ }
+
+ /*!
+ \brief Returns the given json value as a string
+ \param value Json value to convert to a string
+ \param defaultValue Default string value
+ \return String value of the given json value or the default value
+ if the given json value is no string
+ */
+ static inline std::string GetString(const CVariant &value, const char* defaultValue)
+ {
+ std::string str = defaultValue;
+ if (value.isString())
+ {
+ str = value.asString();
+ }
+
+ return str;
+ }
+
+ /*!
+ \brief Returns a TransportLayerCapability value of the
+ given string representation
+ \param transport String representation of the TransportLayerCapability
+ \return TransportLayerCapability value of the given string representation
+ */
+ static inline TransportLayerCapability StringToTransportLayer(const std::string& transport)
+ {
+ if (transport.compare("Announcing") == 0)
+ return Announcing;
+ if (transport.compare("FileDownloadDirect") == 0)
+ return FileDownloadDirect;
+ if (transport.compare("FileDownloadRedirect") == 0)
+ return FileDownloadRedirect;
+
+ return Response;
+ }
+
+ /*!
+ \brief Returns a JSONSchemaType value for the given
+ string representation
+ \param valueType String representation of the JSONSchemaType
+ \return JSONSchemaType value of the given string representation
+ */
+ static inline JSONSchemaType StringToSchemaValueType(const std::string& valueType)
+ {
+ if (valueType.compare("null") == 0)
+ return NullValue;
+ if (valueType.compare("string") == 0)
+ return StringValue;
+ if (valueType.compare("number") == 0)
+ return NumberValue;
+ if (valueType.compare("integer") == 0)
+ return IntegerValue;
+ if (valueType.compare("boolean") == 0)
+ return BooleanValue;
+ if (valueType.compare("array") == 0)
+ return ArrayValue;
+ if (valueType.compare("object") == 0)
+ return ObjectValue;
+
+ return AnyValue;
+ }
+
+ /*!
+ \brief Returns a string representation for the
+ given JSONSchemaType
+ \param valueType Specific JSONSchemaType
+ \return String representation of the given JSONSchemaType
+ */
+ static inline std::string SchemaValueTypeToString(JSONSchemaType valueType)
+ {
+ std::vector<JSONSchemaType> types = std::vector<JSONSchemaType>();
+ for (unsigned int value = 0x01; value <= (unsigned int)AnyValue; value *= 2)
+ {
+ if (HasType(valueType, (JSONSchemaType)value))
+ types.push_back((JSONSchemaType)value);
+ }
+
+ std::string strType;
+ if (types.size() > 1)
+ strType.append("[");
+
+ for (unsigned int index = 0; index < types.size(); index++)
+ {
+ if (index > 0)
+ strType.append(", ");
+
+ switch (types.at(index))
+ {
+ case StringValue:
+ strType.append("string");
+ break;
+ case NumberValue:
+ strType.append("number");
+ break;
+ case IntegerValue:
+ strType.append("integer");
+ break;
+ case BooleanValue:
+ strType.append("boolean");
+ break;
+ case ArrayValue:
+ strType.append("array");
+ break;
+ case ObjectValue:
+ strType.append("object");
+ break;
+ case AnyValue:
+ strType.append("any");
+ break;
+ case NullValue:
+ strType.append("null");
+ break;
+ default:
+ strType.append("unknown");
+ }
+ }
+
+ if (types.size() > 1)
+ strType.append("]");
+
+ return strType;
+ }
+
+ /*!
+ \brief Converts the given json schema type into
+ a json object
+ \param valueTye json schema type(s)
+ \param jsonObject json object into which the json schema type(s) are stored
+ */
+ static inline void SchemaValueTypeToJson(JSONSchemaType valueType, CVariant &jsonObject)
+ {
+ jsonObject = CVariant(CVariant::VariantTypeArray);
+ for (unsigned int value = 0x01; value <= (unsigned int)AnyValue; value *= 2)
+ {
+ if (HasType(valueType, (JSONSchemaType)value))
+ jsonObject.append(SchemaValueTypeToString((JSONSchemaType)value));
+ }
+
+ if (jsonObject.size() == 1)
+ {
+ CVariant jsonType = jsonObject[0];
+ jsonObject = jsonType;
+ }
+ }
+
+ static inline const char *ValueTypeToString(CVariant::VariantType valueType)
+ {
+ switch (valueType)
+ {
+ case CVariant::VariantTypeString:
+ return "string";
+ case CVariant::VariantTypeDouble:
+ return "number";
+ case CVariant::VariantTypeInteger:
+ case CVariant::VariantTypeUnsignedInteger:
+ return "integer";
+ case CVariant::VariantTypeBoolean:
+ return "boolean";
+ case CVariant::VariantTypeArray:
+ return "array";
+ case CVariant::VariantTypeObject:
+ return "object";
+ case CVariant::VariantTypeNull:
+ case CVariant::VariantTypeConstNull:
+ return "null";
+ default:
+ return "unknown";
+ }
+ }
+
+ /*!
+ \brief Checks if the parameter with the given name or at
+ the given position is of a certain type
+ \param parameterObject Object containing all provided parameters
+ \param key Possible name of the parameter
+ \param position Possible position of the parameter
+ \param valueType Expected type of the parameter
+ \return True if the specific parameter is of the given type otherwise false
+ */
+ static inline bool IsParameterType(const CVariant &parameterObject, const char *key, unsigned int position, JSONSchemaType valueType)
+ {
+ if ((valueType & AnyValue) == AnyValue)
+ return true;
+
+ CVariant parameter;
+ if (IsValueMember(parameterObject, key))
+ parameter = parameterObject[key];
+ else if(parameterObject.isArray() && parameterObject.size() > position)
+ parameter = parameterObject[position];
+
+ return IsType(parameter, valueType);
+ }
+
+ /*!
+ \brief Checks if the given json value is of the given type
+ \param value Json value to check
+ \param valueType Expected type of the json value
+ \return True if the given json value is of the given type otherwise false
+ */
+ static inline bool IsType(const CVariant &value, JSONSchemaType valueType)
+ {
+ if (HasType(valueType, AnyValue))
+ return true;
+ if (HasType(valueType, StringValue) && value.isString())
+ return true;
+ if (HasType(valueType, NumberValue) && (value.isInteger() || value.isUnsignedInteger() || value.isDouble()))
+ return true;
+ if (HasType(valueType, IntegerValue) && (value.isInteger() || value.isUnsignedInteger()))
+ return true;
+ if (HasType(valueType, BooleanValue) && value.isBoolean())
+ return true;
+ if (HasType(valueType, ArrayValue) && value.isArray())
+ return true;
+ if (HasType(valueType, ObjectValue) && value.isObject())
+ return true;
+
+ return value.isNull();
+ }
+
+ /*!
+ \brief Sets the value of the given json value to the
+ default value of the given type
+ \param value Json value to be set
+ \param valueType Type of the default value
+ */
+ static inline void SetDefaultValue(CVariant &value, JSONSchemaType valueType)
+ {
+ switch (valueType)
+ {
+ case StringValue:
+ value = CVariant("");
+ break;
+ case NumberValue:
+ value = CVariant(CVariant::VariantTypeDouble);
+ break;
+ case IntegerValue:
+ value = CVariant(CVariant::VariantTypeInteger);
+ break;
+ case BooleanValue:
+ value = CVariant(CVariant::VariantTypeBoolean);
+ break;
+ case ArrayValue:
+ value = CVariant(CVariant::VariantTypeArray);
+ break;
+ case ObjectValue:
+ value = CVariant(CVariant::VariantTypeObject);
+ break;
+ default:
+ value = CVariant(CVariant::VariantTypeNull);
+ }
+ }
+
+ static inline bool HasType(JSONSchemaType typeObject, JSONSchemaType type) { return (typeObject & type) == type; }
+
+ static inline bool ParameterNotNull(const CVariant& parameterObject, const std::string& key)
+ {
+ return parameterObject.isMember(key) && !parameterObject[key].isNull();
+ }
+
+ /*!
+ \brief Copies the values from the jsonStringArray to the stringArray.
+ stringArray is cleared.
+ \param jsonStringArray JSON object representing a string array
+ \param stringArray String array where the values are copied into (cleared)
+ */
+ static void CopyStringArray(const CVariant &jsonStringArray, std::vector<std::string> &stringArray)
+ {
+ if (!jsonStringArray.isArray())
+ return;
+
+ stringArray.clear();
+ for (CVariant::const_iterator_array it = jsonStringArray.begin_array(); it != jsonStringArray.end_array(); ++it)
+ stringArray.push_back(it->asString());
+ }
+
+ static void SetFromDBDate(const CVariant& jsonDate, CDateTime& date);
+
+ static void SetFromDBDateTime(const CVariant& jsonDate, CDateTime& date);
+
+ static bool GetXspFiltering(const std::string &type, const CVariant &filter, std::string &xsp)
+ {
+ if (type.empty() || !filter.isObject())
+ return false;
+
+ CVariant xspObj(CVariant::VariantTypeObject);
+ xspObj["type"] = type;
+
+ if (filter.isMember("field"))
+ {
+ xspObj["rules"]["and"] = CVariant(CVariant::VariantTypeArray);
+ xspObj["rules"]["and"].push_back(filter);
+ }
+ else
+ xspObj["rules"] = filter;
+
+ CSmartPlaylist playlist;
+ return playlist.Load(xspObj) && playlist.SaveAsJson(xsp, false);
+ }
+ };
+}