initial commit
This commit is contained in:
commit
9d20827c46
2469 changed files with 470994 additions and 0 deletions
32
third-party/JsonQt/CMakeLists.txt
vendored
Normal file
32
third-party/JsonQt/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
PROJECT(JsonQt)
|
||||
# Stop cmake 2.6 from whining
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
IF(COMMAND cmake_policy)
|
||||
CMAKE_POLICY(SET CMP0003 NEW)
|
||||
ENDIF(COMMAND cmake_policy)
|
||||
SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR})
|
||||
|
||||
# If building for release, don't include QDebug stuff
|
||||
IF("x${CMAKE_BUILD_TYPE}" STREQUAL "x")
|
||||
SET(CMAKE_BUILD_TYPE "Release")
|
||||
ENDIF()
|
||||
IF("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||
ADD_DEFINITIONS("-DQT_NO_DEBUG_OUTPUT")
|
||||
ELSE()
|
||||
IF(${CMAKE_COMPILER_IS_GNUCXX})
|
||||
ADD_DEFINITIONS("-Wall -Werror")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
# Docs
|
||||
CONFIGURE_FILE(Doxyfile.cmake Doxyfile)
|
||||
ADD_CUSTOM_TARGET(doc doxygen)
|
||||
|
||||
# Subdirs
|
||||
ADD_SUBDIRECTORY(lib)
|
||||
IF("${BUILD_TESTS}" STREQUAL "")
|
||||
OPTION(BUILD_TESTS "Build tests" ON)
|
||||
ENDIF()
|
||||
IF(BUILD_TESTS)
|
||||
ADD_SUBDIRECTORY(tests)
|
||||
ENDIF()
|
||||
11
third-party/JsonQt/COMPATIBILITY
vendored
Normal file
11
third-party/JsonQt/COMPATIBILITY
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
The 0.1.0 API is aimed to be the 1.0.0 API.
|
||||
|
||||
From 1.0.0, JsonQt will follow the normal standards for API and ABI
|
||||
compatability between versions:
|
||||
|
||||
- Anything built against a specific version should work with any later version
|
||||
with the same major version; for example, something built against 1.0.0
|
||||
should work with 1.1.0.
|
||||
- New features that don't break backwards compatability will result in a bump of
|
||||
the minor version; this should mean that anything built against version
|
||||
a.b.c will work with any a.b.* version.
|
||||
13
third-party/JsonQt/COPYING.HEADER
vendored
Normal file
13
third-party/JsonQt/COPYING.HEADER
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
299
third-party/JsonQt/Doxyfile.cmake
vendored
Normal file
299
third-party/JsonQt/Doxyfile.cmake
vendored
Normal file
|
|
@ -0,0 +1,299 @@
|
|||
# Doxyfile 1.5.5
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Project related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
DOXYFILE_ENCODING = UTF-8
|
||||
PROJECT_NAME = JsonQt
|
||||
PROJECT_NUMBER =
|
||||
OUTPUT_DIRECTORY = doc
|
||||
CREATE_SUBDIRS = NO
|
||||
OUTPUT_LANGUAGE = English
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
REPEAT_BRIEF = YES
|
||||
ABBREVIATE_BRIEF = "The $name class" \
|
||||
"The $name widget" \
|
||||
"The $name file" \
|
||||
is \
|
||||
provides \
|
||||
specifies \
|
||||
contains \
|
||||
represents \
|
||||
a \
|
||||
an \
|
||||
the
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
INLINE_INHERITED_MEMB = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
STRIP_FROM_PATH =
|
||||
STRIP_FROM_INC_PATH =
|
||||
SHORT_NAMES = NO
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
QT_AUTOBRIEF = NO
|
||||
MULTILINE_CPP_IS_BRIEF = NO
|
||||
DETAILS_AT_TOP = NO
|
||||
INHERIT_DOCS = YES
|
||||
SEPARATE_MEMBER_PAGES = NO
|
||||
TAB_SIZE = 8
|
||||
ALIASES =
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
OPTIMIZE_OUTPUT_JAVA = NO
|
||||
OPTIMIZE_FOR_FORTRAN = NO
|
||||
OPTIMIZE_OUTPUT_VHDL = NO
|
||||
BUILTIN_STL_SUPPORT = NO
|
||||
CPP_CLI_SUPPORT = NO
|
||||
SIP_SUPPORT = NO
|
||||
DISTRIBUTE_GROUP_DOC = NO
|
||||
SUBGROUPING = YES
|
||||
TYPEDEF_HIDES_STRUCT = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# Build related configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
EXTRACT_ALL = NO
|
||||
EXTRACT_PRIVATE = YES
|
||||
EXTRACT_STATIC = YES
|
||||
EXTRACT_LOCAL_CLASSES = YES
|
||||
EXTRACT_LOCAL_METHODS = NO
|
||||
EXTRACT_ANON_NSPACES = NO
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
HIDE_FRIEND_COMPOUNDS = NO
|
||||
HIDE_IN_BODY_DOCS = NO
|
||||
INTERNAL_DOCS = NO
|
||||
CASE_SENSE_NAMES = YES
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
INLINE_INFO = YES
|
||||
SORT_MEMBER_DOCS = YES
|
||||
SORT_BRIEF_DOCS = NO
|
||||
SORT_GROUP_NAMES = NO
|
||||
SORT_BY_SCOPE_NAME = NO
|
||||
GENERATE_TODOLIST = YES
|
||||
GENERATE_TESTLIST = YES
|
||||
GENERATE_BUGLIST = YES
|
||||
GENERATE_DEPRECATEDLIST= YES
|
||||
ENABLED_SECTIONS =
|
||||
MAX_INITIALIZER_LINES = 30
|
||||
SHOW_USED_FILES = YES
|
||||
SHOW_DIRECTORIES = NO
|
||||
FILE_VERSION_FILTER =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
QUIET = NO
|
||||
WARNINGS = YES
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
WARN_IF_DOC_ERROR = YES
|
||||
WARN_NO_PARAMDOC = NO
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = ${CMAKE_SOURCE_DIR}/lib/ \
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.c \
|
||||
*.cc \
|
||||
*.cxx \
|
||||
*.cpp \
|
||||
*.c++ \
|
||||
*.d \
|
||||
*.java \
|
||||
*.ii \
|
||||
*.ixx \
|
||||
*.ipp \
|
||||
*.i++ \
|
||||
*.inl \
|
||||
*.h \
|
||||
*.hh \
|
||||
*.hxx \
|
||||
*.hpp \
|
||||
*.h++ \
|
||||
*.idl \
|
||||
*.odl \
|
||||
*.cs \
|
||||
*.php \
|
||||
*.php3 \
|
||||
*.inc \
|
||||
*.m \
|
||||
*.mm \
|
||||
*.dox \
|
||||
*.py \
|
||||
*.f90 \
|
||||
*.f \
|
||||
*.vhd \
|
||||
*.vhdl \
|
||||
*.C \
|
||||
*.CC \
|
||||
*.C++ \
|
||||
*.II \
|
||||
*.I++ \
|
||||
*.H \
|
||||
*.HH \
|
||||
*.H++ \
|
||||
*.CS \
|
||||
*.PHP \
|
||||
*.PHP3 \
|
||||
*.M \
|
||||
*.MM \
|
||||
*.PY \
|
||||
*.F90 \
|
||||
*.F \
|
||||
*.VHD \
|
||||
*.VHDL
|
||||
RECURSIVE = YES
|
||||
EXCLUDE =
|
||||
EXCLUDE_SYMLINKS = NO
|
||||
EXCLUDE_PATTERNS = *_p.h \
|
||||
*_p.cpp \
|
||||
${CMAKE_SOURCE_DIR}/src/plugins
|
||||
EXCLUDE_SYMBOLS =
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATTERNS = *
|
||||
EXAMPLE_RECURSIVE = NO
|
||||
IMAGE_PATH =
|
||||
INPUT_FILTER =
|
||||
FILTER_PATTERNS =
|
||||
FILTER_SOURCE_FILES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to source browsing
|
||||
#---------------------------------------------------------------------------
|
||||
SOURCE_BROWSER = YES
|
||||
INLINE_SOURCES = NO
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
REFERENCED_BY_RELATION = NO
|
||||
REFERENCES_RELATION = NO
|
||||
REFERENCES_LINK_SOURCE = YES
|
||||
USE_HTAGS = NO
|
||||
VERBATIM_HEADERS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
ALPHABETICAL_INDEX = YES
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
IGNORE_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_HTML = YES
|
||||
HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER =
|
||||
HTML_FOOTER =
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
GENERATE_HTMLHELP = NO
|
||||
GENERATE_DOCSET = NO
|
||||
DOCSET_FEEDNAME = "Doxygen generated docs"
|
||||
DOCSET_BUNDLE_ID = org.doxygen.Project
|
||||
HTML_DYNAMIC_SECTIONS = YES
|
||||
CHM_FILE =
|
||||
HHC_LOCATION =
|
||||
GENERATE_CHI = NO
|
||||
BINARY_TOC = NO
|
||||
TOC_EXPAND = NO
|
||||
DISABLE_INDEX = NO
|
||||
ENUM_VALUES_PER_LINE = 4
|
||||
GENERATE_TREEVIEW = NO
|
||||
TREEVIEW_WIDTH = 250
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_LATEX = YES
|
||||
LATEX_OUTPUT = latex
|
||||
LATEX_CMD_NAME = latex
|
||||
MAKEINDEX_CMD_NAME = makeindex
|
||||
COMPACT_LATEX = NO
|
||||
PAPER_TYPE = a4wide
|
||||
EXTRA_PACKAGES =
|
||||
LATEX_HEADER =
|
||||
PDF_HYPERLINKS = YES
|
||||
USE_PDFLATEX = YES
|
||||
LATEX_BATCHMODE = NO
|
||||
LATEX_HIDE_INDICES = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_RTF = NO
|
||||
RTF_OUTPUT = rtf
|
||||
COMPACT_RTF = NO
|
||||
RTF_HYPERLINKS = NO
|
||||
RTF_STYLESHEET_FILE =
|
||||
RTF_EXTENSIONS_FILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_MAN = NO
|
||||
MAN_OUTPUT = man
|
||||
MAN_EXTENSION = .3
|
||||
MAN_LINKS = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_XML = NO
|
||||
XML_OUTPUT = xml
|
||||
XML_SCHEMA =
|
||||
XML_DTD =
|
||||
XML_PROGRAMLISTING = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options for the AutoGen Definitions output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_AUTOGEN_DEF = NO
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the Perl module output
|
||||
#---------------------------------------------------------------------------
|
||||
GENERATE_PERLMOD = NO
|
||||
PERLMOD_LATEX = NO
|
||||
PERLMOD_PRETTY = YES
|
||||
PERLMOD_MAKEVAR_PREFIX =
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
ENABLE_PREPROCESSING = YES
|
||||
MACRO_EXPANSION = NO
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
SEARCH_INCLUDES = YES
|
||||
INCLUDE_PATH =
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
PREDEFINED =
|
||||
EXPAND_AS_DEFINED =
|
||||
SKIP_FUNCTION_MACROS = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
TAGFILES =
|
||||
GENERATE_TAGFILE =
|
||||
ALLEXTERNALS = NO
|
||||
EXTERNAL_GROUPS = YES
|
||||
PERL_PATH = /usr/bin/perl
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
CLASS_DIAGRAMS = YES
|
||||
MSCGEN_PATH =
|
||||
HIDE_UNDOC_RELATIONS = YES
|
||||
HAVE_DOT = NO
|
||||
CLASS_GRAPH = YES
|
||||
COLLABORATION_GRAPH = YES
|
||||
GROUP_GRAPHS = YES
|
||||
UML_LOOK = NO
|
||||
TEMPLATE_RELATIONS = NO
|
||||
INCLUDE_GRAPH = YES
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
CALL_GRAPH = NO
|
||||
CALLER_GRAPH = NO
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
DIRECTORY_GRAPH = YES
|
||||
DOT_IMAGE_FORMAT = png
|
||||
DOT_PATH =
|
||||
DOTFILE_DIRS =
|
||||
DOT_GRAPH_MAX_NODES = 50
|
||||
MAX_DOT_GRAPH_DEPTH = 1000
|
||||
DOT_TRANSPARENT = YES
|
||||
DOT_MULTI_TARGETS = NO
|
||||
GENERATE_LEGEND = YES
|
||||
DOT_CLEANUP = YES
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::additions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
SEARCHENGINE = NO
|
||||
13
third-party/JsonQt/add-copyright-header.sh
vendored
Normal file
13
third-party/JsonQt/add-copyright-header.sh
vendored
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#!/bin/sh
|
||||
NOTICE_HEADER="/* LICENSE NOTICE"
|
||||
TMPFILE=$(mktemp)
|
||||
for file in $(find -name *.cpp -o -name *.h); do
|
||||
if ! grep -q "$NOTICE_HEADER" "$file"; then
|
||||
echo "$NOTICE_HEADER" > $TMPFILE
|
||||
cat COPYING.HEADER >> $TMPFILE
|
||||
echo "*/" >> $TMPFILE
|
||||
cat "$file" >> $TMPFILE
|
||||
cat $TMPFILE > "$file"
|
||||
fi
|
||||
done
|
||||
rm $TMPFILE
|
||||
21
third-party/JsonQt/jsonqt.pri
vendored
Normal file
21
third-party/JsonQt/jsonqt.pri
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
HEADERS += \
|
||||
$$PWD/lib/JsonQtExport.h \
|
||||
$$PWD/lib/JsonRpc.h \
|
||||
$$PWD/lib/JsonRpcAdaptor.h \
|
||||
$$PWD/lib/JsonRpcAdaptorPrivate.h \
|
||||
$$PWD/lib/JsonToProperties.h \
|
||||
$$PWD/lib/JsonToVariant.h \
|
||||
$$PWD/lib/ParseException.h \
|
||||
$$PWD/lib/VariantToJson.h
|
||||
|
||||
SOURCES += \
|
||||
$$PWD/lib/JsonRpc.cpp \
|
||||
$$PWD/lib/JsonRpcAdaptor.cpp \
|
||||
$$PWD/lib/JsonRpcAdaptorPrivate.cpp \
|
||||
$$PWD/lib/JsonToProperties.cpp \
|
||||
$$PWD/lib/JsonToVariant.cpp \
|
||||
$$PWD/lib/ParseException.cpp \
|
||||
$$PWD/lib/VariantToJson.cpp
|
||||
|
||||
INCLUDEPATH += $$PWD/lib
|
||||
DEPENDPATH += $$PWD/lib
|
||||
76
third-party/JsonQt/lib/CMakeLists.txt
vendored
Normal file
76
third-party/JsonQt/lib/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
SET(
|
||||
CLASSES
|
||||
ParseException
|
||||
JsonRpc
|
||||
JsonRpcAdaptor
|
||||
JsonRpcAdaptorPrivate
|
||||
JsonToProperties
|
||||
JsonToVariant
|
||||
VariantToJson
|
||||
)
|
||||
SET(HEADERS JsonQtExport.h)
|
||||
|
||||
SET(VERSION 0.1.0)
|
||||
|
||||
##### Probably don't want to edit below this line #####
|
||||
|
||||
# Find Qt4
|
||||
FIND_PACKAGE( Qt4 REQUIRED )
|
||||
|
||||
SET( QT_DONT_USE_QTGUI TRUE )
|
||||
|
||||
# Include the cmake file needed to use qt4
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
|
||||
# Include the binary directory for moc files.
|
||||
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
|
||||
|
||||
FOREACH(class ${CLASSES})
|
||||
QT4_WRAP_CPP(MOC_SOURCE ${class}.h)
|
||||
SET(SOURCES ${SOURCES} ${class}.cpp ${MOC_SOURCE})
|
||||
SET(HEADERS ${HEADERS} ${class}.h)
|
||||
ENDFOREACH()
|
||||
SET(SOURCES ${SOURCES} ${MOC_SOURCE})
|
||||
|
||||
IF("${STATIC_JSONQT}" STREQUAL "")
|
||||
OPTION(STATIC_JSONQT "Build static libraries of JsonQt instead of shared" OFF)
|
||||
ENDIF()
|
||||
IF(STATIC_JSONQT)
|
||||
SET(BUILD STATIC)
|
||||
ELSE()
|
||||
SET(BUILD SHARED)
|
||||
ENDIF()
|
||||
|
||||
MESSAGE(STATUS "Building ${BUILD} JsonQt")
|
||||
|
||||
ADD_LIBRARY(
|
||||
JsonQt
|
||||
${BUILD}
|
||||
${SOURCES}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(
|
||||
JsonQt
|
||||
PROPERTIES
|
||||
VERSION "${VERSION}"
|
||||
SOVERSION "0"
|
||||
)
|
||||
|
||||
TARGET_LINK_LIBRARIES(
|
||||
JsonQt
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
TARGETS
|
||||
JsonQt
|
||||
DESTINATION
|
||||
lib${LIB_SUFFIX}
|
||||
)
|
||||
|
||||
INSTALL(
|
||||
FILES
|
||||
${HEADERS}
|
||||
DESTINATION
|
||||
include/JsonQt
|
||||
)
|
||||
24
third-party/JsonQt/lib/JsonQtExport.h
vendored
Normal file
24
third-party/JsonQt/lib/JsonQtExport.h
vendored
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _JSONQT_EXPORT_H
|
||||
#define _JSONQT_EXPORT_H
|
||||
|
||||
#include <QtGlobal>
|
||||
|
||||
#define JSONQT_EXPORT Q_DECL_EXPORT
|
||||
|
||||
#endif
|
||||
167
third-party/JsonQt/lib/JsonRpc.cpp
vendored
Normal file
167
third-party/JsonQt/lib/JsonRpc.cpp
vendored
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#include "JsonRpc.h"
|
||||
|
||||
#include "JsonToVariant.h"
|
||||
#include "VariantToJson.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
JsonRpc::JsonRpc(QObject* parent) : QObject(parent) {}
|
||||
|
||||
void JsonRpc::sendRequest(const QVariant& id, const QString& method, const QVariant& parameters)
|
||||
{
|
||||
Q_ASSERT(parameters.type() == QVariant::List || parameters.type() == QVariant::Map || parameters.isNull());
|
||||
QVariantMap request;
|
||||
request["jsonrpc"] = "2.0";
|
||||
request["method"] = method;
|
||||
request["id"] = id;
|
||||
|
||||
if(!parameters.isNull())
|
||||
{
|
||||
request["params"] = parameters;
|
||||
}
|
||||
|
||||
emit sendJson(VariantToJson::parse(request));
|
||||
}
|
||||
|
||||
void JsonRpc::sendNotification(const QString& method, const QVariant& parameters)
|
||||
{
|
||||
Q_ASSERT(parameters.type() == QVariant::List || parameters.type() == QVariant::Map || parameters.isNull());
|
||||
QVariantMap request;
|
||||
request["jsonrpc"] = "2.0";
|
||||
request["method"] = method;
|
||||
// no ID for notifications.
|
||||
|
||||
if(!parameters.isNull())
|
||||
{
|
||||
request["params"] = parameters;
|
||||
}
|
||||
|
||||
emit sendJson(VariantToJson::parse(request));
|
||||
}
|
||||
|
||||
void JsonRpc::sendResponse(const QVariant& id, const QVariant& result)
|
||||
{
|
||||
QVariantMap response;
|
||||
response["jsonrpc"] = "2.0";
|
||||
response["id"] = id;
|
||||
response["result"] = result;
|
||||
emit sendJson(VariantToJson::parse(response));
|
||||
}
|
||||
|
||||
void JsonRpc::sendError(const QVariant& id, int errorCode, const QString& message, const QVariant& data)
|
||||
{
|
||||
QVariantMap error;
|
||||
error["code"] = errorCode;
|
||||
error["message"] = message;
|
||||
error["data"] = data;
|
||||
|
||||
QVariantMap response;
|
||||
response["jsonrpc"] = "2.0";
|
||||
response["id"] = id;
|
||||
response["error"] = error;
|
||||
emit sendJson(VariantToJson::parse(response));
|
||||
}
|
||||
|
||||
void JsonRpc::processJson(const QString& json)
|
||||
{
|
||||
QList<QVariantMap> objects;
|
||||
try
|
||||
{
|
||||
objects = JsonToVariant::multiParse(json);
|
||||
}
|
||||
catch(ParseException)
|
||||
{
|
||||
sendError(QVariant(), InvalidJson, "Parse error.");
|
||||
return;
|
||||
}
|
||||
Q_FOREACH(const QVariantMap& object, objects)
|
||||
{
|
||||
if(object.value("jsonrpc").toString() != "2.0")
|
||||
{
|
||||
sendError(object.value("id"), InvalidJsonRpc, "JSON-RPC version not specified or not supported.", object);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Notification or request
|
||||
if(object.contains("method"))
|
||||
{
|
||||
if(object.value("method").type() != QVariant::String)
|
||||
{
|
||||
sendError(object.value("id"), InvalidJsonRpc, "'method' member of request must be a string.", object);
|
||||
continue;
|
||||
}
|
||||
QString method = object.value("method").toString();
|
||||
|
||||
QVariant parameters = object.value("params");
|
||||
|
||||
if(parameters.isNull()) parameters = QVariantList();
|
||||
if(parameters.type() != QVariant::List && parameters.type() != QVariant::Map)
|
||||
{
|
||||
sendError(object.value("id"), InvalidJsonRpc, "'parameters' member of request must be omitted, a list, or an object.", object);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Request or notification
|
||||
if(object.contains("id"))
|
||||
{
|
||||
emit requestReceived(object.value("id"), method, parameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit notificationReceived(method, parameters);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
// Request successful
|
||||
if(object.contains("result"))
|
||||
{
|
||||
if(!object.contains("id"))
|
||||
{
|
||||
sendError(QVariant(), InvalidJsonRpc, "ID not specified in response.", object);
|
||||
continue;
|
||||
}
|
||||
|
||||
emit responseReceived(object.value("id"), object.value("result"));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Request failed
|
||||
if(object.contains("error"))
|
||||
{
|
||||
if(!object.contains("id"))
|
||||
{
|
||||
sendError(QVariant(), InvalidJsonRpc, "ID not specified in response.", object);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(object.value("error").type() != QVariant::Map)
|
||||
{
|
||||
sendError(object.value("id"), InvalidJsonRpc, "'error' member is not an Error object.", object);
|
||||
continue;
|
||||
}
|
||||
|
||||
QVariantMap error = object.value("error").toMap();
|
||||
if(error.value("code").type() != QVariant::Int)
|
||||
{
|
||||
sendError(object.value("id"), InvalidJsonRpc, "'code' member of error object is not an integer.", object);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(error.value("message").type() != QVariant::String)
|
||||
{
|
||||
sendError(object.value("id"), InvalidJsonRpc, "'message' member of error object is not a string.", object);
|
||||
continue;
|
||||
}
|
||||
|
||||
emit errorReceived(object.value("id"), error.value("code").toInt(), error.value("message").toString(), error.value("data"));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Not a notification, request, or response
|
||||
sendError(object.value("id"), InvalidJsonRpc, "JSON object doesn't appear to be a JSON-RPC request, notification, or response.", object);
|
||||
}
|
||||
}
|
||||
};
|
||||
105
third-party/JsonQt/lib/JsonRpc.h
vendored
Normal file
105
third-party/JsonQt/lib/JsonRpc.h
vendored
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#ifndef _JSONQT_JSON_RPC_H
|
||||
#define _JSONQT_JSON_RPC_H
|
||||
|
||||
#include "JsonQtExport.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
/** Class implementing JSON-RPC.
|
||||
*
|
||||
* This implements the JSON-RPC 2.0 proposal, as of 2008-11-15, located
|
||||
* at http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal.
|
||||
*
|
||||
* While 1.1 is more popular for web services, 2.0 is a much simpler
|
||||
* protocol, and is not restricted to HTTP requests.
|
||||
*
|
||||
* Note that 'parameter' QVariant objects must be either null QVariants,
|
||||
* contain a QVariantList, or a QVariantMap. If a QVariantList is used,
|
||||
* it must be a list of all the parameters the method takes, in the
|
||||
* correct order. If a QVariantMap is used, the keys must be strings
|
||||
* exactly matching the parameter names of the method (case-sensitive).
|
||||
*
|
||||
* There are two IO members:
|
||||
* - processJson - slot - parse the JSON string given, and act upon it
|
||||
* - sendJson - signal - an action that an instance of JsonRpc has been
|
||||
* told to do requires that the specified JSON be sent to the other
|
||||
* peer.
|
||||
*
|
||||
* All other members are interfaces to JSON-RPC.
|
||||
*
|
||||
* 'id' parameters SHOULD NOT be NULL, for reasons defined in the
|
||||
* specification. Also, it SHOULD be a scalar.
|
||||
*
|
||||
* @author Fred Emmott <mail@fredemmott.co.uk>
|
||||
*/
|
||||
class JSONQT_EXPORT JsonRpc : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
Q_ENUMS(ErrorCode);
|
||||
/** List of standard JSON-RPC error codes.
|
||||
* All error codes between ServerErrorLow and
|
||||
* ServerErrorHigh are reserved for
|
||||
* implementation-defined server errors.
|
||||
*
|
||||
* All codes between -32768 and -32000 are reserved
|
||||
* either for the definitions below, or for future use.
|
||||
*
|
||||
* Other values may be used.
|
||||
*
|
||||
* InvalidJson and InvalidJsonRpc should only
|
||||
* be used internally by this class.
|
||||
*
|
||||
*/
|
||||
enum ErrorCode
|
||||
{
|
||||
InvalidJson = -32700,
|
||||
InvalidJsonRpc = -32600,
|
||||
MethodNotFound = -32601,
|
||||
BadParameters = -32602,
|
||||
InternalError = -32603,
|
||||
ServerErrorLow = -32099,
|
||||
ServerErrorHigh = -32000
|
||||
};
|
||||
|
||||
/// Construct a JsonRpc object.
|
||||
JsonRpc(QObject* parent = NULL);
|
||||
|
||||
/// Send a request, expecting a response.
|
||||
void sendRequest(const QVariant& id, const QString& method, const QVariant& parameters = QVariant());
|
||||
/// Send a request, not expecting a response.
|
||||
void sendNotification(const QString& method, const QVariant& parameters = QVariant());
|
||||
/// Respond to a request with success.
|
||||
void sendResponse(const QVariant& id, const QVariant& result = QVariant());
|
||||
/// Respond to a request with an error.
|
||||
void sendError(const QVariant& id, int errorCode, const QString& message, const QVariant& data = QVariant());
|
||||
public slots:
|
||||
/** Process a received JSON string, and emit the
|
||||
* appropriate signals.
|
||||
*/
|
||||
void processJson(const QString& json);
|
||||
signals:
|
||||
/** Emitted when JsonRpc needs to send some JSON to the
|
||||
* other peer.
|
||||
*/
|
||||
void sendJson(const QString& json);
|
||||
|
||||
/** A notification has been received from the other peer.
|
||||
* No reponse is neccessary.
|
||||
*/
|
||||
void notificationReceived(const QString& method, const QVariant& parameters);
|
||||
/** A request has been received from the other peer.
|
||||
* A response (with the same id) is required.
|
||||
*/
|
||||
void requestReceived(const QVariant& id, const QString& method, const QVariant& parameters);
|
||||
/// A successful response has been received from the other peer.
|
||||
void responseReceived(const QVariant& id, const QVariant& result);
|
||||
/// An error has been recevied from the other peer.
|
||||
void errorReceived(const QVariant& id, int errorCode, const QString& message, const QVariant& data);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
19
third-party/JsonQt/lib/JsonRpcAdaptor.cpp
vendored
Normal file
19
third-party/JsonQt/lib/JsonRpcAdaptor.cpp
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#include "JsonRpcAdaptor.h"
|
||||
#include "JsonRpcAdaptorPrivate.h"
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
|
||||
JsonRpcAdaptor::JsonRpcAdaptor(QObject* adapt, QObject* parent)
|
||||
:
|
||||
QObject(parent),
|
||||
d(new JsonRpcAdaptorPrivate(adapt, this))
|
||||
{
|
||||
connect(d, SIGNAL(sendJson(const QString&)), this, SIGNAL(sendJson(const QString&)));
|
||||
}
|
||||
|
||||
void JsonRpcAdaptor::processJson(const QString& json)
|
||||
{
|
||||
d->processJson(json);
|
||||
}
|
||||
};
|
||||
69
third-party/JsonQt/lib/JsonRpcAdaptor.h
vendored
Normal file
69
third-party/JsonQt/lib/JsonRpcAdaptor.h
vendored
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef _JSONQT_JSON_RPC_ADAPTOR_H
|
||||
#define _JSONQT_JSON_RPC_ADAPTOR_H
|
||||
|
||||
#include "JsonQtExport.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
class JsonRpcAdaptorPrivate;
|
||||
/** Class exporting a QObject's public slots via JSON-RPC.
|
||||
*
|
||||
* This implements the JSON-RPC 2.0 proposal, as of 2008-11-15, located
|
||||
* at http://groups.google.com/group/json-rpc/web/json-rpc-1-2-proposal.
|
||||
*
|
||||
* It also implements the introspection functionality of JSON-RPC 1.1.
|
||||
*
|
||||
* There are several Q_CLASSINFO declarations that this adaptor will pay
|
||||
* attention to:
|
||||
*
|
||||
* - JsonQt-RPC-id: *REQUIRED*. This is the only required parameter; it
|
||||
* specifies a unique identifier for this service, in the format
|
||||
* described by RFC 3986.
|
||||
*
|
||||
* - JsonQt-RPC-name: the name of the service provided by the QObject.
|
||||
* If this is not specified, the class name will be used.
|
||||
*
|
||||
* - JsonQt-RPC-version: the version of the service provided by the QObject.
|
||||
* If this is omitted, it will be omitted from the introspection data.
|
||||
*
|
||||
* - JsonQt-RPC-summary: A short description of this service. If this
|
||||
* is omitted, it will be omitted from the introspection data.
|
||||
*
|
||||
* - JsonQt-RPC-help: An URL pointing to human-readable documentation
|
||||
* about the service. If this is omitted, it will be omitted from the
|
||||
* introspection data.
|
||||
*
|
||||
* The following types are supported for parameters and return values:
|
||||
* - void return
|
||||
* - bool
|
||||
* - int
|
||||
* - QString
|
||||
* - QVariantList (which can contain any types supported by JsonQt)
|
||||
* - QVariantMap (which can contain any types supported by JsonQt)
|
||||
*
|
||||
* @author Fred Emmott <mail@fredemmott.co.uk>
|
||||
*/
|
||||
class JSONQT_EXPORT JsonRpcAdaptor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/** Construct a JsonRpcAdaptor.
|
||||
* This will expose @param adapt via JSON.
|
||||
*/
|
||||
JsonRpcAdaptor(QObject* adapt, QObject* parent = NULL);
|
||||
public slots:
|
||||
/// Handle received JSON.
|
||||
void processJson(const QString& json);
|
||||
signals:
|
||||
/** When this is emitted, the JSON provided should be
|
||||
* sent to the peer.
|
||||
*/
|
||||
void sendJson(const QString& json);
|
||||
private:
|
||||
JsonRpcAdaptorPrivate* d;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
351
third-party/JsonQt/lib/JsonRpcAdaptorPrivate.cpp
vendored
Normal file
351
third-party/JsonQt/lib/JsonRpcAdaptorPrivate.cpp
vendored
Normal file
|
|
@ -0,0 +1,351 @@
|
|||
#include "JsonRpcAdaptorPrivate.h"
|
||||
|
||||
#include "VariantToJson.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QGenericArgument>
|
||||
#include <QMetaClassInfo>
|
||||
#include <QMetaObject>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
JsonRpcAdaptorPrivate::JsonRpcAdaptorPrivate(QObject* adapt, QObject* parent) : QObject(parent)
|
||||
{
|
||||
m_adapted = adapt;
|
||||
connect(
|
||||
&m_jsonRpc,
|
||||
SIGNAL(sendJson(const QString&)),
|
||||
this,
|
||||
SIGNAL(sendJson(const QString&))
|
||||
);
|
||||
connect(
|
||||
&m_jsonRpc,
|
||||
SIGNAL(requestReceived(const QVariant&, const QString&, const QVariant&)),
|
||||
this,
|
||||
SLOT(requestReceived(const QVariant&, const QString&, const QVariant&))
|
||||
);
|
||||
populateServiceDescription();
|
||||
}
|
||||
|
||||
void JsonRpcAdaptorPrivate::populateServiceDescription()
|
||||
{
|
||||
m_serviceDescription.clear();
|
||||
const QMetaObject* metaObject = m_adapted->metaObject();
|
||||
|
||||
QString id = getClassInfo("JsonQt-RPC-id");
|
||||
Q_ASSERT(!id.isEmpty());
|
||||
m_serviceDescription["id"] = id;
|
||||
m_serviceDescription["sdversion"] = "1.0";
|
||||
QString name = getClassInfo("JsonQt-RPC-name");
|
||||
if(name.isEmpty()) name = metaObject->className();
|
||||
m_serviceDescription["name"] = name;
|
||||
|
||||
QString version = getClassInfo("JsonQt-RPC-version");
|
||||
if(!version.isNull()) m_serviceDescription["version"] = version;
|
||||
|
||||
QString summary = getClassInfo("JsonQt-RPC-summary");
|
||||
if(!summary.isNull()) m_serviceDescription["summary"] = summary;
|
||||
|
||||
QString help = getClassInfo("JsonQt-RPC-help");
|
||||
if(!help.isNull()) m_serviceDescription["help"] = help;
|
||||
|
||||
QMap<QString, QString> typeMap;
|
||||
typeMap[""] = "nil"; // void
|
||||
typeMap["bool"] = "bit";
|
||||
typeMap["int"] = "num";
|
||||
typeMap["QString"] = "str";
|
||||
// typeMap["QVariant"] = "any"; // not supported
|
||||
typeMap["QVariantList"] = "arr";
|
||||
typeMap["QVariantMap"] = "obj";
|
||||
|
||||
QVariantList procs;
|
||||
|
||||
for(int i = metaObject->methodOffset(); i < metaObject->methodCount(); ++i)
|
||||
{
|
||||
QMetaMethod method = metaObject->method(i);
|
||||
|
||||
// Check we should export it
|
||||
if(method.access() != QMetaMethod::Public || method.methodType() != QMetaMethod::Slot) continue;
|
||||
|
||||
QVariantMap proc;
|
||||
QString signature = method.signature();
|
||||
|
||||
// Name
|
||||
QString methodName = signature.left(signature.indexOf('('));
|
||||
proc["name"] = methodName;
|
||||
|
||||
// Return type
|
||||
if(!typeMap.contains(method.typeName()))
|
||||
{
|
||||
qDebug() << "Public slot" << signature << "has unknown return type" << method.typeName();
|
||||
continue;
|
||||
}
|
||||
proc["return"] = typeMap.value(method.typeName());
|
||||
|
||||
// Parameters
|
||||
QVariantList parameters;
|
||||
bool badParameter = false;
|
||||
for(int i = 0; i < method.parameterNames().count(); ++i)
|
||||
{
|
||||
QVariantMap parameter;
|
||||
QString parameterName(method.parameterNames().at(i));
|
||||
parameter["name"] = parameterName;
|
||||
|
||||
QString parameterType = method.parameterTypes().at(i);
|
||||
if(!typeMap.contains(method.parameterTypes().at(i)))
|
||||
{
|
||||
qDebug() << "Public slot" << signature << "has parameter" << parameterName << "with unknown type" << parameterType;
|
||||
badParameter = true;
|
||||
continue;
|
||||
}
|
||||
parameter["type"] = typeMap.value(parameterType);
|
||||
parameters.append(parameter);
|
||||
m_parameterIndices[methodName].insert(parameterName, i);
|
||||
}
|
||||
if(badParameter) continue;
|
||||
|
||||
m_methods.insert(methodName, method);
|
||||
proc["params"] = parameters;
|
||||
|
||||
// Done
|
||||
procs.append(proc);
|
||||
}
|
||||
m_serviceDescription["procs"] = procs;
|
||||
}
|
||||
|
||||
QString JsonRpcAdaptorPrivate::getClassInfo(const char* name)
|
||||
{
|
||||
const QMetaObject* metaObject = m_adapted->metaObject();
|
||||
int index = metaObject->indexOfClassInfo(name);
|
||||
if(index == -1) return QString();
|
||||
return metaObject->classInfo(index).value();
|
||||
}
|
||||
|
||||
void JsonRpcAdaptorPrivate::requestReceived(const QVariant& id, const QString& method, const QVariant& parameters)
|
||||
{
|
||||
if(method == "system.describe")
|
||||
{
|
||||
m_jsonRpc.sendResponse(id, m_serviceDescription);
|
||||
return;
|
||||
}
|
||||
ReturnData result = invokeMethod(method, parameters);
|
||||
if(result.succeeded)
|
||||
{
|
||||
m_jsonRpc.sendResponse(id, result.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_jsonRpc.sendError(id, result.code, result.message, result.data);
|
||||
}
|
||||
}
|
||||
|
||||
JsonRpcAdaptorPrivate::ReturnData JsonRpcAdaptorPrivate::invokeMethod(const QString& methodName, const QVariant& parameters)
|
||||
{
|
||||
ReturnData ret;
|
||||
ret.succeeded = false;
|
||||
if(!m_methods.contains(methodName))
|
||||
{
|
||||
ret.code = JsonRpc::MethodNotFound;
|
||||
ret.message = QString("The method %1 does not exist.").arg(methodName);
|
||||
return ret;
|
||||
}
|
||||
QMetaMethod metaMethod(m_methods.value(methodName));
|
||||
|
||||
int parameterCount;
|
||||
QVariantList parameterList;
|
||||
switch(parameters.type())
|
||||
{
|
||||
case QVariant::List:
|
||||
parameterList = parameters.toList();
|
||||
parameterCount = parameterList.count();
|
||||
break;
|
||||
case QVariant::Map:
|
||||
parameterCount = parameters.toMap().count();
|
||||
for(int i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
parameterList.append(QVariant());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
parameterCount = 0;
|
||||
}
|
||||
Q_ASSERT(parameterCount <= 9);
|
||||
|
||||
ret.code = JsonRpc::BadParameters;
|
||||
if(parameterCount != metaMethod.parameterNames().count())
|
||||
{
|
||||
ret.message = "Parameter count mismatch.";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
if(parameters.type() == QVariant::Map)
|
||||
{
|
||||
QMap<QString, int> parameterIndices = m_parameterIndices.value(methodName);
|
||||
QVariantMap parameterMap = parameters.toMap();
|
||||
for(QVariantMap::ConstIterator it = parameterMap.constBegin(); it != parameterMap.constEnd(); ++it)
|
||||
{
|
||||
if(!parameterIndices.contains(it.key()))
|
||||
{
|
||||
ret.message = QString("'%1' is not a parameter of method '%2'.").arg(it.key()).arg(methodName);
|
||||
return ret;
|
||||
}
|
||||
int index = parameterIndices.value(it.key());
|
||||
Q_ASSERT(index < parameterCount);
|
||||
parameterList[index] = it.value();
|
||||
}
|
||||
}
|
||||
|
||||
QMap<QString, QVariant::Type> typeMap;
|
||||
typeMap[""] = QVariant::Invalid;
|
||||
typeMap["bool"] = QVariant::Bool;
|
||||
typeMap["int"] = QVariant::Int;
|
||||
typeMap["QString"] = QVariant::String;
|
||||
typeMap["QVariantList"] = QVariant::List;
|
||||
typeMap["QVariantMap"] = QVariant::Map;
|
||||
///@todo more types
|
||||
|
||||
QVariant::Type returnType = typeMap.value(metaMethod.typeName());
|
||||
|
||||
// QMetaObject::invokeMethod takes 9 generic arguments
|
||||
QGenericArgument arguments[9];
|
||||
for(int i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
const QVariant& value = parameterList.value(i);
|
||||
if(typeMap.value(metaMethod.parameterTypes().at(i)) != value.type())
|
||||
{
|
||||
ret.message = QString("Value for parameter %1 was not of the correct type.").arg(QString(metaMethod.parameterNames().at(i)));
|
||||
return ret;
|
||||
}
|
||||
void* data = 0;
|
||||
switch(value.type())
|
||||
{
|
||||
case QVariant::Bool:
|
||||
data = new bool(value.toBool());
|
||||
arguments[i] = Q_ARG(bool, *static_cast<bool*>(data));
|
||||
break;
|
||||
case QVariant::Int:
|
||||
data = new int(value.toInt());
|
||||
arguments[i] = Q_ARG(int, *static_cast<int*>(data));
|
||||
break;
|
||||
case QVariant::String:
|
||||
data = new QString(value.toString());
|
||||
arguments[i] = Q_ARG(QString, *static_cast<QString*>(data));
|
||||
break;
|
||||
case QVariant::List:
|
||||
data = new QVariantList(value.toList());
|
||||
arguments[i] = Q_ARG(QVariantList, *static_cast<QVariantList*>(data));
|
||||
break;
|
||||
case QVariant::Map:
|
||||
data = new QVariantMap(value.toMap());
|
||||
arguments[i] = Q_ARG(QVariantMap, *static_cast<QVariantMap*>(data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QGenericReturnArgument returnValue;
|
||||
|
||||
switch(returnType)
|
||||
{
|
||||
case QVariant::Bool:
|
||||
returnValue = Q_RETURN_ARG(bool, *(new bool));
|
||||
break;
|
||||
case QVariant::Int:
|
||||
returnValue = Q_RETURN_ARG(int, *(new int));
|
||||
break;
|
||||
case QVariant::String:
|
||||
returnValue = Q_RETURN_ARG(QString, *(new QString));
|
||||
break;
|
||||
case QVariant::List:
|
||||
returnValue = Q_RETURN_ARG(QVariantList, *(new QVariantList));
|
||||
break;
|
||||
case QVariant::Map:
|
||||
returnValue = Q_RETURN_ARG(QVariantMap, *(new QVariantMap));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
bool success = m_adapted->metaObject()->invokeMethod(
|
||||
m_adapted,
|
||||
methodName.toLatin1().constData(),
|
||||
Qt::DirectConnection,
|
||||
returnValue,
|
||||
arguments[0],
|
||||
arguments[1],
|
||||
arguments[2],
|
||||
arguments[3],
|
||||
arguments[4],
|
||||
arguments[5],
|
||||
arguments[6],
|
||||
arguments[7],
|
||||
arguments[8],
|
||||
arguments[9]
|
||||
);
|
||||
|
||||
// clean up memory allocation
|
||||
for(int i = 0; i < parameterCount; ++i)
|
||||
{
|
||||
QVariant::Type parameterType = parameterList.value(i).type();
|
||||
switch(parameterType)
|
||||
{
|
||||
case QVariant::Bool:
|
||||
delete static_cast<bool*>(arguments[i].data());
|
||||
break;
|
||||
case QVariant::Int:
|
||||
delete static_cast<int*>(arguments[i].data());
|
||||
break;
|
||||
case QVariant::String:
|
||||
delete static_cast<QString*>(arguments[i].data());
|
||||
break;
|
||||
case QVariant::List:
|
||||
delete static_cast<QVariantList*>(arguments[i].data());
|
||||
break;
|
||||
case QVariant::Map:
|
||||
delete static_cast<QVariantMap*>(arguments[i].data());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(success == false)
|
||||
{
|
||||
ret.code = JsonRpc::InternalError;
|
||||
ret.message = "Could not execute method.";
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret.succeeded = true;
|
||||
|
||||
switch(returnType)
|
||||
{
|
||||
case QVariant::Bool:
|
||||
ret.data = *static_cast<bool*>(returnValue.data());
|
||||
break;
|
||||
case QVariant::Int:
|
||||
ret.data = *static_cast<int*>(returnValue.data());
|
||||
break;
|
||||
case QVariant::String:
|
||||
ret.data = *static_cast<QString*>(returnValue.data());
|
||||
break;
|
||||
case QVariant::List:
|
||||
ret.data = *static_cast<QVariantList*>(returnValue.data());
|
||||
break;
|
||||
case QVariant::Map:
|
||||
ret.data = *static_cast<QVariantMap*>(returnValue.data());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void JsonRpcAdaptorPrivate::processJson(const QString& json)
|
||||
{
|
||||
m_jsonRpc.processJson(json);
|
||||
}
|
||||
}
|
||||
44
third-party/JsonQt/lib/JsonRpcAdaptorPrivate.h
vendored
Normal file
44
third-party/JsonQt/lib/JsonRpcAdaptorPrivate.h
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef _JSONQT_JSON_RPC_ADAPTOR_PRIVATE_H
|
||||
#define _JSONQT_JSON_RPC_ADAPTOR_PRIVATE_H
|
||||
|
||||
#include "JsonRpc.h"
|
||||
|
||||
#include <QMetaMethod>
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
class JsonRpcAdaptorPrivate : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JsonRpcAdaptorPrivate(QObject* adapt, QObject* parent);
|
||||
signals:
|
||||
void sendJson(const QString& json);
|
||||
public slots:
|
||||
void processJson(const QString& json);
|
||||
private slots:
|
||||
void requestReceived(const QVariant& id, const QString& method, const QVariant& parameters);
|
||||
private:
|
||||
struct ReturnData
|
||||
{
|
||||
bool succeeded;
|
||||
int code;
|
||||
QString message;
|
||||
QVariant data;
|
||||
};
|
||||
|
||||
void populateServiceDescription();
|
||||
QString getClassInfo(const char* name);
|
||||
ReturnData invokeMethod(const QString& method, const QVariant& parameters);
|
||||
|
||||
QMap<QString, QMetaMethod> m_methods;
|
||||
QMap<QString, QMap<QString, int> > m_parameterIndices;
|
||||
QVariantMap m_serviceDescription;
|
||||
JsonRpc m_jsonRpc;
|
||||
QObject* m_adapted;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
53
third-party/JsonQt/lib/JsonToProperties.cpp
vendored
Normal file
53
third-party/JsonQt/lib/JsonToProperties.cpp
vendored
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "JsonToProperties.h"
|
||||
|
||||
#include "JsonToVariant.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMetaObject>
|
||||
#include <QMetaProperty>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
JsonToProperties::JsonToProperties()
|
||||
{
|
||||
}
|
||||
|
||||
void JsonToProperties::parse(const QString& json, QObject* object)
|
||||
throw(ParseException)
|
||||
{
|
||||
QVariantMap dataMap = JsonToVariant::parse(json).toMap();
|
||||
|
||||
const QMetaObject* meta = object->metaObject();
|
||||
for(
|
||||
int i = 0;
|
||||
i < meta->propertyCount();
|
||||
++i
|
||||
)
|
||||
{
|
||||
QMetaProperty property = meta->property(i);
|
||||
if(dataMap.contains(property.name()))
|
||||
{
|
||||
QVariant data = dataMap[property.name()];
|
||||
if(data.canConvert(property.type()))
|
||||
property.write(object, data);
|
||||
else
|
||||
qDebug() << QObject::tr("Found property %1 with incompatible data type.").arg(property.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
52
third-party/JsonQt/lib/JsonToProperties.h
vendored
Normal file
52
third-party/JsonQt/lib/JsonToProperties.h
vendored
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef _JSONQT_JSON_TO_PROPERTIES_H
|
||||
#define _JSONQT_JSON_TO_PROPERTIES_H
|
||||
|
||||
#include "ParseException.h"
|
||||
#include "JsonQtExport.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
/** Class for setting the properties of a QObject from a JSON string.
|
||||
* Note that this only pays attention to basic types in the top level
|
||||
* object in the JSON.
|
||||
*
|
||||
* @author Fred Emmott <mail@fredemmott.co.uk>
|
||||
*/
|
||||
class JSONQT_EXPORT JsonToProperties
|
||||
{
|
||||
public:
|
||||
/** Main parsing function.
|
||||
*
|
||||
* @param json is a string containing JSON text.
|
||||
* @param object is an object with properties to be
|
||||
* filled from JSON.
|
||||
* @throws ParseException if the string provided is not
|
||||
* valid JSON (or at least this parser thinks it
|
||||
* isn't ;) )
|
||||
*/
|
||||
static void parse(const QString& json, QObject* object)
|
||||
throw(ParseException);
|
||||
private:
|
||||
JsonToProperties();
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
606
third-party/JsonQt/lib/JsonToVariant.cpp
vendored
Normal file
606
third-party/JsonQt/lib/JsonToVariant.cpp
vendored
Normal file
|
|
@ -0,0 +1,606 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "JsonToVariant.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#define FAIL(x) throw ParseException(*m_sym, x, remaining())
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
JsonToVariant::JsonToVariant(){}
|
||||
|
||||
QVariant JsonToVariant::parse(const QString& json) throw(ParseException)
|
||||
{
|
||||
JsonToVariant parser;
|
||||
// Store the start and end of the string
|
||||
parser.m_next = json.constBegin();
|
||||
parser.m_sym = parser.m_next;
|
||||
parser.m_end = json.constEnd();
|
||||
// Parse any JSON value.
|
||||
return parser.parseValue();
|
||||
}
|
||||
|
||||
QList<QVariantMap> JsonToVariant::multiParse(const QString& raw) throw(ParseException)
|
||||
{
|
||||
QList<QVariantMap> objects;
|
||||
QString json(raw.trimmed());
|
||||
|
||||
JsonToVariant parser;
|
||||
// Store the start and end of the string
|
||||
parser.m_next = json.constBegin();
|
||||
parser.m_sym = parser.m_next;
|
||||
parser.m_end = json.constEnd();
|
||||
// A JSON Object is the top-level item in the parse tree
|
||||
do
|
||||
{
|
||||
objects.append(parser.parseObject());
|
||||
}
|
||||
while(parser.m_next != parser.m_end && parser.m_sym != parser.m_end);
|
||||
return objects;
|
||||
}
|
||||
|
||||
QVariantMap JsonToVariant::parseObject()
|
||||
{
|
||||
/*
|
||||
* object
|
||||
* {}
|
||||
* { members }
|
||||
*/
|
||||
|
||||
QVariantMap data;
|
||||
|
||||
consume('{');
|
||||
if(peekNext() != '}')
|
||||
data = parseMembers();
|
||||
consume('}');
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
QVariantMap JsonToVariant::parseMembers()
|
||||
{
|
||||
/*
|
||||
* members
|
||||
* pair
|
||||
* pair , members
|
||||
*/
|
||||
|
||||
QVariantMap data;
|
||||
QPair<QString, QVariant> pair;
|
||||
|
||||
// loop instead of recursing
|
||||
do
|
||||
{
|
||||
// Grab a pair
|
||||
pair = parsePair();
|
||||
|
||||
// Store it in our data
|
||||
data[pair.first] = pair.second;
|
||||
}
|
||||
while(tryConsume(',')); // Loop if we've got a list separator
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
QPair<QString, QVariant> JsonToVariant::parsePair()
|
||||
{
|
||||
/*
|
||||
* pair
|
||||
* string : value
|
||||
*/
|
||||
|
||||
QString key = parseString();
|
||||
consume(':');
|
||||
QVariant value = parseValue();
|
||||
|
||||
return qMakePair(key, value);
|
||||
}
|
||||
|
||||
QVariantList JsonToVariant::parseArray()
|
||||
{
|
||||
/*
|
||||
* array
|
||||
* []
|
||||
* [ elements ]
|
||||
*/
|
||||
|
||||
QVariantList data;
|
||||
|
||||
consume('[');
|
||||
if(peekNext() != ']')
|
||||
data = parseElements();
|
||||
consume(']');
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
QVariantList JsonToVariant::parseElements()
|
||||
{
|
||||
/*
|
||||
* elements
|
||||
* value
|
||||
* value , elements
|
||||
*/
|
||||
QVariantList data;
|
||||
|
||||
// loop instead of recursing
|
||||
do
|
||||
{
|
||||
// Grab a value
|
||||
data += parseValue();
|
||||
}
|
||||
while(tryConsume(',')); // repeat if we've got a list separator
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
QVariant JsonToVariant::parseValue()
|
||||
{
|
||||
/*
|
||||
* value
|
||||
* string
|
||||
* number
|
||||
* object
|
||||
* array
|
||||
* bool
|
||||
* null
|
||||
*/
|
||||
|
||||
tryConsume(':');
|
||||
|
||||
// Lookahead to work out the type of value
|
||||
switch(peekNext().toAscii())
|
||||
{
|
||||
case '"':
|
||||
return parseString();
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
case '-':
|
||||
return parseNumber();
|
||||
case '{':
|
||||
return parseObject();
|
||||
case '[':
|
||||
return parseArray();
|
||||
case 't': // true
|
||||
case 'f': // false
|
||||
return parseBool();
|
||||
case 'n': // null
|
||||
return parseNull();
|
||||
default:
|
||||
FAIL(QObject::tr("string, number, object, array, bool, or null"));
|
||||
}
|
||||
}
|
||||
|
||||
QString JsonToVariant::parseString()
|
||||
{
|
||||
/*
|
||||
* string
|
||||
* ""
|
||||
* " chars "
|
||||
*/
|
||||
|
||||
QString data;
|
||||
|
||||
// Starting quotation marks
|
||||
consume('"');
|
||||
|
||||
// If it's a non-empty string, grab the contents
|
||||
if(*m_next != '"')
|
||||
data = parseChars();
|
||||
|
||||
// Ending quotation marks
|
||||
consume('"');
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
QString JsonToVariant::parseChars()
|
||||
{
|
||||
/*
|
||||
* chars
|
||||
* char
|
||||
* char chars
|
||||
*/
|
||||
|
||||
QString data;
|
||||
|
||||
// chars contains at least one char
|
||||
data = parseChar();
|
||||
|
||||
while(peekNext() != '"')
|
||||
data.append( parseChar() );
|
||||
return data;
|
||||
}
|
||||
|
||||
QChar JsonToVariant::parseChar()
|
||||
{
|
||||
/*
|
||||
* char
|
||||
* any character except for ", \, or control characters
|
||||
* \"
|
||||
* \\
|
||||
* \/
|
||||
* \b
|
||||
* \f
|
||||
* \n
|
||||
* \r
|
||||
* \t
|
||||
* \u four-hex-digits
|
||||
*/
|
||||
|
||||
// Grab the next character, without skipping whitespace
|
||||
consume(false);
|
||||
|
||||
// We're not allowed unescaped quotation marks
|
||||
if(*m_sym == '"')
|
||||
FAIL(QObject::tr("Any unicode character except for \" or JSON escape sequences"));
|
||||
|
||||
// But some escape sequences are allowed
|
||||
if(*m_sym == '\\')
|
||||
{
|
||||
QString digits;
|
||||
switch(consume().toAscii())
|
||||
{
|
||||
case '"':
|
||||
return '"';
|
||||
case '\\':
|
||||
return '\\';
|
||||
case '/':
|
||||
return '/';
|
||||
case 'b':
|
||||
return '\b';
|
||||
case 'f':
|
||||
return '\f';
|
||||
case 'n':
|
||||
return '\n';
|
||||
case 'r':
|
||||
return '\r';
|
||||
case 't':
|
||||
return '\t';
|
||||
case 'u':
|
||||
// Unicode 4-digit hex
|
||||
for(int i = 0; i < 4; ++i)
|
||||
{
|
||||
digits += parseHexDigit();
|
||||
}
|
||||
return QChar(digits.toInt(0, 16));
|
||||
default:
|
||||
FAIL("[\"\\/bfnrtu]");
|
||||
}
|
||||
}
|
||||
return *m_sym;
|
||||
}
|
||||
|
||||
QVariant JsonToVariant::parseNumber()
|
||||
{
|
||||
/*
|
||||
* number
|
||||
* int
|
||||
* int frac
|
||||
* int exp
|
||||
* int frac exp
|
||||
*/
|
||||
|
||||
// Every JSON number starts with an int
|
||||
QString data = parseInt();
|
||||
|
||||
// Lookahead for fractions and exponents
|
||||
|
||||
// Do we have a fraction?
|
||||
if(*m_next == '.') data += parseFrac();
|
||||
// Do we have an exponent?
|
||||
if(*m_next == 'e' || *m_next == 'E') data += parseExp();
|
||||
|
||||
// Try several return types...
|
||||
bool ok;
|
||||
QVariant ret;
|
||||
|
||||
ret = data.toInt(&ok); if(ok) return ret;
|
||||
ret = data.toLongLong(&ok); if(ok) return ret;
|
||||
ret = data.toDouble(&ok); if(ok) return ret;
|
||||
|
||||
// If this point is reached, don't know how to convert the string
|
||||
// to an integer.
|
||||
Q_ASSERT(false);
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QString JsonToVariant::parseInt()
|
||||
{
|
||||
/*
|
||||
* int
|
||||
* digit
|
||||
* digit1-9 digits
|
||||
* - digit
|
||||
* - digit1-9 digits
|
||||
*/
|
||||
|
||||
QString data;
|
||||
|
||||
// Match any negation mark
|
||||
if(tryConsume('-'))
|
||||
data = "-";
|
||||
|
||||
// Grab the first digit...
|
||||
QChar firstDigit = parseDigit();
|
||||
data += firstDigit;
|
||||
// ...if it's not zero...
|
||||
if(firstDigit != '0')
|
||||
{
|
||||
// ... try and add more digits.
|
||||
try { data += parseDigits(); }
|
||||
catch(ParseException)
|
||||
{
|
||||
// Catch, as more digits are entirely optional
|
||||
// Roll back.
|
||||
m_next = m_sym--;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
QString JsonToVariant::parseFrac()
|
||||
{
|
||||
/*
|
||||
* frac
|
||||
* . digits
|
||||
*/
|
||||
|
||||
consume('.');
|
||||
return QString(".%1").arg(parseDigits());
|
||||
}
|
||||
|
||||
QString JsonToVariant::parseExp()
|
||||
{
|
||||
/*
|
||||
* exp
|
||||
* e digits
|
||||
*/
|
||||
|
||||
QString data;
|
||||
data = parseE();
|
||||
data += parseDigits();
|
||||
return data;
|
||||
}
|
||||
|
||||
QString JsonToVariant::parseDigits()
|
||||
{
|
||||
/*
|
||||
* digits
|
||||
* digit
|
||||
* digit digits
|
||||
*/
|
||||
|
||||
QString data;
|
||||
|
||||
// Digits has at least one digit...
|
||||
data += parseDigit();
|
||||
|
||||
// ... try and get some more
|
||||
// Loop instead of recurse
|
||||
Q_FOREVER
|
||||
{
|
||||
try { data += parseDigit(); }
|
||||
catch(ParseException)
|
||||
{
|
||||
m_next = m_sym--; // roll back
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
QString JsonToVariant::parseE()
|
||||
{
|
||||
/*
|
||||
* e
|
||||
* e
|
||||
* e+
|
||||
* e-
|
||||
* E
|
||||
* E+
|
||||
* E-
|
||||
*/
|
||||
|
||||
// Try and grab an 'e' or 'E'
|
||||
if(consume(false).toLower() == 'e')
|
||||
{
|
||||
// digits in follow[e]
|
||||
if(m_next->isDigit())
|
||||
return "e";
|
||||
|
||||
// Hopefully the next is a + or -
|
||||
// grab another chracter...
|
||||
consume(false);
|
||||
// If it's not + or -, fail
|
||||
if(*m_sym != '+' && *m_sym != '-')
|
||||
FAIL("+ | -");
|
||||
|
||||
// Otherwise, return e[+-]
|
||||
return QString("e%1").arg(*m_sym);
|
||||
}
|
||||
else
|
||||
FAIL("e | E");
|
||||
}
|
||||
|
||||
|
||||
QChar JsonToVariant::parseDigit()
|
||||
{
|
||||
/*
|
||||
* digit
|
||||
* [0-9]
|
||||
*/
|
||||
|
||||
if(!consume(false).isDigit())
|
||||
FAIL("[0-9]");
|
||||
return *m_sym;
|
||||
}
|
||||
|
||||
QChar JsonToVariant::parseHexDigit()
|
||||
{
|
||||
/*
|
||||
* hexdigit
|
||||
* [0-9a-fA-F]
|
||||
*/
|
||||
|
||||
QChar character = consume().toLower();
|
||||
if(character.isDigit() || (character >= 'a' && character <= 'f'))
|
||||
return character;
|
||||
FAIL("[0-9a-fA-F]");
|
||||
}
|
||||
|
||||
bool JsonToVariant::parseBool()
|
||||
{
|
||||
/*
|
||||
* bool
|
||||
* true
|
||||
* false
|
||||
*/
|
||||
|
||||
switch(peekNext().toAscii())
|
||||
{
|
||||
case 't':
|
||||
consume(QString("true"));
|
||||
return true;
|
||||
case 'f':
|
||||
consume(QString("false"));
|
||||
return false;
|
||||
default:
|
||||
consume(false);
|
||||
FAIL("true | false");
|
||||
}
|
||||
}
|
||||
|
||||
QVariant JsonToVariant::parseNull()
|
||||
{
|
||||
/*
|
||||
* null
|
||||
* null
|
||||
*/
|
||||
|
||||
consume(QString("null"));
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QString JsonToVariant::remaining()
|
||||
{
|
||||
QString data;
|
||||
|
||||
QString::ConstIterator it = m_sym;
|
||||
while(it != m_end) data += *it++;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
QChar JsonToVariant::consume(bool skipWhitespace) throw(ParseException)
|
||||
{
|
||||
// Read a character...
|
||||
do
|
||||
{
|
||||
if(m_next == m_end)
|
||||
{
|
||||
throw ParseException("EOF", "symbol", remaining());
|
||||
}
|
||||
m_sym = m_next++;
|
||||
}
|
||||
//...and loop while we get whitespace, if it's being skipped
|
||||
while(skipWhitespace && m_sym->isSpace());
|
||||
|
||||
// Just for convenience...
|
||||
return *m_sym;
|
||||
}
|
||||
|
||||
void JsonToVariant::consume(QChar wanted) throw(ParseException)
|
||||
{
|
||||
// Grab a char(ignoring whitespace), and if it's not what's
|
||||
// expected, throw
|
||||
if(consume() != wanted)
|
||||
{
|
||||
FAIL(wanted);
|
||||
}
|
||||
}
|
||||
|
||||
void JsonToVariant::consume(char wanted) throw(ParseException)
|
||||
{
|
||||
// Convenience function for the above
|
||||
consume(QChar(wanted));
|
||||
}
|
||||
|
||||
void JsonToVariant::consume(QString wanted) throw(ParseException)
|
||||
{
|
||||
// Keep track of where we start...
|
||||
QString::ConstIterator it = m_sym;
|
||||
// Grab wanted.length() characters, and compare them to the
|
||||
// character in the appropriate position in the parameter
|
||||
for(int i = 0; i < wanted.length(); ++i)
|
||||
if(consume(false) != wanted[i])
|
||||
{
|
||||
// If it doesn't match, roll back, and throw a
|
||||
// parse exception
|
||||
m_sym = it;
|
||||
m_next = ++it;
|
||||
FAIL(wanted);
|
||||
}
|
||||
}
|
||||
|
||||
bool JsonToVariant::tryConsume(QChar wanted) throw()
|
||||
{
|
||||
// Grab the next character
|
||||
try
|
||||
{
|
||||
consume();
|
||||
}
|
||||
catch(ParseException)
|
||||
{
|
||||
// End-Of-String, rollback and return false
|
||||
m_next = m_sym--;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if it's what we want
|
||||
if(*m_sym != wanted)
|
||||
{
|
||||
// nope, something else, rollback and return false
|
||||
m_next = m_sym--;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
QChar JsonToVariant::peekNext(bool skipWhitespace) throw(ParseException)
|
||||
{
|
||||
QString::ConstIterator it = m_sym;
|
||||
do
|
||||
{
|
||||
++it;
|
||||
if(it == m_end)
|
||||
{
|
||||
FAIL("symbol");
|
||||
}
|
||||
}
|
||||
while(skipWhitespace && it->isSpace());
|
||||
return *it;
|
||||
}
|
||||
}
|
||||
160
third-party/JsonQt/lib/JsonToVariant.h
vendored
Normal file
160
third-party/JsonQt/lib/JsonToVariant.h
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef _JSONQT_JSON_TO_VARIANT_H
|
||||
#define _JSONQT_JSON_TO_VARIANT_H
|
||||
|
||||
#include "ParseException.h"
|
||||
|
||||
#include "JsonQtExport.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
/** Qt-based JSON handling.
|
||||
* This is based on a recursive descent parser with 1-character lookahed,
|
||||
* and follows the structure of the grammar presented on json.org as closely
|
||||
* as possible, to avoid mistakes, and hopefully to make the code more readable.
|
||||
*
|
||||
* @author Fred Emmott <mail@fredemmott.co.uk>
|
||||
*/
|
||||
namespace JsonQt
|
||||
{
|
||||
/** Class for converting JSON strings to QVariant-based structures.
|
||||
*
|
||||
* @author Fred Emmott <mail@fredemmott.co.uk>
|
||||
*/
|
||||
class JSONQT_EXPORT JsonToVariant
|
||||
{
|
||||
public:
|
||||
/** Main parsing function.
|
||||
*
|
||||
* @param json is a string containing JSON text.
|
||||
* @returns A QVariant-representation of the JSON
|
||||
* structure.
|
||||
* @throws ParseException if the string provided is not
|
||||
* valid JSON (or at least this parser thinks it
|
||||
* isn't ;) )
|
||||
*/
|
||||
static QVariant parse(const QString& json) throw (ParseException);
|
||||
|
||||
/** Parse multiple objects in one string.
|
||||
* This is useful when working on streams where
|
||||
* one-chunk-per-json-object is not guaranteed.
|
||||
*/
|
||||
static QList<QVariantMap> multiParse(const QString& json) throw(ParseException);
|
||||
private:
|
||||
JsonToVariant();
|
||||
// Parsers for types given on JSON.org
|
||||
QVariantMap parseObject();
|
||||
QVariantMap parseMembers();
|
||||
QPair<QString, QVariant> parsePair();
|
||||
QVariantList parseArray();
|
||||
QVariantList parseElements();
|
||||
QVariant parseValue();
|
||||
QString parseString();
|
||||
QString parseChars();
|
||||
QChar parseChar();
|
||||
QVariant parseNumber();
|
||||
QString parseInt();
|
||||
QString parseFrac();
|
||||
QString parseExp();
|
||||
QString parseDigits();
|
||||
QString parseE();
|
||||
|
||||
// Parsers for types implied on JSON.org
|
||||
QChar parseDigit();
|
||||
QChar parseHexDigit();
|
||||
bool parseBool();
|
||||
QVariant parseNull();
|
||||
|
||||
// Internal functions
|
||||
/// The unparsed part of the input string.
|
||||
inline QString remaining();
|
||||
|
||||
/** Consume the next character.
|
||||
* Advances m_sym to the next character, and returns it.
|
||||
* Optionally skips over whitespace.
|
||||
*
|
||||
* @param skipWhitespace controls if whitespace is
|
||||
* ignored.
|
||||
* @returns *m_sym
|
||||
* @throws ParseException if the end of the string is
|
||||
* reached.
|
||||
*/
|
||||
QChar consume(bool skipWhitespace = true)
|
||||
throw(ParseException);
|
||||
|
||||
/** Consume the next character, and check for equality
|
||||
* with the specified character.
|
||||
*
|
||||
* @param wanted is the character to compare to.
|
||||
* @throws ParseException if the end of the string is
|
||||
* reached, or the characaters are not equal.
|
||||
*/
|
||||
void consume(QChar wanted) throw(ParseException);
|
||||
|
||||
/// Convenience function for consume(QChar).
|
||||
void consume(char wanted) throw(ParseException);
|
||||
|
||||
/** Attempt to consume the specified string.
|
||||
* This attempts to consume length(wanted) characters,
|
||||
* including whitespace, and checks that they are equal
|
||||
* to the characters in the same position in the
|
||||
* specified string.
|
||||
*
|
||||
* @param wanted is the string to attempt to consume.
|
||||
* @throws ParseException if the end of the string is
|
||||
* reached, or the string comparisson fails.
|
||||
*/
|
||||
void consume(QString wanted) throw(ParseException);
|
||||
|
||||
/** Try to consume a single character, without throw.
|
||||
* This will try to read a single character, and
|
||||
* compares to the specified character.
|
||||
*
|
||||
* @param wanted is the character to compare to.
|
||||
* @returns true if the character specified was
|
||||
* successfully consumed.
|
||||
* @returns false if the end of the string was reached,
|
||||
* or the characters were not equal.
|
||||
*/
|
||||
bool tryConsume(QChar wanted) throw();
|
||||
|
||||
/** Return the next symbol.
|
||||
* Optionally skips whitespace.
|
||||
*
|
||||
* @param skipWhitespace sets the whitespace handling.
|
||||
* @returns the next symbol.
|
||||
* @throws ParseException if the end of the string is
|
||||
* reached.
|
||||
*/
|
||||
QChar peekNext(bool skipWhitespace = true)
|
||||
throw(ParseException);
|
||||
|
||||
// Variables
|
||||
|
||||
/// Iterator pointing at the current symbol.
|
||||
QString::ConstIterator m_sym;
|
||||
/// Iterator pointing at the next symbol.
|
||||
QString::ConstIterator m_next;
|
||||
/// Iterator pointing at the end of the string.
|
||||
QString::ConstIterator m_end;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
47
third-party/JsonQt/lib/ParseException.cpp
vendored
Normal file
47
third-party/JsonQt/lib/ParseException.cpp
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "ParseException.h"
|
||||
|
||||
// For QObject::tr
|
||||
#include <QObject>
|
||||
|
||||
#include "psilogger.h"
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
ParseException::ParseException(const QString& got, const QString& expected, const QString& remaining) throw()
|
||||
:
|
||||
m_got(got),
|
||||
m_expected(expected),
|
||||
m_remaining(remaining)
|
||||
{
|
||||
PsiLogger::instance()->log(QString("JsonQt::ParseException(): got = %1; expected = %2; remaining = %3")
|
||||
.arg(got)
|
||||
.arg(expected)
|
||||
.arg(remaining));
|
||||
}
|
||||
|
||||
ParseException::~ParseException() throw(){}
|
||||
|
||||
const char* ParseException::what() const throw()
|
||||
{
|
||||
return qPrintable(QObject::tr("A parsing error occurred:\n\tGot: '%1'\n\tExpected: '%2'\n\tAt: '%3'").arg(m_got).arg(m_expected).arg(m_remaining));
|
||||
}
|
||||
|
||||
QString ParseException::got() { return m_got; }
|
||||
QString ParseException::expected() { return m_expected; }
|
||||
QString ParseException::remaining() { return m_remaining; }
|
||||
}
|
||||
63
third-party/JsonQt/lib/ParseException.h
vendored
Normal file
63
third-party/JsonQt/lib/ParseException.h
vendored
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#ifndef _JSONQT_PARSE_EXCEPTION_H
|
||||
#define _JSONQT_PARSE_EXCEPTION_H
|
||||
|
||||
#include "JsonQtExport.h"
|
||||
|
||||
#include <exception>
|
||||
#include <QChar>
|
||||
#include <QString>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
/** Parsing exception class.
|
||||
* Raised whenever JsonQt can't pass something it's been given, for
|
||||
* whatever reason.
|
||||
*/
|
||||
class JSONQT_EXPORT ParseException : public std::exception
|
||||
{
|
||||
public:
|
||||
/** Create a ParseException.
|
||||
* @param got is what was found in the string.
|
||||
* @param expected is what the parser was expecting.
|
||||
* @param remaining is what was left of the input.
|
||||
*/
|
||||
ParseException(
|
||||
const QString& got,
|
||||
const QString& expected,
|
||||
const QString& remaining
|
||||
) throw();
|
||||
~ParseException() throw();
|
||||
|
||||
/// A single string providing information on the
|
||||
/// exception.
|
||||
virtual const char* what() const throw();
|
||||
|
||||
/// What the parser found.
|
||||
QString got();
|
||||
/// What the parser was expecting.
|
||||
QString expected();
|
||||
/// The remaining unparsed input.
|
||||
QString remaining();
|
||||
private:
|
||||
QString m_got;
|
||||
QString m_expected;
|
||||
QString m_remaining;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
64
third-party/JsonQt/lib/VariantToJson.cpp
vendored
Normal file
64
third-party/JsonQt/lib/VariantToJson.cpp
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include "VariantToJson.h"
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
QString VariantToJson::parse(const QVariantMap& data)
|
||||
{
|
||||
QStringList members;
|
||||
for(QVariantMap::ConstIterator it = data.begin(); it != data.end(); ++it)
|
||||
{
|
||||
members.append(QString("\"%1\": %2").arg(it.key()).arg(parseElement(it.value())));
|
||||
}
|
||||
return "{" + members.join(", ") + "}";
|
||||
}
|
||||
QString VariantToJson::parseElement(const QVariant& value)
|
||||
{
|
||||
switch(value.type())
|
||||
{
|
||||
case QVariant::Bool:
|
||||
return value.toBool() ? "true" : "false";
|
||||
case QVariant::Map:
|
||||
return parse(value.toMap());
|
||||
case QVariant::Int:
|
||||
return QString::number(value.toInt());
|
||||
case QVariant::LongLong:
|
||||
return QString::number(value.toLongLong());
|
||||
case QVariant::Double:
|
||||
return QString::number(value.toDouble());
|
||||
case QVariant::UInt:
|
||||
return QString::number(value.toUInt());
|
||||
case QVariant::ULongLong:
|
||||
return QString::number(value.toULongLong());
|
||||
case QVariant::List:
|
||||
return parseList(value.toList());
|
||||
case QVariant::String:
|
||||
return QString("\"%1\"").arg(value.toString().replace("\\", "\\\\").replace("\"", "\\\""));
|
||||
case QVariant::StringList:
|
||||
return parseStringList(value.toStringList());
|
||||
case QVariant::Invalid:
|
||||
return "null";
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
QString VariantToJson::parseList(const QVariantList& list)
|
||||
{
|
||||
QStringList parts;
|
||||
Q_FOREACH(QVariant variant, list)
|
||||
{
|
||||
parts.append(parseElement(variant));
|
||||
}
|
||||
return "[" + parts.join(", ") + "]";
|
||||
}
|
||||
|
||||
QString VariantToJson::parseStringList(const QStringList& stringList)
|
||||
{
|
||||
QVariantList variantList;
|
||||
Q_FOREACH(const QString& string, stringList)
|
||||
{
|
||||
variantList.append(string);
|
||||
}
|
||||
return parseList(variantList);
|
||||
}
|
||||
}
|
||||
40
third-party/JsonQt/lib/VariantToJson.h
vendored
Normal file
40
third-party/JsonQt/lib/VariantToJson.h
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef _JSONQT_VARIANT_TO_JSON_H
|
||||
#define _JSONQT_VARIANT_TO_JSON_H
|
||||
|
||||
#include "JsonQtExport.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QVariant>
|
||||
|
||||
namespace JsonQt
|
||||
{
|
||||
/** Class for converting QVariants into JSON structures.
|
||||
*
|
||||
* The following variant types are supported:
|
||||
* - QVariant::Bool
|
||||
* - QVariant::String
|
||||
* - QVariant::Double
|
||||
* - QVariant::Int
|
||||
* - QVariant::LongLong
|
||||
* - QVariant::UInt
|
||||
* - QVariant::ULongLong
|
||||
* - QVariant::Invalid
|
||||
* - QVariant::List // JSON array
|
||||
* - QVariant::Map // JSON object
|
||||
*
|
||||
* @author Fred Emmott <mail@fredemmott.co.uk>
|
||||
*/
|
||||
class JSONQT_EXPORT VariantToJson
|
||||
{
|
||||
public:
|
||||
/// Parse a QVariant into JSON.
|
||||
static QString parse(const QVariantMap& data);
|
||||
private:
|
||||
static QString parseElement(const QVariant& element);
|
||||
static QString parseList(const QVariantList& list);
|
||||
static QString parseStringList(const QStringList& list);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
44
third-party/JsonQt/tests/CMakeLists.txt
vendored
Normal file
44
third-party/JsonQt/tests/CMakeLists.txt
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
SET(
|
||||
TESTS
|
||||
JsonRpc
|
||||
JsonRpcAdaptor
|
||||
JsonToProperties
|
||||
JsonToVariant
|
||||
VariantToJson
|
||||
)
|
||||
|
||||
##### Probably don't want to edit below this line #####
|
||||
|
||||
# Find Qt4
|
||||
FIND_PACKAGE( Qt4 REQUIRED )
|
||||
|
||||
# Pick modules
|
||||
SET( QT_DONT_USE_QTGUI TRUE )
|
||||
SET( QT_USE_QTTEST TRUE )
|
||||
|
||||
# Use it
|
||||
INCLUDE( ${QT_USE_FILE} )
|
||||
|
||||
# Include the library include directories, and the current build directory (moc)
|
||||
INCLUDE_DIRECTORIES(
|
||||
../lib
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
|
||||
# Build the tests
|
||||
INCLUDE(AddFileDependencies)
|
||||
FOREACH(test ${TESTS})
|
||||
MESSAGE(STATUS "Building ${test}")
|
||||
QT4_WRAP_CPP(MOC_SOURCE ${test}.cpp)
|
||||
ADD_EXECUTABLE(
|
||||
${test}
|
||||
${test}.cpp
|
||||
|
||||
)
|
||||
ADD_FILE_DEPENDENCIES(${test}.cpp ${MOC_SOURCE})
|
||||
TARGET_LINK_LIBRARIES(
|
||||
${test}
|
||||
${QT_LIBRARIES}
|
||||
JsonQt
|
||||
)
|
||||
ENDFOREACH()
|
||||
300
third-party/JsonQt/tests/JsonRpc.cpp
vendored
Normal file
300
third-party/JsonQt/tests/JsonRpc.cpp
vendored
Normal file
|
|
@ -0,0 +1,300 @@
|
|||
#include "JsonRpc.h"
|
||||
#include "JsonToVariant.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <QSignalSpy>
|
||||
|
||||
/// Check that JSON a gets error code b
|
||||
#define ERROR_TEST(a, b) \
|
||||
JsonQt::JsonRpc t; \
|
||||
QSignalSpy jsonSpy(&t, SIGNAL(sendJson(const QString&))); \
|
||||
t.processJson(a); \
|
||||
\
|
||||
QCOMPARE(jsonSpy.count(), 1); \
|
||||
\
|
||||
QString json(jsonSpy.first().first().toString()); \
|
||||
QVariantMap response = JsonQt::JsonToVariant::parse(json).toMap(); \
|
||||
\
|
||||
QVERIFY(response.contains("error")); \
|
||||
QCOMPARE(response.value("error").type(), QVariant::Map); \
|
||||
\
|
||||
QVariantMap error = response.value("error").toMap(); \
|
||||
QVERIFY(error.contains("code")); \
|
||||
QVERIFY(error.contains("message")); \
|
||||
\
|
||||
QCOMPARE(error.value("code").type(), QVariant::Int); \
|
||||
QCOMPARE(error.value("code").toInt(), static_cast<int>(b));
|
||||
|
||||
/// Get a QVariantMap from spy
|
||||
#define GET_DATA() \
|
||||
QCOMPARE(spy.count(), 1); \
|
||||
QCOMPARE(spy.first().first().type(), QVariant::String); \
|
||||
QVariantMap data(JsonQt::JsonToVariant::parse(spy.first().first().toString()).toMap());
|
||||
|
||||
/// Setup client and server JsonRpc instances
|
||||
#define SETUP_CLIENT_SERVER() \
|
||||
JsonQt::JsonRpc client; \
|
||||
JsonQt::JsonRpc server; \
|
||||
\
|
||||
connect( \
|
||||
&client, SIGNAL(sendJson(const QString&)), \
|
||||
&server, SLOT(processJson(const QString&)) \
|
||||
);
|
||||
|
||||
Q_DECLARE_METATYPE(QVariant);
|
||||
|
||||
class JsonRpc : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
qRegisterMetaType<QVariant>("QVariant");
|
||||
}
|
||||
|
||||
void testInvalidJson()
|
||||
{
|
||||
ERROR_TEST("{", JsonQt::JsonRpc::InvalidJson);
|
||||
}
|
||||
|
||||
void testEmptyJsonObject()
|
||||
{
|
||||
ERROR_TEST("{}", JsonQt::JsonRpc::InvalidJsonRpc);
|
||||
}
|
||||
|
||||
void testSimpleNotificationReceived()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(notificationReceived(const QString&, const QVariant&)));
|
||||
t.processJson(
|
||||
"{"
|
||||
"\"jsonrpc\": \"2.0\","
|
||||
"\"method\": \"ping\""
|
||||
"}"
|
||||
);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().first().toString(), QString("ping"));
|
||||
}
|
||||
|
||||
void testSimpleRequestReceived()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy requestSpy(&t, SIGNAL(requestReceived(const QVariant&, const QString&, const QVariant&)));
|
||||
t.processJson(
|
||||
"{"
|
||||
"\"jsonrpc\": \"2.0\","
|
||||
"\"method\": \"ping\","
|
||||
"\"id\": 9001"
|
||||
"}"
|
||||
);
|
||||
QCOMPARE(requestSpy.count(), 1);
|
||||
// method
|
||||
QCOMPARE(requestSpy.first().value(1).toString(), QString("ping"));
|
||||
// id
|
||||
QVariant id = requestSpy.first().value(0).value<QVariant>();
|
||||
QCOMPARE(id.type(), QVariant::Int);
|
||||
QCOMPARE(id.toInt(), 9001);
|
||||
}
|
||||
|
||||
void testErrorReceived()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(errorReceived(const QVariant&, int, const QString&, const QVariant&)));
|
||||
t.processJson(
|
||||
"{"
|
||||
"\"jsonrpc\": \"2.0\","
|
||||
"\"error\":"
|
||||
"{"
|
||||
"\"code\": 1234,"
|
||||
"\"message\": \"foo\","
|
||||
"\"data\": \"bar\""
|
||||
"},"
|
||||
"\"id\": 9001"
|
||||
"}"
|
||||
);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
|
||||
// id
|
||||
QVariant id = spy.first().first().value<QVariant>();
|
||||
QCOMPARE(id.type(), QVariant::Int);
|
||||
QCOMPARE(id.toInt(), 9001);
|
||||
// code
|
||||
QCOMPARE(spy.first().value(1).type(), QVariant::Int);
|
||||
QCOMPARE(spy.first().value(1).toInt(), 1234);
|
||||
// message
|
||||
QCOMPARE(spy.first().value(2).type(), QVariant::String);
|
||||
QCOMPARE(spy.first().value(2).toString(), QString("foo"));
|
||||
// data
|
||||
QVariant data = spy.first().value(3).value<QVariant>();
|
||||
QCOMPARE(data.type(), QVariant::String);
|
||||
QCOMPARE(data.toString(), QString("bar"));
|
||||
}
|
||||
|
||||
void testJsonRpcVersion()
|
||||
{
|
||||
QString testString =
|
||||
"{"
|
||||
"\"jsonrpc\": \"9001\","
|
||||
"\"method\": \"ping\""
|
||||
"}";
|
||||
ERROR_TEST(testString, JsonQt::JsonRpc::InvalidJsonRpc);
|
||||
}
|
||||
|
||||
void testComplexNotificationReceived()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(notificationReceived(const QString&, const QVariant&)));
|
||||
t.processJson(
|
||||
"{"
|
||||
"\"jsonrpc\": \"2.0\","
|
||||
"\"method\": \"ping\","
|
||||
"\"params\":"
|
||||
"{"
|
||||
"\"foo\": \"bar\","
|
||||
"\"123\": 456"
|
||||
"}"
|
||||
"}"
|
||||
);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
|
||||
QCOMPARE(spy.first().first().toString(), QString("ping"));
|
||||
QVariantMap parameters = spy.first().value(1).value<QVariant>().toMap();
|
||||
|
||||
QVERIFY(parameters.contains("foo"));
|
||||
QCOMPARE(parameters.value("foo").type(), QVariant::String);
|
||||
QCOMPARE(parameters.value("foo").toString(), QString("bar"));
|
||||
QVERIFY(parameters.contains("123"));
|
||||
QCOMPARE(parameters.value("123").type(), QVariant::Int);
|
||||
QCOMPARE(parameters.value("123").toInt(), 456);
|
||||
}
|
||||
|
||||
void testSendingSimpleNotification()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
|
||||
t.sendNotification("foo");
|
||||
GET_DATA();
|
||||
QCOMPARE(data.value("method").toString(), QString("foo"));
|
||||
QVERIFY(!data.contains("id"));
|
||||
QVERIFY(!data.contains("params"));
|
||||
}
|
||||
|
||||
void testSendingSimpleRequest()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
|
||||
t.sendRequest(QVariant(123), "foo");
|
||||
GET_DATA();
|
||||
QCOMPARE(data.value("method").toString(), QString("foo"));
|
||||
QCOMPARE(data.value("id").toInt(), 123);
|
||||
QVERIFY(!data.contains("params"));
|
||||
}
|
||||
|
||||
void testSendingResponse()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
|
||||
t.sendResponse(QVariant(123), "foo");
|
||||
GET_DATA();
|
||||
QCOMPARE(data.value("result").toString(), QString("foo"));
|
||||
QCOMPARE(data.value("id").toInt(), 123);
|
||||
}
|
||||
|
||||
void testSendingError()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
|
||||
t.sendError(QVariant(123), 456, "foo", QVariant(789));
|
||||
GET_DATA();
|
||||
QCOMPARE(data.value("id").toInt(), 123);
|
||||
QCOMPARE(data.value("error").type(), QVariant::Map);
|
||||
QVariantMap error = data.value("error").toMap();
|
||||
QCOMPARE(error.value("code").toInt(), 456);
|
||||
QCOMPARE(error.value("message").toString(), QString("foo"));
|
||||
QCOMPARE(error.value("data").toInt(), 789);
|
||||
|
||||
}
|
||||
|
||||
void testSendingComplexNotification()
|
||||
{
|
||||
JsonQt::JsonRpc t;
|
||||
QSignalSpy spy(&t, SIGNAL(sendJson(const QString&)));
|
||||
QVariantMap params;
|
||||
params["bar"] = "baz";
|
||||
t.sendNotification("foo", params);
|
||||
GET_DATA();
|
||||
QCOMPARE(data.value("method").toString(), QString("foo"));
|
||||
QVERIFY(!data.contains("id"));
|
||||
QCOMPARE(data.value("params").toMap(), params);
|
||||
}
|
||||
|
||||
void testNotificationBothEnds()
|
||||
{
|
||||
SETUP_CLIENT_SERVER();
|
||||
QSignalSpy spy(&server, SIGNAL(notificationReceived(const QString&, const QVariant&)));
|
||||
|
||||
QVariantMap params;
|
||||
params["bar"] = "baz";
|
||||
|
||||
client.sendNotification("foo", params);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().value(0).toString(), QString("foo"));
|
||||
QCOMPARE(spy.first().value(1).value<QVariant>().toMap(), params);
|
||||
}
|
||||
|
||||
void testRequestBothEnds()
|
||||
{
|
||||
SETUP_CLIENT_SERVER();
|
||||
QSignalSpy spy(&server, SIGNAL(requestReceived(const QVariant&, const QString&, const QVariant&)));
|
||||
|
||||
QVariantMap params;
|
||||
params["bar"] = "baz";
|
||||
|
||||
client.sendRequest(123, "foo", params);
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().value(0).value<QVariant>(), QVariant::fromValue<QVariant>(123));
|
||||
QCOMPARE(spy.first().value(1).toString(), QString("foo"));
|
||||
QCOMPARE(spy.first().value(2).value<QVariant>().toMap(), params);
|
||||
}
|
||||
|
||||
void testResponseBothEnds()
|
||||
{
|
||||
SETUP_CLIENT_SERVER();
|
||||
QSignalSpy spy(&server, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
|
||||
|
||||
client.sendResponse(123, "foo");
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().value(0).value<QVariant>(), QVariant::fromValue<QVariant>(123));
|
||||
QCOMPARE(spy.first().value(1).value<QVariant>().toString(), QString("foo"));
|
||||
}
|
||||
|
||||
void testErrorBothEnds()
|
||||
{
|
||||
SETUP_CLIENT_SERVER();
|
||||
QSignalSpy spy(&server, SIGNAL(errorReceived(const QVariant&, int, const QString&, const QVariant&)));
|
||||
|
||||
client.sendError(123, 456, "789", "foo");
|
||||
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().value(0).value<QVariant>(), QVariant::fromValue<QVariant>(123));
|
||||
QCOMPARE(spy.first().value(1).toInt(), 456);
|
||||
QCOMPARE(spy.first().value(2).toString(), QString("789"));
|
||||
QCOMPARE(spy.first().value(3).value<QVariant>().toString(), QString("foo"));
|
||||
}
|
||||
|
||||
void testJsonErrorBothEnds()
|
||||
{
|
||||
SETUP_CLIENT_SERVER();
|
||||
QSignalSpy spy(&server, SIGNAL(errorReceived(const QVariant&, int, const QString&, const QVariant&)));
|
||||
client.processJson("{");
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(spy.first().value(1).toInt(), static_cast<int>(JsonQt::JsonRpc::InvalidJson));
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(JsonRpc);
|
||||
|
||||
#include "moc_JsonRpc.cxx"
|
||||
258
third-party/JsonQt/tests/JsonRpcAdaptor.cpp
vendored
Normal file
258
third-party/JsonQt/tests/JsonRpcAdaptor.cpp
vendored
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
#include "JsonRpcAdaptor.h"
|
||||
|
||||
#include "JsonRpc.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
Q_DECLARE_METATYPE(QVariant);
|
||||
|
||||
class TestObject : public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
Q_CLASSINFO("JsonQt-RPC-name", "TestName");
|
||||
Q_CLASSINFO("JsonQt-RPC-id", "urn:data:test");
|
||||
Q_CLASSINFO("JsonQt-RPC-version", "9000.001");
|
||||
Q_CLASSINFO("JsonQt-RPC-summary", "Ponies");
|
||||
public:
|
||||
TestObject(QObject* parent) : QObject(parent) {}
|
||||
public slots:
|
||||
void functionOne(const QString& foo)
|
||||
{
|
||||
emit functionOneCalled(foo);
|
||||
}
|
||||
QString functionTwo()
|
||||
{
|
||||
emit functionTwoCalled();
|
||||
return "Mary had a little lamb.";
|
||||
}
|
||||
void functionThree(int one, bool two, QVariantList three, QVariantMap four)
|
||||
{
|
||||
emit functionThreeCalled(one, two, three, four);
|
||||
}
|
||||
void functionFour(const QString& foo, const QString& bar)
|
||||
{
|
||||
emit functionFourCalled(foo, bar);
|
||||
}
|
||||
signals:
|
||||
void functionOneCalled(const QString& foo);
|
||||
void functionTwoCalled();
|
||||
void functionThreeCalled(int, bool, QVariantList, QVariantMap);
|
||||
void functionFourCalled(QString, QString);
|
||||
};
|
||||
|
||||
class JsonRpcAdaptor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
qRegisterMetaType<QVariant>("QVariant");
|
||||
m_testObject = new TestObject(this);
|
||||
m_adaptor = new JsonQt::JsonRpcAdaptor(m_testObject, this);
|
||||
m_rpc = new JsonQt::JsonRpc(this);
|
||||
connect(
|
||||
m_rpc, SIGNAL(sendJson(const QString&)),
|
||||
m_adaptor, SLOT(processJson(const QString&))
|
||||
);
|
||||
connect(
|
||||
m_adaptor, SIGNAL(sendJson(const QString&)),
|
||||
m_rpc, SLOT(processJson(const QString&))
|
||||
);
|
||||
}
|
||||
|
||||
void testFunctionOne()
|
||||
{
|
||||
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionOneCalled(const QString&)));
|
||||
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
|
||||
|
||||
QVariantMap parameters;
|
||||
parameters["foo"] = "bar";
|
||||
|
||||
m_rpc->sendRequest(42, "functionOne", parameters);
|
||||
|
||||
QCOMPARE(testObjectSpy.count(), 1);
|
||||
QCOMPARE(testObjectSpy.first().first().toString(), QString("bar"));
|
||||
QCOMPARE(rpcSpy.count(), 1);
|
||||
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant(42));
|
||||
QCOMPARE(rpcSpy.first().value(1).value<QVariant>(), QVariant());
|
||||
}
|
||||
|
||||
void testFunctionFour()
|
||||
{
|
||||
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionFourCalled(QString, QString)));
|
||||
QVariantMap parameters;
|
||||
parameters["foo"] = "bar";
|
||||
parameters["bar"] = "baz";
|
||||
m_rpc->sendRequest(123, "functionFour", parameters);
|
||||
QCOMPARE(testObjectSpy.count(), 1);
|
||||
QCOMPARE(testObjectSpy.first().value(0).toString(), QString("bar"));
|
||||
QCOMPARE(testObjectSpy.first().value(1).toString(), QString("baz"));
|
||||
}
|
||||
|
||||
void testFunctionTwo()
|
||||
{
|
||||
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionTwoCalled()));
|
||||
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
|
||||
|
||||
m_rpc->sendRequest(1337, "functionTwo");
|
||||
|
||||
QCOMPARE(testObjectSpy.count(), 1);
|
||||
QCOMPARE(rpcSpy.count(), 1);
|
||||
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant(1337));
|
||||
QCOMPARE(rpcSpy.first().value(1).value<QVariant>().toString(), QString("Mary had a little lamb."));
|
||||
}
|
||||
|
||||
void testFunctionThree()
|
||||
{
|
||||
QSignalSpy testObjectSpy(m_testObject, SIGNAL(functionThreeCalled(int, bool, QVariantList, QVariantMap)));
|
||||
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
|
||||
|
||||
QVariantList listParameter;
|
||||
QVariantMap nestedMap;
|
||||
nestedMap["foo"] = "bar";
|
||||
|
||||
listParameter.append(nestedMap);
|
||||
listParameter.append("baz");
|
||||
|
||||
QVariantList parameters;
|
||||
parameters.append(123);
|
||||
parameters.append(true);
|
||||
parameters.append(listParameter);
|
||||
parameters.append(nestedMap);
|
||||
|
||||
m_rpc->sendRequest(42, "functionThree", parameters);
|
||||
|
||||
QCOMPARE(testObjectSpy.count(), 1);
|
||||
QVariantList result = testObjectSpy.first();
|
||||
QCOMPARE(result.value(0), QVariant(123));
|
||||
QCOMPARE(result.value(1), QVariant(true));
|
||||
QCOMPARE(result.value(2), QVariant(listParameter));
|
||||
QCOMPARE(result.value(3), QVariant(nestedMap));
|
||||
|
||||
QCOMPARE(rpcSpy.count(), 1);
|
||||
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant(42));
|
||||
QCOMPARE(rpcSpy.first().value(1).value<QVariant>(), QVariant());
|
||||
}
|
||||
|
||||
void testInvalidFunction()
|
||||
{
|
||||
QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant)));
|
||||
m_rpc->sendRequest("123", "DOES NOT EXIST");
|
||||
QCOMPARE(rpcSpy.count(), 1);
|
||||
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant("123"));
|
||||
QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::MethodNotFound));
|
||||
}
|
||||
|
||||
void testBadArgumentCount()
|
||||
{
|
||||
QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant)));
|
||||
m_rpc->sendRequest("123", "functionOne");
|
||||
QCOMPARE(rpcSpy.count(), 1);
|
||||
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant("123"));
|
||||
QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::BadParameters));
|
||||
}
|
||||
|
||||
void testWrongArgumentTypes()
|
||||
{
|
||||
QSignalSpy rpcSpy(m_rpc, SIGNAL(errorReceived(QVariant, int, QString, QVariant)));
|
||||
QVariantMap parameters;
|
||||
parameters["foo"] = 123;
|
||||
m_rpc->sendRequest("123", "functionOne", parameters);
|
||||
QCOMPARE(rpcSpy.count(), 1);
|
||||
QCOMPARE(rpcSpy.first().value(0).value<QVariant>(), QVariant("123"));
|
||||
QCOMPARE(rpcSpy.first().value(1), QVariant(JsonQt::JsonRpc::BadParameters));
|
||||
}
|
||||
|
||||
void testIntropection()
|
||||
{
|
||||
QSignalSpy rpcSpy(m_rpc, SIGNAL(responseReceived(const QVariant&, const QVariant&)));
|
||||
m_rpc->sendRequest(QVariant(), "system.describe");
|
||||
QCOMPARE(rpcSpy.count(), 1);
|
||||
QVariantMap introspectionData = rpcSpy.first().value(1).value<QVariant>().toMap();
|
||||
QVERIFY(!introspectionData.isEmpty());
|
||||
|
||||
// Service data
|
||||
QCOMPARE(introspectionData.value("sdversion").toString(), QString("1.0")); // Service Description version
|
||||
QCOMPARE(introspectionData.value("name").toString(), QString("TestName"));
|
||||
QCOMPARE(introspectionData.value("id").toString(), QString("urn:data:test"));
|
||||
QCOMPARE(introspectionData.value("version").toString(), QString("9000.001"));
|
||||
QCOMPARE(introspectionData.value("summary").toString(), QString("Ponies"));
|
||||
QVERIFY(!introspectionData.contains("help"));
|
||||
QVERIFY(introspectionData.contains("procs"));
|
||||
|
||||
// Method data
|
||||
QVariantList methods = introspectionData.value("procs").toList();
|
||||
QCOMPARE(methods.count(), 4);
|
||||
QVariantMap functionOne = methods.takeFirst().toMap();
|
||||
QVariantMap functionTwo = methods.takeFirst().toMap();
|
||||
QVariantMap functionThree = methods.takeFirst().toMap();
|
||||
QVariantMap functionFour = methods.takeFirst().toMap();
|
||||
|
||||
QVariantList params;
|
||||
QVariantMap param;
|
||||
|
||||
// functionOne
|
||||
QCOMPARE(functionOne.value("name").toString(), QString("functionOne"));
|
||||
QCOMPARE(functionOne.value("return").toString(), QString("nil"));
|
||||
|
||||
params = functionOne.value("params").toList();
|
||||
QCOMPARE(params.count(), 1);
|
||||
|
||||
param = params.first().toMap();
|
||||
QCOMPARE(param.value("name").toString(), QString("foo"));
|
||||
QCOMPARE(param.value("type").toString(), QString("str"));
|
||||
|
||||
// functionTwo
|
||||
QCOMPARE(functionTwo.value("name").toString(), QString("functionTwo"));
|
||||
QCOMPARE(functionTwo.value("return").toString(), QString("str"));
|
||||
|
||||
params = functionTwo.value("params").toList();
|
||||
QCOMPARE(params.count(), 0);
|
||||
|
||||
// functionThree
|
||||
QCOMPARE(functionThree.value("name").toString(), QString("functionThree"));
|
||||
QCOMPARE(functionThree.value("return").toString(), QString("nil"));
|
||||
|
||||
params = functionThree.value("params").toList();
|
||||
QCOMPARE(params.count(), 4);
|
||||
|
||||
param = params.takeFirst().toMap();
|
||||
QCOMPARE(param.value("name").toString(), QString("one"));
|
||||
QCOMPARE(param.value("type").toString(), QString("num"));
|
||||
|
||||
param = params.takeFirst().toMap();
|
||||
QCOMPARE(param.value("name").toString(), QString("two"));
|
||||
QCOMPARE(param.value("type").toString(), QString("bit"));
|
||||
|
||||
param = params.takeFirst().toMap();
|
||||
QCOMPARE(param.value("name").toString(), QString("three"));
|
||||
QCOMPARE(param.value("type").toString(), QString("arr"));
|
||||
|
||||
param = params.takeFirst().toMap();
|
||||
QCOMPARE(param.value("name").toString(), QString("four"));
|
||||
QCOMPARE(param.value("type").toString(), QString("obj"));
|
||||
|
||||
// functionFour
|
||||
QCOMPARE(functionFour.value("name").toString(), QString("functionFour"));
|
||||
QCOMPARE(functionFour.value("return").toString(), QString("nil"));
|
||||
|
||||
params = functionFour.value("params").toList();
|
||||
QCOMPARE(params.count(), 2);
|
||||
|
||||
param = params.takeFirst().toMap();
|
||||
QCOMPARE(param.value("name").toString(), QString("foo"));
|
||||
QCOMPARE(param.value("type").toString(), QString("str"));
|
||||
|
||||
param = params.takeFirst().toMap();
|
||||
QCOMPARE(param.value("name").toString(), QString("bar"));
|
||||
QCOMPARE(param.value("type").toString(), QString("str"));
|
||||
}
|
||||
private:
|
||||
JsonQt::JsonRpc* m_rpc;
|
||||
JsonQt::JsonRpcAdaptor* m_adaptor;
|
||||
TestObject* m_testObject;
|
||||
};
|
||||
|
||||
QTEST_MAIN(JsonRpcAdaptor);
|
||||
|
||||
#include "moc_JsonRpcAdaptor.cxx"
|
||||
46
third-party/JsonQt/tests/JsonToProperties.cpp
vendored
Normal file
46
third-party/JsonQt/tests/JsonToProperties.cpp
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "JsonToProperties.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
// This test assumes that JsonToVariant works correctly.
|
||||
class JsonToProperties : public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
JsonQt::JsonToProperties::parse(
|
||||
"{"
|
||||
"\"objectName\": \"My JSON Properties Test Object\","
|
||||
"\"END\" : [\"OF\", \"TEST\"]"
|
||||
"}",
|
||||
this
|
||||
);
|
||||
}
|
||||
void testObjectName()
|
||||
{
|
||||
QCOMPARE(
|
||||
this->objectName(),
|
||||
QString("My JSON Properties Test Object")
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(JsonToProperties);
|
||||
|
||||
#include "moc_JsonToProperties.cxx"
|
||||
166
third-party/JsonQt/tests/JsonToVariant.cpp
vendored
Normal file
166
third-party/JsonQt/tests/JsonToVariant.cpp
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/* LICENSE NOTICE
|
||||
Copyright (c) 2008, Frederick Emmott <mail@fredemmott.co.uk>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
#include "JsonToVariant.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class JsonToVariant : public QObject
|
||||
{
|
||||
Q_OBJECT;
|
||||
private slots:
|
||||
void initTestCase()
|
||||
{
|
||||
// Variable use of whitespace intentional
|
||||
QVariant data = JsonQt::JsonToVariant::parse(
|
||||
"{"
|
||||
"\"MyString\": \"foo\","
|
||||
"\"MyInt\" :123 ,"
|
||||
"\"MyBigNum\" : 42e10 , "
|
||||
"\"MyLongNum\" : 8589934592,"
|
||||
"\"MyFraction\" : 2.718,"
|
||||
"\"MyArray\" : [1, \"2\", {\"3\": 4}],"
|
||||
"\"MyObject\" : {\"a\" : 1, \"b\" : 2 },"
|
||||
"\"MyEmptyObject\" : { },"
|
||||
"\"MyBool\": true,"
|
||||
"\"END\" : [\"OF\", \"TEST\"]"
|
||||
"}"
|
||||
);
|
||||
QCOMPARE(data.type(), QVariant::Map);
|
||||
m_parsed = data.toMap();
|
||||
}
|
||||
|
||||
void testStringWithEscapedForwardSlash()
|
||||
{
|
||||
QVariant data = JsonQt::JsonToVariant::parse("\"\\/\"");
|
||||
QCOMPARE(data.type(), QVariant::String);
|
||||
QCOMPARE(data.toString(), QString("/"));
|
||||
}
|
||||
|
||||
void testMulti()
|
||||
{
|
||||
QList<QVariantMap> parsed = JsonQt::JsonToVariant::multiParse(
|
||||
"{"
|
||||
"\"foo\": \"bar\""
|
||||
"}"
|
||||
"{"
|
||||
"\"x\": \"y\""
|
||||
"}"
|
||||
);
|
||||
QCOMPARE(parsed.count(), 2);
|
||||
QCOMPARE(parsed.at(0).value("foo"), QVariant("bar"));
|
||||
QCOMPARE(parsed.at(1).value("x"), QVariant("y"));
|
||||
}
|
||||
|
||||
void testEmpty()
|
||||
{
|
||||
bool thrown = false;
|
||||
try
|
||||
{
|
||||
JsonQt::JsonToVariant::parse("");
|
||||
}
|
||||
catch(JsonQt::ParseException e)
|
||||
{
|
||||
thrown = true;
|
||||
}
|
||||
QVERIFY(thrown);
|
||||
}
|
||||
|
||||
void testString()
|
||||
{
|
||||
QVariant data = m_parsed["MyString"];
|
||||
QCOMPARE(data.type(), QVariant::String);
|
||||
QCOMPARE(data.toString(), QString("foo"));
|
||||
QCOMPARE(data, JsonQt::JsonToVariant::parse("\"foo\""));
|
||||
}
|
||||
|
||||
void testInt()
|
||||
{
|
||||
QVariant data = m_parsed["MyInt"];
|
||||
QCOMPARE(data.type(), QVariant::Int);
|
||||
QCOMPARE(data.toInt(), 123);
|
||||
QCOMPARE(data, JsonQt::JsonToVariant::parse("123"));
|
||||
}
|
||||
|
||||
void testBigNum()
|
||||
{
|
||||
QVariant data = m_parsed["MyBigNum"];
|
||||
QCOMPARE(data.type(), QVariant::Double);
|
||||
QCOMPARE(data.toDouble(), 42e10);
|
||||
QCOMPARE(data, JsonQt::JsonToVariant::parse("42e10"));
|
||||
}
|
||||
|
||||
void testLongNum()
|
||||
{
|
||||
QVariant data = m_parsed["MyLongNum"];
|
||||
QCOMPARE(data.type(), QVariant::LongLong);
|
||||
QCOMPARE(data.value<qint64>(), Q_INT64_C(8589934592));
|
||||
QCOMPARE(data, JsonQt::JsonToVariant::parse("8589934592"));
|
||||
}
|
||||
|
||||
void testFraction()
|
||||
{
|
||||
QVariant data = m_parsed["MyFraction"];
|
||||
QCOMPARE(data.type(), QVariant::Double);
|
||||
QCOMPARE(data.toDouble(), double(2.718));
|
||||
QCOMPARE(data, JsonQt::JsonToVariant::parse("2.718"));
|
||||
}
|
||||
|
||||
void testArray()
|
||||
{
|
||||
QVariant root = m_parsed["MyArray"];
|
||||
QCOMPARE(root.type(), QVariant::List);
|
||||
|
||||
QVariantList rootData = root.toList();
|
||||
QCOMPARE(rootData[0].type(), QVariant::Int);
|
||||
QCOMPARE(rootData[0].toInt(), 1);
|
||||
QCOMPARE(rootData[1].type(), QVariant::String);
|
||||
QCOMPARE(rootData[1].toString(), QString("2"));
|
||||
|
||||
QCOMPARE(rootData[2].type(), QVariant::Map);
|
||||
QVariantMap childData = rootData[2].toMap();
|
||||
QCOMPARE(childData["3"].type(), QVariant::Int);
|
||||
QCOMPARE(childData["3"].toInt(), 4);
|
||||
|
||||
QCOMPARE(root, JsonQt::JsonToVariant::parse("[1, \"2\", {\"3\": 4}]"));
|
||||
}
|
||||
|
||||
void testObject()
|
||||
{
|
||||
QVariant root = m_parsed["MyObject"];
|
||||
QCOMPARE(root.type(), QVariant::Map);
|
||||
|
||||
QVariantMap rootData = root.toMap();
|
||||
|
||||
QCOMPARE(rootData["a"].toInt(), 1);
|
||||
QCOMPARE(rootData["b"].toInt(), 2);
|
||||
|
||||
QCOMPARE(root, JsonQt::JsonToVariant::parse("{\"a\" : 1, \"b\" : 2 }"));
|
||||
}
|
||||
|
||||
void testEmptyObject()
|
||||
{
|
||||
QVariant root = m_parsed["MyEmptyObject"];
|
||||
QCOMPARE(root.type(), QVariant::Map);
|
||||
QCOMPARE(root.value<QVariantMap>().size(), 0);
|
||||
QCOMPARE(root, JsonQt::JsonToVariant::parse("{}"));
|
||||
}
|
||||
private:
|
||||
QVariantMap m_parsed;
|
||||
};
|
||||
|
||||
QTEST_MAIN(JsonToVariant);
|
||||
|
||||
#include "moc_JsonToVariant.cxx"
|
||||
46
third-party/JsonQt/tests/VariantToJson.cpp
vendored
Normal file
46
third-party/JsonQt/tests/VariantToJson.cpp
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#include "VariantToJson.h"
|
||||
#include "JsonToVariant.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
class VariantToJson : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void testFlat()
|
||||
{
|
||||
QVariantMap map;
|
||||
map["string_foo"] = "foo";
|
||||
map["bool_true"] = true;
|
||||
map["int_42"] = 42;
|
||||
map["double_pi"] = 3.14159;
|
||||
|
||||
QString json(JsonQt::VariantToJson::parse(map));
|
||||
QCOMPARE(map, JsonQt::JsonToVariant::parse(json).toMap());
|
||||
}
|
||||
void testComplex()
|
||||
{
|
||||
QVariantMap map;
|
||||
map["string_foo"] = "foo";
|
||||
map["bool_true"] = true;
|
||||
map["int_42"] = 42;
|
||||
map["double_pi"] = 3.14159;
|
||||
map["recurse"] = map;
|
||||
QVariantList list;
|
||||
list.append("zero");
|
||||
list.append("one");
|
||||
map["list"] = list;
|
||||
|
||||
QStringList list2;
|
||||
for(int i = 0; i < 25; i++)
|
||||
list2.append(QString("element").append(QString::number(i)));
|
||||
map["list2"] = list2;
|
||||
|
||||
QString json(JsonQt::VariantToJson::parse(map));
|
||||
QCOMPARE(map, JsonQt::JsonToVariant::parse(json).toMap());
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(VariantToJson);
|
||||
|
||||
#include "moc_VariantToJson.cxx"
|
||||
Reference in a new issue