diff --git a/.gitignore b/.gitignore
index 189b414f..ca5bcc52 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,9 @@
/build
/CMakeLists.txt.user
+/.idea
+/CMakeFiles
+/src/3rdparty
+/cmake-build-debug
+CMakeCache.txt
+cmake_install.cmake
+Makefile
diff --git a/CHANGELOG.md b/CHANGELOG.md
index eee4cf70..aa1f8cf2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,15 @@
+# v2.4.1
+ - [#147](https://github.com/xmrig/xmrig/issues/147) Fixed comparability with monero-stratum.
+
+# v2.4.0
+ - Added [HTTP API](https://github.com/xmrig/xmrig/wiki/API).
+ - Added comments support in config file.
+ - libjansson replaced to rapidjson.
+ - [#98](https://github.com/xmrig/xmrig/issues/98) Ignore `keepalive` option with minergate.com and nicehash.com.
+ - [#101](https://github.com/xmrig/xmrig/issues/101) Fixed MSVC 2017 (15.3) compile time version detection.
+ - [#108](https://github.com/xmrig/xmrig/issues/108) Silently ignore invalid values for `donate-level` option.
+ - [#111](https://github.com/xmrig/xmrig/issues/111) Fixed build without AEON support.
+
# v2.3.1
- [#68](https://github.com/xmrig/xmrig/issues/68) Fixed compatibility with Docker containers, was nothing print on console.
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 021ffc30..7a1556d5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,41 +1,37 @@
cmake_minimum_required(VERSION 3.0)
project(xmrig)
-option(WITH_LIBCPUID "Use Libcpuid" ON)
-option(WITH_AEON "CryptoNight-Lite support" ON)
+set(CMAKE_BUILD_TYPE Debug)
+option(WITH_LIBCPUID "Use Libcpuid" ON)
+option(WITH_AEON "CryptoNight-Lite support" ON)
+option(WITH_HTTPD "HTTP REST API" OFF)
+option(WITH_CC "CC Server" ON)
include (CheckIncludeFile)
set(HEADERS
src/3rdparty/align.h
+ src/api/Api.h
+ src/api/ApiState.h
+ src/api/NetworkState.h
src/App.h
- src/Console.h
- src/Cpu.h
src/interfaces/IClientListener.h
- src/interfaces/IConsoleListener.h
src/interfaces/IJobResultListener.h
src/interfaces/ILogBackend.h
src/interfaces/IStrategy.h
src/interfaces/IStrategyListener.h
src/interfaces/IWorker.h
- src/log/ConsoleLog.h
- src/log/FileLog.h
- src/log/Log.h
- src/Mem.h
src/net/Client.h
src/net/Job.h
+ src/net/JobId.h
src/net/JobResult.h
src/net/Network.h
src/net/strategies/DonateStrategy.h
src/net/strategies/FailoverStrategy.h
src/net/strategies/SinglePoolStrategy.h
src/net/SubmitResult.h
- src/net/Url.h
- src/Options.h
- src/Platform.h
- src/Summary.h
src/version.h
src/workers/DoubleWorker.h
src/workers/Handle.h
@@ -60,21 +56,17 @@ set(HEADERS_CRYPTO
)
set(SOURCES
+ src/api/Api.cpp
+ src/api/ApiState.cpp
+ src/api/NetworkState.cpp
src/App.cpp
- src/Console.cpp
- src/log/ConsoleLog.cpp
- src/log/FileLog.cpp
- src/log/Log.cpp
- src/Mem.cpp
src/net/Client.cpp
src/net/Job.cpp
src/net/Network.cpp
src/net/strategies/DonateStrategy.cpp
src/net/strategies/FailoverStrategy.cpp
src/net/strategies/SinglePoolStrategy.cpp
- src/net/Url.cpp
- src/Options.cpp
- src/Platform.cpp
+ src/net/SubmitResult.cpp
src/Summary.cpp
src/workers/DoubleWorker.cpp
src/workers/Handle.cpp
@@ -96,6 +88,31 @@ set(SOURCES_CRYPTO
src/crypto/CryptoNight.cpp
)
+set(HEADERS_COMMON
+ src/interfaces/IConsoleListener.h
+ src/Console.h
+ src/Mem.h
+ src/Cpu.h
+ src/net/Url.h
+ src/Options.h
+ src/log/ConsoleLog.h
+ src/log/FileLog.h
+ src/log/Log.h
+ src/Platform.h
+ src/Summary.h
+)
+
+set(SOURCES_COMMON
+ src/Console.cpp
+ src/Mem.cpp
+ src/net/Url.cpp
+ src/Options.cpp
+ src/log/ConsoleLog.cpp
+ src/log/FileLog.cpp
+ src/log/Log.cpp
+ src/Platform.cpp
+ )
+
if (WIN32)
set(SOURCES_OS
res/app.rc
@@ -125,8 +142,13 @@ else()
set(EXTRA_LIBS pthread)
endif()
+if (CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
+ set(EXTRA_LIBS ${EXTRA_LIBS} kvm)
+endif()
+
add_definitions(/D__STDC_FORMAT_MACROS)
add_definitions(/DUNICODE)
+add_definitions(/DRAPIDJSON_SSE2)
#add_definitions(/DAPP_DEBUG)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
@@ -138,13 +160,18 @@ if ("${CMAKE_BUILD_TYPE}" STREQUAL "")
endif()
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_CXX_EXTENSIONS OFF)
+set(CMAKE_CXX_STANDARD 11)
+
+
# https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_ID.html
if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall -Wno-strict-aliasing")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -s -funroll-loops -fvariable-expansion-in-unroller -ftree-loop-if-convert-stores -fmerge-all-constants -fbranch-target-load-optimize2")
if (WIN32)
@@ -155,6 +182,10 @@ if (CMAKE_CXX_COMPILER_ID MATCHES GNU)
add_definitions(/D_GNU_SOURCE)
+ if (${CMAKE_VERSION} VERSION_LESS "3.1.0")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ endif()
+
#set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -gdwarf-2")
elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
@@ -163,13 +194,14 @@ elseif (CMAKE_CXX_COMPILER_ID MATCHES MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox /Ot /Oi /MT /GL")
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
add_definitions(/D_CRT_NONSTDC_NO_WARNINGS)
+ add_definitions(/DNOMINMAX)
elseif (CMAKE_CXX_COMPILER_ID MATCHES Clang)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maes -Wall")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -std=c++14 -fno-exceptions -fno-rtti")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maes -Wall -fno-exceptions -fno-rtti -Wno-missing-braces")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast -funroll-loops -fmerge-all-constants")
endif()
@@ -191,12 +223,82 @@ if (HAVE_SYSLOG_H)
set(SOURCES_SYSLOG src/log/SysLog.h src/log/SysLog.cpp)
endif()
+if (NOT WITH_AEON)
+ add_definitions(/DXMRIG_NO_AEON)
+endif()
+
+if (WITH_HTTPD)
+ find_package(MHD)
+
+ if (MHD_FOUND)
+ include_directories(${MHD_INCLUDE_DIRS})
+ set(HTTPD_SOURCES src/api/Httpd.h src/api/Httpd.cpp)
+ else()
+ message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_HTTPD=OFF` to build without http deamon support")
+ endif()
+else()
+ add_definitions(/DXMRIG_NO_HTTPD)
+ add_definitions(/DXMRIG_NO_API)
+endif()
+
+if (WITH_CC)
+ find_package(MHD)
+
+ if (MHD_FOUND)
+ include_directories(${MHD_INCLUDE_DIRS})
+ else()
+ message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_CC=OFF` to build without CC Server support")
+ endif()
+
+ find_package(CURL)
+
+ if (CURL_FOUND)
+ include_directories(${CURL_INCLUDE_DIRS})
+ else()
+ message(FATAL_ERROR "microhttpd NOT found: use `-DWITH_CC=OFF` to build without CC Server support")
+ endif()
+
+ set(HEADERS_CC_COMMON
+ src/cc/ControlCommand.h
+ src/cc/ClientStatus.h)
+
+ set(SOURCES_CC_COMMON
+ src/cc/ControlCommand.cpp
+ src/cc/ClientStatus.cpp)
+
+ set(HEADERS_CC_CLIENT
+ src/cc/CCClient.h)
+
+ set(SOURCES_CC_CLIENT
+ src/cc/CCClient.cpp)
+
+ set(HEADERS_CC_SERVER
+ src/cc/CCServer.h
+ src/cc/Service.h
+ src/cc/Httpd.h)
+
+ set(SOURCES_CC_SERVER
+ src/cc/CCServer.cpp
+ src/cc/Service.cpp
+ src/cc/Summary.cpp
+ src/cc/Httpd.cpp
+ src/xmrigCC.cpp
+ )
+else()
+ add_definitions(/DXMRIG_NO_CC)
+endif()
+
include_directories(src)
include_directories(src/3rdparty)
-include_directories(src/3rdparty/jansson)
include_directories(${UV_INCLUDE_DIR})
-add_subdirectory(src/3rdparty/jansson)
+add_executable(xmrigMiner ${HEADERS} ${SOURCES} ${HEADERS_COMMON} ${SOURCES_COMMON} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG} ${HTTPD_SOURCES} ${SOURCES_CC_COMMON} ${HEADERS_CC_COMMON} ${SOURCES_CC_CLIENT} ${HEADERS_CC_CLIENT})
+target_link_libraries(xmrigMiner ${UV_LIBRARIES} ${MHD_LIBRARY} ${CURL_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
-add_executable(xmrig ${HEADERS} ${SOURCES} ${SOURCES_OS} ${SOURCES_CPUID} ${HEADERS_CRYPTO} ${SOURCES_CRYPTO} ${SOURCES_SYSLOG})
-target_link_libraries(xmrig jansson ${UV_LIBRARIES} ${EXTRA_LIBS} ${CPUID_LIB})
+add_executable(xmrigDaemon src/xmrigd.cpp)
+
+if (WITH_CC AND MHD_FOUND AND CURL_FOUND)
+ add_executable(xmrigCCServer ${HEADERS_COMMON} ${SOURCES_COMMON} ${SOURCES_OS} ${SOURCES_CPUID} ${SOURCES_SYSLOG} ${SOURCES_CC_COMMON} ${HEADERS_CC_COMMON} ${SOURCES_CC_SERVER} ${HEADERS_CC_SERVER})
+ target_link_libraries(xmrigCCServer ${UV_LIBRARIES} ${MHD_LIBRARY} ${EXTRA_LIBS} ${CPUID_LIB})
+ set_target_properties(xmrigCCServer PROPERTIES COMPILE_FLAGS "-DXMRIG_CC_SERVER ${SHARED_FLAGS}")
+endif()
\ No newline at end of file
diff --git a/README.md b/README.md
index e6648bc5..3a34f14f 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,16 @@
-# XMRig
-XMRig is high performance Monero (XMR) CPU miner, with the official full Windows support.
+# XMRigCC
+
+[Build instructions / Notes / Howto](https://raw.githubusercontent.com/Bendr0id/xmrigCC/feature_cc/howto_and_notes.txt)
+
+Documentation will be added here soon.
+
+##### About
+
+XMRig is high performance Monero (XMR) / Aeon CPU miner, with the official full Windows support.
Originally based on cpuminer-multi with heavy optimizations/rewrites and removing a lot of legacy code, since version 1.0.0 complete rewritten from scratch on C++.
* This is the CPU-mining version, there is also a [NVIDIA GPU version](https://github.com/xmrig/xmrig-nvidia).
+* [Roadmap](https://github.com/xmrig/xmrig/issues/106) for next releases.
@@ -17,7 +25,17 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
* [Donations](#donations)
* [Contacts](#contacts)
-## Features
+## Additional features of xmrigCC
+* Command and control server
+* CC Dashboard with:
+ * statistics
+ * remote control (start/stop/restart/shutdown) miner
+ * remote configuration changes of miner
+* Added daemon to restart miner
+
+\+ All features of the latest xmrig
+
+## Features of xmrig
* High performance.
* Official Windows support.
* Small Windows executable, without dependencies.
@@ -31,9 +49,9 @@ Originally based on cpuminer-multi with heavy optimizations/rewrites and removin
* It's open source software.
## Download
-* Binary releases: https://github.com/xmrig/xmrig/releases
-* Git tree: https://github.com/xmrig/xmrig.git
- * Clone with `git clone https://github.com/xmrig/xmrig.git` :hammer: [Build instructions](https://github.com/xmrig/xmrig/wiki/Build).
+* Binary releases: soon
+* Git tree: https://github.com/Bendr0id/xmrigCC.git
+ * Clone with `git clone https://github.com/Bendr0id/xmrigCC.git` :hammer: [Build instructions / Notes / Howto](https://raw.githubusercontent.com/Bendr0id/xmrigCC/feature_cc/howto_and_notes.txt).
## Usage
### Basic example
@@ -93,7 +111,6 @@ Since version 0.8.0.
## Other information
* No HTTP support, only stratum protocol support.
* No TLS support.
-* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
### CPU mining performance
@@ -105,14 +122,27 @@ Please note performance is highly dependent on system load. The numbers above ar
### Maximum performance checklist
* Idle operating system.
* Do not exceed optimal thread count.
-* Use modern CPUs with AES-NI instructuon set.
+* Use modern CPUs with AES-NI instruction set.
* Try setup optimal cpu affinity.
* Enable fast memory (Large/Huge pages).
## Donations
-* XMR: `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
-* BTC: `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
+* Default donation 5% (5 minutes in 100 minutes) can be reduced to 1% via command line option `--donate-level`.
+* The donations will be automatically splitted (50/50) on my pool between xmrig and me.
-## Contacts
+##### BenDroid (xmrigCC):
+* XMR `46FkYo7x6LqYjLQo4Jd84UTGBybW7tsWqJaQVLPhbUSK19ajSTMY9T2Sa2LH6CfWhSingjvQARtfeM4Feekpp2yFR1wsFNT`
+* AEON `Wmtm4S2cQ8uEBBAVjvbiaVAPv2d6gA1mAUmBmjna4VF7VixLxLRUYag5cvsym3WnuzdJ9zvhQ3Xwa8gWxPDPRfcQ3AUkYra3W`
+* BTC `128qLZCaGdoWhBTfaS7rytpbvG4mNTyAQm`
+
+##### xmrig:
+* XMR `48edfHu7V9Z84YzzMa6fUueoELZ9ZRXq9VetWzYGzKt52XU5xvqgzYnDK9URnRoJMk1j8nLwEVsaSWJ4fhdUyZijBGUicoD`
+* BTC `1P7ujsXeX7GxQwHNnJsRMgAdNkFZmNVqJT`
+
+## Contacts xmrigCC
+* ben [at] graef.in
+* [reddit](https://www.reddit.com/user/BenDr0id/)
+
+## Contacts xmrig
* support@xmrig.com
* [reddit](https://www.reddit.com/user/XMRig/)
diff --git a/cmake/FindMHD.cmake b/cmake/FindMHD.cmake
new file mode 100644
index 00000000..f6665892
--- /dev/null
+++ b/cmake/FindMHD.cmake
@@ -0,0 +1,39 @@
+# - Try to find MHD
+# Once done this will define
+#
+# MHD_FOUND - system has MHD
+# MHD_INCLUDE_DIRS - the MHD include directory
+# MHD_LIBRARY - Link these to use MHD
+
+find_path(
+ MHD_INCLUDE_DIR
+ NAMES microhttpd.h
+ DOC "microhttpd include dir"
+)
+
+find_library(
+ MHD_LIBRARY
+ NAMES microhttpd microhttpd-10 libmicrohttpd libmicrohttpd-dll
+ DOC "microhttpd library"
+)
+
+set(MHD_INCLUDE_DIRS ${MHD_INCLUDE_DIR})
+set(MHD_LIBRARIES ${MHD_LIBRARY})
+
+# debug library on windows
+# same naming convention as in qt (appending debug library with d)
+# boost is using the same "hack" as us with "optimized" and "debug"
+# official MHD project actually uses _d suffix
+if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL MSVC)
+ find_library(
+ MHD_LIBRARY_DEBUG
+ NAMES microhttpd_d microhttpd-10_d libmicrohttpd_d libmicrohttpd-dll_d
+ DOC "mhd debug library"
+ )
+ set(MHD_LIBRARIES optimized ${MHD_LIBRARIES} debug ${MHD_LIBRARY_DEBUG})
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(mhd DEFAULT_MSG MHD_INCLUDE_DIR MHD_LIBRARY)
+mark_as_advanced(MHD_INCLUDE_DIR MHD_LIBRARY)
+
diff --git a/howto_and_notes.txt b/howto_and_notes.txt
new file mode 100644
index 00000000..3ef1d8ef
--- /dev/null
+++ b/howto_and_notes.txt
@@ -0,0 +1,161 @@
+installation:
+
+sudo apt-get install git build-essential cmake libuv1-dev libmicrohttpd-dev libcurl4-gnutls-dev
+
+(or any other libcurl)
+
+git clone https://github.com/Bendr0id/xmrigCC.git
+cd xmrigCC
+mkdir build
+cd build
+cmake ..
+make
+
+
+config cc server:
+
+ sample is in src folder (config_cc.json):
+
+{
+ "background": false, // true to run the cc-server in the background (no console)
+ "colors": true, // false to disable colored output
+ "log-file": null, // log all output to a file
+ "syslog": false, // use system log for output messages
+ "cc-server": {
+ "port": 3344, // port the CC Server will listens on
+ "access-token": null, // access token for CC Clients (should be set!!!)
+ "user": "admin", // admin user for access CC Dashboard
+ "pass": "pass", // admin pass for access CC Dashboard
+ "client-config-folder" : null, // folder which contains the client-config files (null=current)
+ "custom-dashboard" : "index.html" // dashboard html file
+ }
+}
+
+
+config cc client (miner):
+
+ sample is in src folder (config.json):
+
+{
+ "algo": "cryptonight-light",
+ "av": 0,
+ "background": false,
+ "colors": true,
+ "cpu-affinity": null,
+ "cpu-priority": null,
+ "donate-level": 0,
+ "log-file": null,
+ "max-cpu-usage": 75,
+ "print-time": 60,
+ "retries": 5,
+ "retry-pause": 5,
+ "safe": false,
+ "syslog": false,
+ "threads": null,
+ "pools": [
+ {
+ "url": "pool.aeonmining.pro:3333", // your pool here
+ "user": "Wmtm4S2cQ8uEBBAVjvbiaVAPv2d6gA1mAUmBmjna4VF7VixLxLRUYag5cvsym3WnuzdJ9zvhQ3Xwa8gWxPDPRfcQ3AUkYra3W", // your wallet here
+ "pass": "donate",
+ "keepalive": true,
+ "nicehash": false
+ }
+ ],
+ "api": {
+ "port": 3339, // port for the miner API https://github.com/xmrig/xmrig/wiki/API
+ "access-token": null, // access token for API
+ "worker-id": null // custom worker-id for API
+ },
+ "cc-client": {
+ "url": "localhost:3344", // url of the CC Server (ip:port)
+ "access-token": null, // access token for CC Server (has to be the same in config_cc.json)
+ "worker-id": null // custom worker-id for CC Server (otherwise hostname is used)
+ }
+}
+
+
+config to deploy / notes:
+
+ sample is in src folder (default_config.json) -> currently the same then the miner config.
+
+ miner specific config files have to be stored within the defined folder (defined in config_cc.json), or the root folder of the xmrigCCServer.
+
+ the client specific config filename has to be in the format "hostname_config.json" or if alternative worker-id is defined "myworkername_config.json".
+ if you dont provide a client specific config, the default_config.json is transfered to the client(miner) if you trigger the "update" action. the client will be automatically restarted, when the config is applied.
+
+running:
+ to start the cc server just start xmrigCCServer.
+ on the client execute xmrigDaemond (don't run the xmrigMiner it will not start). xmrigDaemon (miner) and xmrigCCServer can be runned on the same machine. xmrigDaemon will automatically connect every 10s to the xmrigCCServer and publish its results and will check for an outstanding command, which will be immediately executed.
+
+
+xmrigCCServer:
+
+ the dashboard is available via http://ip:port (the port is defined within config_cc.json, per default the port is bound to any available device [0.0.0.0]). You have to login with user/pass (defined in config_cc.json)
+
+ all the webservices return 200 OK as result code, or when there is an error, the specific result code.
+
+ available rest webservices:
+
+
+ (GET):
+
+ http://ip:port/getClientStatusList
+
+ request:
+
+ curl -H "Content-Type: application/json" -X GET http://admin:pass@127.0.0.1:3344/admin/getClientStatusList
+
+ response:
+
+ {"client_status_list":[{"client_status":{"client_id":"TestClient","current_pool":"","current_status":"RUNNING","hashrate_short":0.0,"hashrate_medium":0.0,"hashrate_long":0.0,"hashrate_highest":0.0,"avg_time":0,"shares_good":0,"shares_total":0,"hashes_total":0,"last_status_update":1508526287}}]}
+
+
+
+ http://ip:port/admin/getClientCommand?clientId=theMinerId (or the hostname, depends on your config) -> return the current command which
+ is set for the client (miner)
+
+ request:
+
+ curl -H "Content-Type: application/json" -X GET http://admin:pass@127.0.0.1:3344/admin/getClientCommand?clientId=TestClient
+
+ response: (command can be: START/STOP/RESTART/UPDATE_CONFIG/SHUTDOWN)
+
+ {"control_command":{"command":"START"}}
+
+
+
+ http://ip:port/admin/getClientConfig?clientId=theMinerId (or the hostname, depends on your config) -> returns the current config which is set for the client (miner) or if there is none, the default_config.json.
+
+ request:
+
+ curl -H "Content-Type: application/json" -X GET http://admin:pass@127.0.0.1:3344/admin/getClientConfig?clientId=TestClient
+
+ response:
+
+ a client config in json format
+
+
+
+ (POST)
+
+ http://ip:port/admin/setClientCommand?clientId=theMinerId (or the hostname, depends on your config) -> set the command for the client (miner) which has to be executed on the client.
+
+ request: (command can be: START/STOP/RESTART/UPDATE_CONFIG/SHUTDOWN)
+
+ curl -H "Content-Type: application/json" -X POST -d '{"control_command":{"command":"QUIT"}}' http://admin:pass@127.0.0.1:3344/admin/setClientCommand?clientId=TestClient
+
+ response:
+
+ OK (200)
+
+
+
+ http://ip:port/admin/setClientConfig?clientId=theMinerId (or the hostname, depends on your config) -> set the config for the client (miner) which has to be executed on the client.
+
+ request:
+
+ curl -H "Content-Type: application/json" -X POST -d 'put device config json here' http://admin:pass@127.0.0.1:3344/admin/setClientConfig?clientId=TestClient
+
+ response:
+
+ OK (200)
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 00000000..a666bb2b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,117 @@
+
+
+
+
+XMRigCC Dashboard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
XMRigCC Dashboard
+
+
+
+
+
+ Client Id
+ Pool
+ Status
+
+ Hashrate
+ Hashrate 5m
+ Hashrate 60m
+
+ Hashrate Highest
+ Hashes Total
+ Avg. Time
+
+ Shares Good
+ Shares Total
+ Last Update
+ Action
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/3rdparty/jansson/CMakeLists.txt b/src/3rdparty/jansson/CMakeLists.txt
deleted file mode 100644
index 7bd74c67..00000000
--- a/src/3rdparty/jansson/CMakeLists.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-cmake_minimum_required (VERSION 2.8)
-project (jansson C)
-
-add_definitions(-DHAVE_CONFIG_H)
-
-# Add the lib sources.
-file(GLOB JANSSON_SRC *.c)
-
-set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Os")
-
-set(JANSSON_HDR_PRIVATE
- ${CMAKE_CURRENT_SOURCE_DIR}/hashtable.h
- ${CMAKE_CURRENT_SOURCE_DIR}/jansson_private.h
- ${CMAKE_CURRENT_SOURCE_DIR}/strbuffer.h
- ${CMAKE_CURRENT_SOURCE_DIR}/utf.h
- ${CMAKE_CURRENT_SOURCE_DIR}/jansson_private_config.h)
-
-set(JANSSON_HDR_PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}/jansson_config.h
- ${CMAKE_CURRENT_SOURCE_DIR}/jansson.h)
-
-add_library(jansson STATIC
- ${JANSSON_SRC}
- ${JANSSON_HDR_PRIVATE}
- ${JANSSON_HDR_PUBLIC})
diff --git a/src/3rdparty/jansson/LICENSE b/src/3rdparty/jansson/LICENSE
deleted file mode 100644
index 8ae43e02..00000000
--- a/src/3rdparty/jansson/LICENSE
+++ /dev/null
@@ -1,19 +0,0 @@
-Copyright (c) 2009-2014 Petri Lehtinen
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
diff --git a/src/3rdparty/jansson/dump.c b/src/3rdparty/jansson/dump.c
deleted file mode 100644
index 0f8996e7..00000000
--- a/src/3rdparty/jansson/dump.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifdef _MSC_VER
-#pragma warning(disable:4090)
-#endif
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include "jansson_private.h"
-
-#include
-#include
-#include
-#include
-
-#if defined(HAVE_UNISTD_H)
-# include
-#elif defined(_MSC_VER)
-# include
-#endif
-
-#include "jansson.h"
-#include "strbuffer.h"
-#include "utf.h"
-
-#define MAX_INTEGER_STR_LENGTH 100
-#define MAX_REAL_STR_LENGTH 100
-
-#define FLAGS_TO_INDENT(f) ((f) & 0x1F)
-#define FLAGS_TO_PRECISION(f) (((f) >> 11) & 0x1F)
-
-struct buffer {
- const size_t size;
- size_t used;
- char *data;
-};
-
-static int dump_to_strbuffer(const char *buffer, size_t size, void *data)
-{
- return strbuffer_append_bytes((strbuffer_t *)data, buffer, size);
-}
-
-static int dump_to_buffer(const char *buffer, size_t size, void *data)
-{
- struct buffer *buf = (struct buffer *)data;
-
- if(buf->used + size <= buf->size)
- memcpy(&buf->data[buf->used], buffer, size);
-
- buf->used += size;
- return 0;
-}
-
-static int dump_to_file(const char *buffer, size_t size, void *data)
-{
- FILE *dest = (FILE *)data;
- if(fwrite(buffer, size, 1, dest) != 1)
- return -1;
- return 0;
-}
-
-static int dump_to_fd(const char *buffer, size_t size, void *data)
-{
- int *dest = (int *)data;
-# if defined(HAVE_UNISTD_H)
- if(write(*dest, buffer, size) == (ssize_t)size)
- return 0;
-# elif (defined(_MSC_VER))
- if (write(*dest, buffer, (unsigned int) size) == (int) size)
- return 0;
-# endif
- return -1;
-}
-
-/* 32 spaces (the maximum indentation size) */
-static const char whitespace[] = " ";
-
-static int dump_indent(size_t flags, int depth, int space, json_dump_callback_t dump, void *data)
-{
- if(FLAGS_TO_INDENT(flags) > 0)
- {
- unsigned int ws_count = FLAGS_TO_INDENT(flags), n_spaces = depth * ws_count;
-
- if(dump("\n", 1, data))
- return -1;
-
- while(n_spaces > 0)
- {
- int cur_n = n_spaces < sizeof whitespace - 1 ? n_spaces : sizeof whitespace - 1;
-
- if(dump(whitespace, cur_n, data))
- return -1;
-
- n_spaces -= cur_n;
- }
- }
- else if(space && !(flags & JSON_COMPACT))
- {
- return dump(" ", 1, data);
- }
- return 0;
-}
-
-static int dump_string(const char *str, size_t len, json_dump_callback_t dump, void *data, size_t flags)
-{
- const char *pos, *end, *lim;
- int32_t codepoint;
-
- if(dump("\"", 1, data))
- return -1;
-
- end = pos = str;
- lim = str + len;
- while(1)
- {
- const char *text;
- char seq[13];
- int length;
-
- while(end < lim)
- {
- end = utf8_iterate(pos, lim - pos, &codepoint);
- if(!end)
- return -1;
-
- /* mandatory escape or control char */
- if(codepoint == '\\' || codepoint == '"' || codepoint < 0x20)
- break;
-
- /* slash */
- if((flags & JSON_ESCAPE_SLASH) && codepoint == '/')
- break;
-
- /* non-ASCII */
- if((flags & JSON_ENSURE_ASCII) && codepoint > 0x7F)
- break;
-
- pos = end;
- }
-
- if(pos != str) {
- if(dump(str, pos - str, data))
- return -1;
- }
-
- if(end == pos)
- break;
-
- /* handle \, /, ", and control codes */
- length = 2;
- switch(codepoint)
- {
- case '\\': text = "\\\\"; break;
- case '\"': text = "\\\""; break;
- case '\b': text = "\\b"; break;
- case '\f': text = "\\f"; break;
- case '\n': text = "\\n"; break;
- case '\r': text = "\\r"; break;
- case '\t': text = "\\t"; break;
- case '/': text = "\\/"; break;
- default:
- {
- /* codepoint is in BMP */
- if(codepoint < 0x10000)
- {
- snprintf(seq, sizeof(seq), "\\u%04X", (unsigned int)codepoint);
- length = 6;
- }
-
- /* not in BMP -> construct a UTF-16 surrogate pair */
- else
- {
- int32_t first, last;
-
- codepoint -= 0x10000;
- first = 0xD800 | ((codepoint & 0xffc00) >> 10);
- last = 0xDC00 | (codepoint & 0x003ff);
-
- snprintf(seq, sizeof(seq), "\\u%04X\\u%04X", (unsigned int)first, (unsigned int)last);
- length = 12;
- }
-
- text = seq;
- break;
- }
- }
-
- if(dump(text, length, data))
- return -1;
-
- str = pos = end;
- }
-
- return dump("\"", 1, data);
-}
-
-static int compare_keys(const void *key1, const void *key2)
-{
- return strcmp(*(const char **)key1, *(const char **)key2);
-}
-
-static int do_dump(const json_t *json, size_t flags, int depth,
- json_dump_callback_t dump, void *data)
-{
- int embed = flags & JSON_EMBED;
-
- flags &= ~JSON_EMBED;
-
- if(!json)
- return -1;
-
- switch(json_typeof(json)) {
- case JSON_NULL:
- return dump("null", 4, data);
-
- case JSON_TRUE:
- return dump("true", 4, data);
-
- case JSON_FALSE:
- return dump("false", 5, data);
-
- case JSON_INTEGER:
- {
- char buffer[MAX_INTEGER_STR_LENGTH];
- int size;
-
- size = snprintf(buffer, MAX_INTEGER_STR_LENGTH,
- "%" JSON_INTEGER_FORMAT,
- json_integer_value(json));
- if(size < 0 || size >= MAX_INTEGER_STR_LENGTH)
- return -1;
-
- return dump(buffer, size, data);
- }
-
- case JSON_REAL:
- {
- char buffer[MAX_REAL_STR_LENGTH];
- int size;
- double value = json_real_value(json);
-
- size = jsonp_dtostr(buffer, MAX_REAL_STR_LENGTH, value,
- FLAGS_TO_PRECISION(flags));
- if(size < 0)
- return -1;
-
- return dump(buffer, size, data);
- }
-
- case JSON_STRING:
- return dump_string(json_string_value(json), json_string_length(json), dump, data, flags);
-
- case JSON_ARRAY:
- {
- size_t n;
- size_t i;
-
- json_array_t *array;
-
- /* detect circular references */
- array = json_to_array(json);
- if(array->visited)
- goto array_error;
- array->visited = 1;
-
- n = json_array_size(json);
-
- if(!embed && dump("[", 1, data))
- goto array_error;
- if(n == 0) {
- array->visited = 0;
- return embed ? 0 : dump("]", 1, data);
- }
- if(dump_indent(flags, depth + 1, 0, dump, data))
- goto array_error;
-
- for(i = 0; i < n; ++i) {
- if(do_dump(json_array_get(json, i), flags, depth + 1,
- dump, data))
- goto array_error;
-
- if(i < n - 1)
- {
- if(dump(",", 1, data) ||
- dump_indent(flags, depth + 1, 1, dump, data))
- goto array_error;
- }
- else
- {
- if(dump_indent(flags, depth, 0, dump, data))
- goto array_error;
- }
- }
-
- array->visited = 0;
- return embed ? 0 : dump("]", 1, data);
-
- array_error:
- array->visited = 0;
- return -1;
- }
-
- case JSON_OBJECT:
- {
- json_object_t *object;
- void *iter;
- const char *separator;
- int separator_length;
-
- if(flags & JSON_COMPACT) {
- separator = ":";
- separator_length = 1;
- }
- else {
- separator = ": ";
- separator_length = 2;
- }
-
- /* detect circular references */
- object = json_to_object(json);
- if(object->visited)
- goto object_error;
- object->visited = 1;
-
- iter = json_object_iter((json_t *)json);
-
- if(!embed && dump("{", 1, data))
- goto object_error;
- if(!iter) {
- object->visited = 0;
- return embed ? 0 : dump("}", 1, data);
- }
- if(dump_indent(flags, depth + 1, 0, dump, data))
- goto object_error;
-
- if(flags & JSON_SORT_KEYS)
- {
- const char **keys;
- size_t size, i;
-
- size = json_object_size(json);
- keys = jsonp_malloc(size * sizeof(const char *));
- if(!keys)
- goto object_error;
-
- i = 0;
- while(iter)
- {
- keys[i] = json_object_iter_key(iter);
- iter = json_object_iter_next((json_t *)json, iter);
- i++;
- }
- assert(i == size);
-
- qsort(keys, size, sizeof(const char *), compare_keys);
-
- for(i = 0; i < size; i++)
- {
- const char *key;
- json_t *value;
-
- key = keys[i];
- value = json_object_get(json, key);
- assert(value);
-
- dump_string(key, strlen(key), dump, data, flags);
- if(dump(separator, separator_length, data) ||
- do_dump(value, flags, depth + 1, dump, data))
- {
- jsonp_free(keys);
- goto object_error;
- }
-
- if(i < size - 1)
- {
- if(dump(",", 1, data) ||
- dump_indent(flags, depth + 1, 1, dump, data))
- {
- jsonp_free(keys);
- goto object_error;
- }
- }
- else
- {
- if(dump_indent(flags, depth, 0, dump, data))
- {
- jsonp_free(keys);
- goto object_error;
- }
- }
- }
-
- jsonp_free(keys);
- }
- else
- {
- /* Don't sort keys */
-
- while(iter)
- {
- void *next = json_object_iter_next((json_t *)json, iter);
- const char *key = json_object_iter_key(iter);
-
- dump_string(key, strlen(key), dump, data, flags);
- if(dump(separator, separator_length, data) ||
- do_dump(json_object_iter_value(iter), flags, depth + 1,
- dump, data))
- goto object_error;
-
- if(next)
- {
- if(dump(",", 1, data) ||
- dump_indent(flags, depth + 1, 1, dump, data))
- goto object_error;
- }
- else
- {
- if(dump_indent(flags, depth, 0, dump, data))
- goto object_error;
- }
-
- iter = next;
- }
- }
-
- object->visited = 0;
- return embed ? 0 : dump("}", 1, data);
-
- object_error:
- object->visited = 0;
- return -1;
- }
-
- default:
- /* not reached */
- return -1;
- }
-}
-
-char *json_dumps(const json_t *json, size_t flags)
-{
- strbuffer_t strbuff;
- char *result;
-
- if(strbuffer_init(&strbuff))
- return NULL;
-
- if(json_dump_callback(json, dump_to_strbuffer, (void *)&strbuff, flags))
- result = NULL;
- else
- result = jsonp_strdup(strbuffer_value(&strbuff));
-
- strbuffer_close(&strbuff);
- return result;
-}
-
-size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags)
-{
- struct buffer buf = { size, 0, buffer };
-
- if(json_dump_callback(json, dump_to_buffer, (void *)&buf, flags))
- return 0;
-
- return buf.used;
-}
-
-int json_dumpf(const json_t *json, FILE *output, size_t flags)
-{
- return json_dump_callback(json, dump_to_file, (void *)output, flags);
-}
-
-int json_dumpfd(const json_t *json, int output, size_t flags)
-{
- return json_dump_callback(json, dump_to_fd, (void *)&output, flags);
-}
-
-int json_dump_file(const json_t *json, const char *path, size_t flags)
-{
- int result;
-
- FILE *output = fopen(path, "w");
- if(!output)
- return -1;
-
- result = json_dumpf(json, output, flags);
-
- fclose(output);
- return result;
-}
-
-int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags)
-{
- if(!(flags & JSON_ENCODE_ANY)) {
- if(!json_is_array(json) && !json_is_object(json))
- return -1;
- }
-
- return do_dump(json, flags, 0, callback, data);
-}
diff --git a/src/3rdparty/jansson/error.c b/src/3rdparty/jansson/error.c
deleted file mode 100644
index 58c83790..00000000
--- a/src/3rdparty/jansson/error.c
+++ /dev/null
@@ -1,63 +0,0 @@
-#include
-#include "jansson_private.h"
-
-void jsonp_error_init(json_error_t *error, const char *source)
-{
- if(error)
- {
- error->text[0] = '\0';
- error->line = -1;
- error->column = -1;
- error->position = 0;
- if(source)
- jsonp_error_set_source(error, source);
- else
- error->source[0] = '\0';
- }
-}
-
-void jsonp_error_set_source(json_error_t *error, const char *source)
-{
- size_t length;
-
- if(!error || !source)
- return;
-
- length = strlen(source);
- if(length < JSON_ERROR_SOURCE_LENGTH)
- strncpy(error->source, source, length + 1);
- else {
- size_t extra = length - JSON_ERROR_SOURCE_LENGTH + 4;
- strncpy(error->source, "...", 3);
- strncpy(error->source + 3, source + extra, length - extra + 1);
- }
-}
-
-void jsonp_error_set(json_error_t *error, int line, int column,
- size_t position, const char *msg, ...)
-{
- va_list ap;
-
- va_start(ap, msg);
- jsonp_error_vset(error, line, column, position, msg, ap);
- va_end(ap);
-}
-
-void jsonp_error_vset(json_error_t *error, int line, int column,
- size_t position, const char *msg, va_list ap)
-{
- if(!error)
- return;
-
- if(error->text[0] != '\0') {
- /* error already set */
- return;
- }
-
- error->line = line;
- error->column = column;
- error->position = (int)position;
-
- vsnprintf(error->text, JSON_ERROR_TEXT_LENGTH, msg, ap);
- error->text[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
-}
diff --git a/src/3rdparty/jansson/hashtable.c b/src/3rdparty/jansson/hashtable.c
deleted file mode 100644
index dcc1687b..00000000
--- a/src/3rdparty/jansson/hashtable.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifdef _MSC_VER
-#pragma warning(disable:4334)
-#endif
-
-#if HAVE_CONFIG_H
-#include
-#endif
-
-#include
-#include
-
-#if HAVE_STDINT_H
-#include
-#endif
-
-#include /* for JSON_INLINE */
-#include "jansson_private.h" /* for container_of() */
-#include "hashtable.h"
-
-#ifndef INITIAL_HASHTABLE_ORDER
-#define INITIAL_HASHTABLE_ORDER 3
-#endif
-
-typedef struct hashtable_list list_t;
-typedef struct hashtable_pair pair_t;
-typedef struct hashtable_bucket bucket_t;
-
-extern volatile uint32_t hashtable_seed;
-
-/* Implementation of the hash function */
-#include "lookup3.h"
-
-#define list_to_pair(list_) container_of(list_, pair_t, list)
-#define ordered_list_to_pair(list_) container_of(list_, pair_t, ordered_list)
-#define hash_str(key) ((size_t)hashlittle((key), strlen(key), hashtable_seed))
-
-static JSON_INLINE void list_init(list_t *list)
-{
- list->next = list;
- list->prev = list;
-}
-
-static JSON_INLINE void list_insert(list_t *list, list_t *node)
-{
- node->next = list;
- node->prev = list->prev;
- list->prev->next = node;
- list->prev = node;
-}
-
-static JSON_INLINE void list_remove(list_t *list)
-{
- list->prev->next = list->next;
- list->next->prev = list->prev;
-}
-
-static JSON_INLINE int bucket_is_empty(hashtable_t *hashtable, bucket_t *bucket)
-{
- return bucket->first == &hashtable->list && bucket->first == bucket->last;
-}
-
-static void insert_to_bucket(hashtable_t *hashtable, bucket_t *bucket,
- list_t *list)
-{
- if(bucket_is_empty(hashtable, bucket))
- {
- list_insert(&hashtable->list, list);
- bucket->first = bucket->last = list;
- }
- else
- {
- list_insert(bucket->first, list);
- bucket->first = list;
- }
-}
-
-static pair_t *hashtable_find_pair(hashtable_t *hashtable, bucket_t *bucket,
- const char *key, size_t hash)
-{
- list_t *list;
- pair_t *pair;
-
- if(bucket_is_empty(hashtable, bucket))
- return NULL;
-
- list = bucket->first;
- while(1)
- {
- pair = list_to_pair(list);
- if(pair->hash == hash && strcmp(pair->key, key) == 0)
- return pair;
-
- if(list == bucket->last)
- break;
-
- list = list->next;
- }
-
- return NULL;
-}
-
-/* returns 0 on success, -1 if key was not found */
-static int hashtable_do_del(hashtable_t *hashtable,
- const char *key, size_t hash)
-{
- pair_t *pair;
- bucket_t *bucket;
- size_t index;
-
- index = hash & hashmask(hashtable->order);
- bucket = &hashtable->buckets[index];
-
- pair = hashtable_find_pair(hashtable, bucket, key, hash);
- if(!pair)
- return -1;
-
- if(&pair->list == bucket->first && &pair->list == bucket->last)
- bucket->first = bucket->last = &hashtable->list;
-
- else if(&pair->list == bucket->first)
- bucket->first = pair->list.next;
-
- else if(&pair->list == bucket->last)
- bucket->last = pair->list.prev;
-
- list_remove(&pair->list);
- list_remove(&pair->ordered_list);
- json_decref(pair->value);
-
- jsonp_free(pair);
- hashtable->size--;
-
- return 0;
-}
-
-static void hashtable_do_clear(hashtable_t *hashtable)
-{
- list_t *list, *next;
- pair_t *pair;
-
- for(list = hashtable->list.next; list != &hashtable->list; list = next)
- {
- next = list->next;
- pair = list_to_pair(list);
- json_decref(pair->value);
- jsonp_free(pair);
- }
-}
-
-static int hashtable_do_rehash(hashtable_t *hashtable)
-{
- list_t *list, *next;
- pair_t *pair;
- size_t i, index, new_size, new_order;
- struct hashtable_bucket *new_buckets;
-
- new_order = hashtable->order + 1;
- new_size = hashsize(new_order);
-
- new_buckets = jsonp_malloc(new_size * sizeof(bucket_t));
- if(!new_buckets)
- return -1;
-
- jsonp_free(hashtable->buckets);
- hashtable->buckets = new_buckets;
- hashtable->order = new_order;
-
- for(i = 0; i < hashsize(hashtable->order); i++)
- {
- hashtable->buckets[i].first = hashtable->buckets[i].last =
- &hashtable->list;
- }
-
- list = hashtable->list.next;
- list_init(&hashtable->list);
-
- for(; list != &hashtable->list; list = next) {
- next = list->next;
- pair = list_to_pair(list);
- index = pair->hash % new_size;
- insert_to_bucket(hashtable, &hashtable->buckets[index], &pair->list);
- }
-
- return 0;
-}
-
-
-int hashtable_init(hashtable_t *hashtable)
-{
- size_t i;
-
- hashtable->size = 0;
- hashtable->order = INITIAL_HASHTABLE_ORDER;
- hashtable->buckets = jsonp_malloc(hashsize(hashtable->order) * sizeof(bucket_t));
- if(!hashtable->buckets)
- return -1;
-
- list_init(&hashtable->list);
- list_init(&hashtable->ordered_list);
-
- for(i = 0; i < hashsize(hashtable->order); i++)
- {
- hashtable->buckets[i].first = hashtable->buckets[i].last =
- &hashtable->list;
- }
-
- return 0;
-}
-
-void hashtable_close(hashtable_t *hashtable)
-{
- hashtable_do_clear(hashtable);
- jsonp_free(hashtable->buckets);
-}
-
-int hashtable_set(hashtable_t *hashtable, const char *key, json_t *value)
-{
- pair_t *pair;
- bucket_t *bucket;
- size_t hash, index;
-
- /* rehash if the load ratio exceeds 1 */
- if(hashtable->size >= hashsize(hashtable->order))
- if(hashtable_do_rehash(hashtable))
- return -1;
-
- hash = hash_str(key);
- index = hash & hashmask(hashtable->order);
- bucket = &hashtable->buckets[index];
- pair = hashtable_find_pair(hashtable, bucket, key, hash);
-
- if(pair)
- {
- json_decref(pair->value);
- pair->value = value;
- }
- else
- {
- /* offsetof(...) returns the size of pair_t without the last,
- flexible member. This way, the correct amount is
- allocated. */
-
- size_t len = strlen(key);
- if(len >= (size_t)-1 - offsetof(pair_t, key)) {
- /* Avoid an overflow if the key is very long */
- return -1;
- }
-
- pair = jsonp_malloc(offsetof(pair_t, key) + len + 1);
- if(!pair)
- return -1;
-
- pair->hash = hash;
- strncpy(pair->key, key, len + 1);
- pair->value = value;
- list_init(&pair->list);
- list_init(&pair->ordered_list);
-
- insert_to_bucket(hashtable, bucket, &pair->list);
- list_insert(&hashtable->ordered_list, &pair->ordered_list);
-
- hashtable->size++;
- }
- return 0;
-}
-
-void *hashtable_get(hashtable_t *hashtable, const char *key)
-{
- pair_t *pair;
- size_t hash;
- bucket_t *bucket;
-
- hash = hash_str(key);
- bucket = &hashtable->buckets[hash & hashmask(hashtable->order)];
-
- pair = hashtable_find_pair(hashtable, bucket, key, hash);
- if(!pair)
- return NULL;
-
- return pair->value;
-}
-
-int hashtable_del(hashtable_t *hashtable, const char *key)
-{
- size_t hash = hash_str(key);
- return hashtable_do_del(hashtable, key, hash);
-}
-
-void hashtable_clear(hashtable_t *hashtable)
-{
- size_t i;
-
- hashtable_do_clear(hashtable);
-
- for(i = 0; i < hashsize(hashtable->order); i++)
- {
- hashtable->buckets[i].first = hashtable->buckets[i].last =
- &hashtable->list;
- }
-
- list_init(&hashtable->list);
- list_init(&hashtable->ordered_list);
- hashtable->size = 0;
-}
-
-void *hashtable_iter(hashtable_t *hashtable)
-{
- return hashtable_iter_next(hashtable, &hashtable->ordered_list);
-}
-
-void *hashtable_iter_at(hashtable_t *hashtable, const char *key)
-{
- pair_t *pair;
- size_t hash;
- bucket_t *bucket;
-
- hash = hash_str(key);
- bucket = &hashtable->buckets[hash & hashmask(hashtable->order)];
-
- pair = hashtable_find_pair(hashtable, bucket, key, hash);
- if(!pair)
- return NULL;
-
- return &pair->ordered_list;
-}
-
-void *hashtable_iter_next(hashtable_t *hashtable, void *iter)
-{
- list_t *list = (list_t *)iter;
- if(list->next == &hashtable->ordered_list)
- return NULL;
- return list->next;
-}
-
-void *hashtable_iter_key(void *iter)
-{
- pair_t *pair = ordered_list_to_pair((list_t *)iter);
- return pair->key;
-}
-
-void *hashtable_iter_value(void *iter)
-{
- pair_t *pair = ordered_list_to_pair((list_t *)iter);
- return pair->value;
-}
-
-void hashtable_iter_set(void *iter, json_t *value)
-{
- pair_t *pair = ordered_list_to_pair((list_t *)iter);
-
- json_decref(pair->value);
- pair->value = value;
-}
diff --git a/src/3rdparty/jansson/hashtable.h b/src/3rdparty/jansson/hashtable.h
deleted file mode 100644
index d4c32ae0..00000000
--- a/src/3rdparty/jansson/hashtable.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * This library is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef HASHTABLE_H
-#define HASHTABLE_H
-
-#include
-#include "jansson.h"
-
-struct hashtable_list {
- struct hashtable_list *prev;
- struct hashtable_list *next;
-};
-
-/* "pair" may be a bit confusing a name, but think of it as a
- key-value pair. In this case, it just encodes some extra data,
- too */
-struct hashtable_pair {
- struct hashtable_list list;
- struct hashtable_list ordered_list;
- size_t hash;
- json_t *value;
- char key[1];
-};
-
-struct hashtable_bucket {
- struct hashtable_list *first;
- struct hashtable_list *last;
-};
-
-typedef struct hashtable {
- size_t size;
- struct hashtable_bucket *buckets;
- size_t order; /* hashtable has pow(2, order) buckets */
- struct hashtable_list list;
- struct hashtable_list ordered_list;
-} hashtable_t;
-
-
-#define hashtable_key_to_iter(key_) \
- (&(container_of(key_, struct hashtable_pair, key)->ordered_list))
-
-
-/**
- * hashtable_init - Initialize a hashtable object
- *
- * @hashtable: The (statically allocated) hashtable object
- *
- * Initializes a statically allocated hashtable object. The object
- * should be cleared with hashtable_close when it's no longer used.
- *
- * Returns 0 on success, -1 on error (out of memory).
- */
-int hashtable_init(hashtable_t *hashtable);
-
-/**
- * hashtable_close - Release all resources used by a hashtable object
- *
- * @hashtable: The hashtable
- *
- * Destroys a statically allocated hashtable object.
- */
-void hashtable_close(hashtable_t *hashtable);
-
-/**
- * hashtable_set - Add/modify value in hashtable
- *
- * @hashtable: The hashtable object
- * @key: The key
- * @serial: For addition order of keys
- * @value: The value
- *
- * If a value with the given key already exists, its value is replaced
- * with the new value. Value is "stealed" in the sense that hashtable
- * doesn't increment its refcount but decreases the refcount when the
- * value is no longer needed.
- *
- * Returns 0 on success, -1 on failure (out of memory).
- */
-int hashtable_set(hashtable_t *hashtable, const char *key, json_t *value);
-
-/**
- * hashtable_get - Get a value associated with a key
- *
- * @hashtable: The hashtable object
- * @key: The key
- *
- * Returns value if it is found, or NULL otherwise.
- */
-void *hashtable_get(hashtable_t *hashtable, const char *key);
-
-/**
- * hashtable_del - Remove a value from the hashtable
- *
- * @hashtable: The hashtable object
- * @key: The key
- *
- * Returns 0 on success, or -1 if the key was not found.
- */
-int hashtable_del(hashtable_t *hashtable, const char *key);
-
-/**
- * hashtable_clear - Clear hashtable
- *
- * @hashtable: The hashtable object
- *
- * Removes all items from the hashtable.
- */
-void hashtable_clear(hashtable_t *hashtable);
-
-/**
- * hashtable_iter - Iterate over hashtable
- *
- * @hashtable: The hashtable object
- *
- * Returns an opaque iterator to the first element in the hashtable.
- * The iterator should be passed to hashtable_iter_* functions.
- * The hashtable items are not iterated over in any particular order.
- *
- * There's no need to free the iterator in any way. The iterator is
- * valid as long as the item that is referenced by the iterator is not
- * deleted. Other values may be added or deleted. In particular,
- * hashtable_iter_next() may be called on an iterator, and after that
- * the key/value pair pointed by the old iterator may be deleted.
- */
-void *hashtable_iter(hashtable_t *hashtable);
-
-/**
- * hashtable_iter_at - Return an iterator at a specific key
- *
- * @hashtable: The hashtable object
- * @key: The key that the iterator should point to
- *
- * Like hashtable_iter() but returns an iterator pointing to a
- * specific key.
- */
-void *hashtable_iter_at(hashtable_t *hashtable, const char *key);
-
-/**
- * hashtable_iter_next - Advance an iterator
- *
- * @hashtable: The hashtable object
- * @iter: The iterator
- *
- * Returns a new iterator pointing to the next element in the
- * hashtable or NULL if the whole hastable has been iterated over.
- */
-void *hashtable_iter_next(hashtable_t *hashtable, void *iter);
-
-/**
- * hashtable_iter_key - Retrieve the key pointed by an iterator
- *
- * @iter: The iterator
- */
-void *hashtable_iter_key(void *iter);
-
-/**
- * hashtable_iter_value - Retrieve the value pointed by an iterator
- *
- * @iter: The iterator
- */
-void *hashtable_iter_value(void *iter);
-
-/**
- * hashtable_iter_set - Set the value pointed by an iterator
- *
- * @iter: The iterator
- * @value: The value to set
- */
-void hashtable_iter_set(void *iter, json_t *value);
-
-#endif
diff --git a/src/3rdparty/jansson/hashtable_seed.c b/src/3rdparty/jansson/hashtable_seed.c
deleted file mode 100644
index 8aed5406..00000000
--- a/src/3rdparty/jansson/hashtable_seed.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/* Generate sizeof(uint32_t) bytes of as random data as possible to seed
- the hash function.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-
-#include
-#include
-
-#ifdef HAVE_STDINT_H
-#include
-#endif
-
-#ifdef HAVE_FCNTL_H
-#include
-#endif
-
-#ifdef HAVE_SCHED_H
-#include
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include
-#endif
-
-#ifdef HAVE_SYS_STAT_H
-#include
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include
-#endif
-
-#ifdef HAVE_SYS_TYPES_H
-#include
-#endif
-
-#if defined(_WIN32)
-/* For GetModuleHandle(), GetProcAddress() and GetCurrentProcessId() */
-#include
-#endif
-
-#include "jansson.h"
-
-
-static uint32_t buf_to_uint32(char *data) {
- size_t i;
- uint32_t result = 0;
-
- for (i = 0; i < sizeof(uint32_t); i++)
- result = (result << 8) | (unsigned char)data[i];
-
- return result;
-}
-
-
-
-/* /dev/urandom */
-#if !defined(_WIN32) && defined(USE_URANDOM)
-static int seed_from_urandom(uint32_t *seed) {
- /* Use unbuffered I/O if we have open(), close() and read(). Otherwise
- fall back to fopen() */
-
- char data[sizeof(uint32_t)];
- int ok;
-
-#if defined(HAVE_OPEN) && defined(HAVE_CLOSE) && defined(HAVE_READ)
- int urandom;
- urandom = open("/dev/urandom", O_RDONLY);
- if (urandom == -1)
- return 1;
-
- ok = read(urandom, data, sizeof(uint32_t)) == sizeof(uint32_t);
- close(urandom);
-#else
- FILE *urandom;
-
- urandom = fopen("/dev/urandom", "rb");
- if (!urandom)
- return 1;
-
- ok = fread(data, 1, sizeof(uint32_t), urandom) == sizeof(uint32_t);
- fclose(urandom);
-#endif
-
- if (!ok)
- return 1;
-
- *seed = buf_to_uint32(data);
- return 0;
-}
-#endif
-
-/* Windows Crypto API */
-#if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI)
-#include
-
-typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv, LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType, DWORD dwFlags);
-typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer);
-typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV hProv, DWORD dwFlags);
-
-static int seed_from_windows_cryptoapi(uint32_t *seed)
-{
- HINSTANCE hAdvAPI32 = NULL;
- CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
- CRYPTGENRANDOM pCryptGenRandom = NULL;
- CRYPTRELEASECONTEXT pCryptReleaseContext = NULL;
- HCRYPTPROV hCryptProv = 0;
- BYTE data[sizeof(uint32_t)];
- int ok;
-
- hAdvAPI32 = GetModuleHandle(TEXT("advapi32.dll"));
- if(hAdvAPI32 == NULL)
- return 1;
-
- pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(hAdvAPI32, "CryptAcquireContextA");
- if (!pCryptAcquireContext)
- return 1;
-
- pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(hAdvAPI32, "CryptGenRandom");
- if (!pCryptGenRandom)
- return 1;
-
- pCryptReleaseContext = (CRYPTRELEASECONTEXT)GetProcAddress(hAdvAPI32, "CryptReleaseContext");
- if (!pCryptReleaseContext)
- return 1;
-
- if (!pCryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
- return 1;
-
- ok = pCryptGenRandom(hCryptProv, sizeof(uint32_t), data);
- pCryptReleaseContext(hCryptProv, 0);
-
- if (!ok)
- return 1;
-
- *seed = buf_to_uint32((char *)data);
- return 0;
-}
-#endif
-
-/* gettimeofday() and getpid() */
-static int seed_from_timestamp_and_pid(uint32_t *seed) {
-#ifdef HAVE_GETTIMEOFDAY
- /* XOR of seconds and microseconds */
- struct timeval tv;
- gettimeofday(&tv, NULL);
- *seed = (uint32_t)tv.tv_sec ^ (uint32_t)tv.tv_usec;
-#else
- /* Seconds only */
- *seed = (uint32_t)time(NULL);
-#endif
-
- /* XOR with PID for more randomness */
-#if defined(_WIN32)
- *seed ^= (uint32_t)GetCurrentProcessId();
-#elif defined(HAVE_GETPID)
- *seed ^= (uint32_t)getpid();
-#endif
-
- return 0;
-}
-
-static uint32_t generate_seed() {
- uint32_t seed;
- int done = 0;
-
-#if !defined(_WIN32) && defined(USE_URANDOM)
- if (seed_from_urandom(&seed) == 0)
- done = 1;
-#endif
-
-#if defined(_WIN32) && defined(USE_WINDOWS_CRYPTOAPI)
- if (seed_from_windows_cryptoapi(&seed) == 0)
- done = 1;
-#endif
-
- if (!done) {
- /* Fall back to timestamp and PID if no better randomness is
- available */
- seed_from_timestamp_and_pid(&seed);
- }
-
- /* Make sure the seed is never zero */
- if (seed == 0)
- seed = 1;
-
- return seed;
-}
-
-
-volatile uint32_t hashtable_seed = 0;
-
-#if defined(HAVE_ATOMIC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32))
-static volatile char seed_initialized = 0;
-
-void json_object_seed(size_t seed) {
- uint32_t new_seed = (uint32_t)seed;
-
- if (hashtable_seed == 0) {
- if (__atomic_test_and_set(&seed_initialized, __ATOMIC_RELAXED) == 0) {
- /* Do the seeding ourselves */
- if (new_seed == 0)
- new_seed = generate_seed();
-
- __atomic_store_n(&hashtable_seed, new_seed, __ATOMIC_RELEASE);
- } else {
- /* Wait for another thread to do the seeding */
- do {
-#ifdef HAVE_SCHED_YIELD
- sched_yield();
-#endif
- } while(__atomic_load_n(&hashtable_seed, __ATOMIC_ACQUIRE) == 0);
- }
- }
-}
-#elif defined(HAVE_SYNC_BUILTINS) && (defined(HAVE_SCHED_YIELD) || !defined(_WIN32))
-void json_object_seed(size_t seed) {
- uint32_t new_seed = (uint32_t)seed;
-
- if (hashtable_seed == 0) {
- if (new_seed == 0) {
- /* Explicit synchronization fences are not supported by the
- __sync builtins, so every thread getting here has to
- generate the seed value.
- */
- new_seed = generate_seed();
- }
-
- do {
- if (__sync_bool_compare_and_swap(&hashtable_seed, 0, new_seed)) {
- /* We were the first to seed */
- break;
- } else {
- /* Wait for another thread to do the seeding */
-#ifdef HAVE_SCHED_YIELD
- sched_yield();
-#endif
- }
- } while(hashtable_seed == 0);
- }
-}
-#elif defined(_WIN32)
-static long seed_initialized = 0;
-void json_object_seed(size_t seed) {
- uint32_t new_seed = (uint32_t)seed;
-
- if (hashtable_seed == 0) {
- if (InterlockedIncrement(&seed_initialized) == 1) {
- /* Do the seeding ourselves */
- if (new_seed == 0)
- new_seed = generate_seed();
-
- hashtable_seed = new_seed;
- } else {
- /* Wait for another thread to do the seeding */
- do {
- SwitchToThread();
- } while (hashtable_seed == 0);
- }
- }
-}
-#else
-/* Fall back to a thread-unsafe version */
-void json_object_seed(size_t seed) {
- uint32_t new_seed = (uint32_t)seed;
-
- if (hashtable_seed == 0) {
- if (new_seed == 0)
- new_seed = generate_seed();
-
- hashtable_seed = new_seed;
- }
-}
-#endif
diff --git a/src/3rdparty/jansson/jansson.h b/src/3rdparty/jansson/jansson.h
deleted file mode 100644
index a5927bd6..00000000
--- a/src/3rdparty/jansson/jansson.h
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef JANSSON_H
-#define JANSSON_H
-
-#include
-#include /* for size_t */
-#include
-
-#include "jansson_config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* version */
-
-#define JANSSON_MAJOR_VERSION 2
-#define JANSSON_MINOR_VERSION 10
-#define JANSSON_MICRO_VERSION 0
-
-/* Micro version is omitted if it's 0 */
-#define JANSSON_VERSION "2.10"
-
-/* Version as a 3-byte hex number, e.g. 0x010201 == 1.2.1. Use this
- for numeric comparisons, e.g. #if JANSSON_VERSION_HEX >= ... */
-#define JANSSON_VERSION_HEX ((JANSSON_MAJOR_VERSION << 16) | \
- (JANSSON_MINOR_VERSION << 8) | \
- (JANSSON_MICRO_VERSION << 0))
-
-
-/* types */
-
-typedef enum {
- JSON_OBJECT,
- JSON_ARRAY,
- JSON_STRING,
- JSON_INTEGER,
- JSON_REAL,
- JSON_TRUE,
- JSON_FALSE,
- JSON_NULL
-} json_type;
-
-typedef struct json_t {
- json_type type;
- size_t refcount;
-} json_t;
-
-#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
-#if JSON_INTEGER_IS_LONG_LONG
-#ifdef _WIN32
-#define JSON_INTEGER_FORMAT "I64d"
-#else
-#define JSON_INTEGER_FORMAT "lld"
-#endif
-typedef long long json_int_t;
-#else
-#define JSON_INTEGER_FORMAT "ld"
-typedef long json_int_t;
-#endif /* JSON_INTEGER_IS_LONG_LONG */
-#endif
-
-#define json_typeof(json) ((json)->type)
-#define json_is_object(json) ((json) && json_typeof(json) == JSON_OBJECT)
-#define json_is_array(json) ((json) && json_typeof(json) == JSON_ARRAY)
-#define json_is_string(json) ((json) && json_typeof(json) == JSON_STRING)
-#define json_is_integer(json) ((json) && json_typeof(json) == JSON_INTEGER)
-#define json_is_real(json) ((json) && json_typeof(json) == JSON_REAL)
-#define json_is_number(json) (json_is_integer(json) || json_is_real(json))
-#define json_is_true(json) ((json) && json_typeof(json) == JSON_TRUE)
-#define json_is_false(json) ((json) && json_typeof(json) == JSON_FALSE)
-#define json_boolean_value json_is_true
-#define json_is_boolean(json) (json_is_true(json) || json_is_false(json))
-#define json_is_null(json) ((json) && json_typeof(json) == JSON_NULL)
-
-/* construction, destruction, reference counting */
-
-json_t *json_object(void);
-json_t *json_array(void);
-json_t *json_string(const char *value);
-json_t *json_stringn(const char *value, size_t len);
-json_t *json_string_nocheck(const char *value);
-json_t *json_stringn_nocheck(const char *value, size_t len);
-json_t *json_integer(json_int_t value);
-json_t *json_real(double value);
-json_t *json_true(void);
-json_t *json_false(void);
-#define json_boolean(val) ((val) ? json_true() : json_false())
-json_t *json_null(void);
-
-static JSON_INLINE
-json_t *json_incref(json_t *json)
-{
- if(json && json->refcount != (size_t)-1)
- ++json->refcount;
- return json;
-}
-
-/* do not call json_delete directly */
-void json_delete(json_t *json);
-
-static JSON_INLINE
-void json_decref(json_t *json)
-{
- if(json && json->refcount != (size_t)-1 && --json->refcount == 0)
- json_delete(json);
-}
-
-#if defined(__GNUC__) || defined(__clang__)
-static JSON_INLINE
-void json_decrefp(json_t **json)
-{
- if(json) {
- json_decref(*json);
- *json = NULL;
- }
-}
-
-#define json_auto_t json_t __attribute__((cleanup(json_decrefp)))
-#endif
-
-
-/* error reporting */
-
-#define JSON_ERROR_TEXT_LENGTH 160
-#define JSON_ERROR_SOURCE_LENGTH 80
-
-typedef struct {
- int line;
- int column;
- int position;
- char source[JSON_ERROR_SOURCE_LENGTH];
- char text[JSON_ERROR_TEXT_LENGTH];
-} json_error_t;
-
-
-/* getters, setters, manipulation */
-
-void json_object_seed(size_t seed);
-size_t json_object_size(const json_t *object);
-json_t *json_object_get(const json_t *object, const char *key);
-int json_object_set_new(json_t *object, const char *key, json_t *value);
-int json_object_set_new_nocheck(json_t *object, const char *key, json_t *value);
-int json_object_del(json_t *object, const char *key);
-int json_object_clear(json_t *object);
-int json_object_update(json_t *object, json_t *other);
-int json_object_update_existing(json_t *object, json_t *other);
-int json_object_update_missing(json_t *object, json_t *other);
-void *json_object_iter(json_t *object);
-void *json_object_iter_at(json_t *object, const char *key);
-void *json_object_key_to_iter(const char *key);
-void *json_object_iter_next(json_t *object, void *iter);
-const char *json_object_iter_key(void *iter);
-json_t *json_object_iter_value(void *iter);
-int json_object_iter_set_new(json_t *object, void *iter, json_t *value);
-
-#define json_object_foreach(object, key, value) \
- for(key = json_object_iter_key(json_object_iter(object)); \
- key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
- key = json_object_iter_key(json_object_iter_next(object, json_object_key_to_iter(key))))
-
-#define json_object_foreach_safe(object, n, key, value) \
- for(key = json_object_iter_key(json_object_iter(object)), \
- n = json_object_iter_next(object, json_object_key_to_iter(key)); \
- key && (value = json_object_iter_value(json_object_key_to_iter(key))); \
- key = json_object_iter_key(n), \
- n = json_object_iter_next(object, json_object_key_to_iter(key)))
-
-#define json_array_foreach(array, index, value) \
- for(index = 0; \
- index < json_array_size(array) && (value = json_array_get(array, index)); \
- index++)
-
-static JSON_INLINE
-int json_object_set(json_t *object, const char *key, json_t *value)
-{
- return json_object_set_new(object, key, json_incref(value));
-}
-
-static JSON_INLINE
-int json_object_set_nocheck(json_t *object, const char *key, json_t *value)
-{
- return json_object_set_new_nocheck(object, key, json_incref(value));
-}
-
-static JSON_INLINE
-int json_object_iter_set(json_t *object, void *iter, json_t *value)
-{
- return json_object_iter_set_new(object, iter, json_incref(value));
-}
-
-size_t json_array_size(const json_t *array);
-json_t *json_array_get(const json_t *array, size_t index);
-int json_array_set_new(json_t *array, size_t index, json_t *value);
-int json_array_append_new(json_t *array, json_t *value);
-int json_array_insert_new(json_t *array, size_t index, json_t *value);
-int json_array_remove(json_t *array, size_t index);
-int json_array_clear(json_t *array);
-int json_array_extend(json_t *array, json_t *other);
-
-static JSON_INLINE
-int json_array_set(json_t *array, size_t ind, json_t *value)
-{
- return json_array_set_new(array, ind, json_incref(value));
-}
-
-static JSON_INLINE
-int json_array_append(json_t *array, json_t *value)
-{
- return json_array_append_new(array, json_incref(value));
-}
-
-static JSON_INLINE
-int json_array_insert(json_t *array, size_t ind, json_t *value)
-{
- return json_array_insert_new(array, ind, json_incref(value));
-}
-
-const char *json_string_value(const json_t *string);
-size_t json_string_length(const json_t *string);
-json_int_t json_integer_value(const json_t *integer);
-double json_real_value(const json_t *real);
-double json_number_value(const json_t *json);
-
-int json_string_set(json_t *string, const char *value);
-int json_string_setn(json_t *string, const char *value, size_t len);
-int json_string_set_nocheck(json_t *string, const char *value);
-int json_string_setn_nocheck(json_t *string, const char *value, size_t len);
-int json_integer_set(json_t *integer, json_int_t value);
-int json_real_set(json_t *real, double value);
-
-/* pack, unpack */
-
-json_t *json_pack(const char *fmt, ...);
-json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...);
-json_t *json_vpack_ex(json_error_t *error, size_t flags, const char *fmt, va_list ap);
-
-#define JSON_VALIDATE_ONLY 0x1
-#define JSON_STRICT 0x2
-
-int json_unpack(json_t *root, const char *fmt, ...);
-int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...);
-int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, va_list ap);
-
-
-/* equality */
-
-int json_equal(json_t *value1, json_t *value2);
-
-
-/* copying */
-
-json_t *json_copy(json_t *value);
-json_t *json_deep_copy(const json_t *value);
-
-
-/* decoding */
-
-#define JSON_REJECT_DUPLICATES 0x1
-#define JSON_DISABLE_EOF_CHECK 0x2
-#define JSON_DECODE_ANY 0x4
-#define JSON_DECODE_INT_AS_REAL 0x8
-#define JSON_ALLOW_NUL 0x10
-
-typedef size_t (*json_load_callback_t)(void *buffer, size_t buflen, void *data);
-
-json_t *json_loads(const char *input, size_t flags, json_error_t *error);
-json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error);
-json_t *json_loadf(FILE *input, size_t flags, json_error_t *error);
-json_t *json_loadfd(int input, size_t flags, json_error_t *error);
-json_t *json_load_file(const char *path, size_t flags, json_error_t *error);
-json_t *json_load_callback(json_load_callback_t callback, void *data, size_t flags, json_error_t *error);
-
-
-/* encoding */
-
-#define JSON_MAX_INDENT 0x1F
-#define JSON_INDENT(n) ((n) & JSON_MAX_INDENT)
-#define JSON_COMPACT 0x20
-#define JSON_ENSURE_ASCII 0x40
-#define JSON_SORT_KEYS 0x80
-#define JSON_PRESERVE_ORDER 0x100
-#define JSON_ENCODE_ANY 0x200
-#define JSON_ESCAPE_SLASH 0x400
-#define JSON_REAL_PRECISION(n) (((n) & 0x1F) << 11)
-#define JSON_EMBED 0x10000
-
-typedef int (*json_dump_callback_t)(const char *buffer, size_t size, void *data);
-
-char *json_dumps(const json_t *json, size_t flags);
-size_t json_dumpb(const json_t *json, char *buffer, size_t size, size_t flags);
-int json_dumpf(const json_t *json, FILE *output, size_t flags);
-int json_dumpfd(const json_t *json, int output, size_t flags);
-int json_dump_file(const json_t *json, const char *path, size_t flags);
-int json_dump_callback(const json_t *json, json_dump_callback_t callback, void *data, size_t flags);
-
-/* custom memory allocation */
-
-typedef void *(*json_malloc_t)(size_t);
-typedef void (*json_free_t)(void *);
-
-void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn);
-void json_get_alloc_funcs(json_malloc_t *malloc_fn, json_free_t *free_fn);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/3rdparty/jansson/jansson_config.h b/src/3rdparty/jansson/jansson_config.h
deleted file mode 100644
index f1a5ddd2..00000000
--- a/src/3rdparty/jansson/jansson_config.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2010-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- *
- *
- * This file specifies a part of the site-specific configuration for
- * Jansson, namely those things that affect the public API in
- * jansson.h.
- *
- * The configure script copies this file to jansson_config.h and
- * replaces @var@ substitutions by values that fit your system. If you
- * cannot run the configure script, you can do the value substitution
- * by hand.
- */
-
-#ifndef JANSSON_CONFIG_H
-#define JANSSON_CONFIG_H
-
-/* If your compiler supports the inline keyword in C, JSON_INLINE is
- defined to `inline', otherwise empty. In C++, the inline is always
- supported. */
-#ifdef __cplusplus
-#define JSON_INLINE inline
-#else
-#define JSON_INLINE inline
-#endif
-
-/* If your compiler supports the `long long` type and the strtoll()
- library function, JSON_INTEGER_IS_LONG_LONG is defined to 1,
- otherwise to 0. */
-#define JSON_INTEGER_IS_LONG_LONG 1
-
-/* If locale.h and localeconv() are available, define to 1,
- otherwise to 0. */
-#define JSON_HAVE_LOCALECONV 1
-
-/* Maximum recursion depth for parsing JSON input.
- This limits the depth of e.g. array-within-array constructions. */
-#define JSON_PARSER_MAX_DEPTH 2048
-
-#endif
diff --git a/src/3rdparty/jansson/jansson_private.h b/src/3rdparty/jansson/jansson_private.h
deleted file mode 100644
index 5ed96158..00000000
--- a/src/3rdparty/jansson/jansson_private.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef JANSSON_PRIVATE_H
-#define JANSSON_PRIVATE_H
-
-#include "jansson_private_config.h"
-#include
-#include "jansson.h"
-#include "hashtable.h"
-#include "strbuffer.h"
-
-#define container_of(ptr_, type_, member_) \
- ((type_ *)((char *)ptr_ - offsetof(type_, member_)))
-
-/* On some platforms, max() may already be defined */
-#ifndef max
-#define max(a, b) ((a) > (b) ? (a) : (b))
-#endif
-
-/* va_copy is a C99 feature. In C89 implementations, it's sometimes
- available as __va_copy. If not, memcpy() should do the trick. */
-#ifndef va_copy
-#ifdef __va_copy
-#define va_copy __va_copy
-#else
-#define va_copy(a, b) memcpy(&(a), &(b), sizeof(va_list))
-#endif
-#endif
-
-typedef struct {
- json_t json;
- hashtable_t hashtable;
- int visited;
-} json_object_t;
-
-typedef struct {
- json_t json;
- size_t size;
- size_t entries;
- json_t **table;
- int visited;
-} json_array_t;
-
-typedef struct {
- json_t json;
- char *value;
- size_t length;
-} json_string_t;
-
-typedef struct {
- json_t json;
- double value;
-} json_real_t;
-
-typedef struct {
- json_t json;
- json_int_t value;
-} json_integer_t;
-
-#define json_to_object(json_) container_of(json_, json_object_t, json)
-#define json_to_array(json_) container_of(json_, json_array_t, json)
-#define json_to_string(json_) container_of(json_, json_string_t, json)
-#define json_to_real(json_) container_of(json_, json_real_t, json)
-#define json_to_integer(json_) container_of(json_, json_integer_t, json)
-
-/* Create a string by taking ownership of an existing buffer */
-json_t *jsonp_stringn_nocheck_own(const char *value, size_t len);
-
-/* Error message formatting */
-void jsonp_error_init(json_error_t *error, const char *source);
-void jsonp_error_set_source(json_error_t *error, const char *source);
-void jsonp_error_set(json_error_t *error, int line, int column,
- size_t position, const char *msg, ...);
-void jsonp_error_vset(json_error_t *error, int line, int column,
- size_t position, const char *msg, va_list ap);
-
-/* Locale independent string<->double conversions */
-int jsonp_strtod(strbuffer_t *strbuffer, double *out);
-int jsonp_dtostr(char *buffer, size_t size, double value, int prec);
-
-/* Wrappers for custom memory functions */
-void* jsonp_malloc(size_t size);
-void jsonp_free(void *ptr);
-char *jsonp_strndup(const char *str, size_t length);
-char *jsonp_strdup(const char *str);
-char *jsonp_strndup(const char *str, size_t len);
-
-
-/* Windows compatibility */
-#if defined(_WIN32) || defined(WIN32)
-# if defined(_MSC_VER) /* MS compiller */
-# if (_MSC_VER < 1900) && !defined(snprintf) /* snprintf not defined yet & not introduced */
-# define snprintf _snprintf
-# endif
-# if (_MSC_VER < 1500) && !defined(vsnprintf) /* vsnprintf not defined yet & not introduced */
-# define vsnprintf(b,c,f,a) _vsnprintf(b,c,f,a)
-# endif
-# else /* Other Windows compiller, old definition */
-# define snprintf _snprintf
-# define vsnprintf _vsnprintf
-# endif
-#endif
-
-#endif
diff --git a/src/3rdparty/jansson/jansson_private_config.h b/src/3rdparty/jansson/jansson_private_config.h
deleted file mode 100644
index 671993d9..00000000
--- a/src/3rdparty/jansson/jansson_private_config.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/* jansson_private_config.h. Generated from jansson_private_config.h.in by configure. */
-/* jansson_private_config.h.in. Generated from configure.ac by autoheader. */
-
-/* Define to 1 if gcc's __atomic builtins are available */
-#ifndef _MSC_VER
-# define HAVE_ATOMIC_BUILTINS 1
-#endif
-
-/* Define to 1 if you have the `close' function. */
-#define HAVE_CLOSE 1
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_DLFCN_H */
-
-/* Define to 1 if you have the header file. */
-/* #undef HAVE_ENDIAN_H */
-
-/* Define to 1 if you have the header file. */
-#define HAVE_FCNTL_H 1
-
-/* Define to 1 if you have the `getpid' function. */
-#define HAVE_GETPID 1
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#ifndef _MSC_VER
-# define HAVE_GETTIMEOFDAY 1
-#endif
-
-/* Define to 1 if you have the header file. */
-#define HAVE_INTTYPES_H 1
-
-/* Define to 1 if you have the `localeconv' function. */
-#define HAVE_LOCALECONV 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_LOCALE_H 1
-
-/* Define to 1 if the system has the type 'long long int'. */
-#define HAVE_LONG_LONG_INT 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_MEMORY_H 1
-
-/* Define to 1 if you have the `open' function. */
-#define HAVE_OPEN 1
-
-/* Define to 1 if you have the `read' function. */
-#define HAVE_READ 1
-
-/* Define to 1 if you have the header file. */
-#ifndef _MSC_VER
-# define HAVE_SCHED_H 1
-#endif
-
-/* Define to 1 if you have the `sched_yield' function. */
-#ifndef _MSC_VER
-# define HAVE_SCHED_YIELD 1
-#endif
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDINT_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STDLIB_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STRINGS_H 1
-
-/* Define to 1 if you have the header file. */
-#define HAVE_STRING_H 1
-
-/* Define to 1 if you have the `strtoll' function. */
-#define HAVE_STRTOLL 1
-
-/* Define to 1 if gcc's __sync builtins are available */
-#define HAVE_SYNC_BUILTINS 1
-
-/* Define to 1 if you have the header file. */
-#ifndef _MSC_VER
-# define HAVE_SYS_PARAM_H 1
-#endif
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_STAT_H 1
-
-/* Define to 1 if you have the header file. */
-#ifndef _MSC_VER
-# define HAVE_SYS_TIME_H 1
-#endif
-
-/* Define to 1 if you have the header file. */
-#define HAVE_SYS_TYPES_H 1
-
-/* Define to 1 if you have the header file. */
-#ifndef _MSC_VER
-# define HAVE_UNISTD_H 1
-#endif
-
-/* Define to 1 if the system has the type 'unsigned long long int'. */
-#define HAVE_UNSIGNED_LONG_LONG_INT 1
-
-/* Number of buckets new object hashtables contain is 2 raised to this power.
- E.g. 3 -> 2^3 = 8. */
-#define INITIAL_HASHTABLE_ORDER 3
-
-/* Define to the sub-directory where libtool stores uninstalled libraries. */
-#define LT_OBJDIR ".libs/"
-
-/* Name of package */
-#define PACKAGE "jansson"
-
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "petri@digip.org"
-
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "jansson"
-
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "jansson 2.9"
-
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "jansson"
-
-/* Define to the home page for this package. */
-#define PACKAGE_URL ""
-
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.9"
-
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
-
-/* Define to 1 if /dev/urandom should be used for seeding the hash function */
-#define USE_URANDOM 1
-
-/* Define to 1 if CryptGenRandom should be used for seeding the hash function
- */
-#define USE_WINDOWS_CRYPTOAPI 1
-
-/* Version number of package */
-#define VERSION "2.9"
-
-/* Define for Solaris 2.5.1 so the uint32_t typedef from ,
- , or is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT32_T */
-
-/* Define for Solaris 2.5.1 so the uint8_t typedef from ,
- , or is not used. If the typedef were allowed, the
- #define below would cause a syntax error. */
-/* #undef _UINT8_T */
-
-/* Define to `__inline__' or `__inline' if that's what the C compiler
- calls it, or to nothing if 'inline' is not supported under any name. */
-#ifndef __cplusplus
-/* #undef inline */
-#endif
-
-/* Define to the type of a signed integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef int32_t */
-
-/* Define to the type of an unsigned integer type of width exactly 16 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint16_t */
-
-/* Define to the type of an unsigned integer type of width exactly 32 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint32_t */
-
-/* Define to the type of an unsigned integer type of width exactly 8 bits if
- such a type exists and the standard includes do not define it. */
-/* #undef uint8_t */
diff --git a/src/3rdparty/jansson/load.c b/src/3rdparty/jansson/load.c
deleted file mode 100644
index d9399696..00000000
--- a/src/3rdparty/jansson/load.c
+++ /dev/null
@@ -1,1158 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include "jansson_private.h"
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-#if defined(HAVE_UNISTD_H)
-# include
-#elif defined(_MSC_VER)
-# include
-# define HAVE_UNISTD_H
-# define STDIN_FILENO 0
-#endif
-
-#include "jansson.h"
-#include "strbuffer.h"
-#include "utf.h"
-
-#define STREAM_STATE_OK 0
-#define STREAM_STATE_EOF -1
-#define STREAM_STATE_ERROR -2
-
-#define TOKEN_INVALID -1
-#define TOKEN_EOF 0
-#define TOKEN_STRING 256
-#define TOKEN_INTEGER 257
-#define TOKEN_REAL 258
-#define TOKEN_TRUE 259
-#define TOKEN_FALSE 260
-#define TOKEN_NULL 261
-
-/* Locale independent versions of isxxx() functions */
-#define l_isupper(c) ('A' <= (c) && (c) <= 'Z')
-#define l_islower(c) ('a' <= (c) && (c) <= 'z')
-#define l_isalpha(c) (l_isupper(c) || l_islower(c))
-#define l_isdigit(c) ('0' <= (c) && (c) <= '9')
-#define l_isxdigit(c) \
- (l_isdigit(c) || ('A' <= (c) && (c) <= 'F') || ('a' <= (c) && (c) <= 'f'))
-
-/* Read one byte from stream, convert to unsigned char, then int, and
- return. return EOF on end of file. This corresponds to the
- behaviour of fgetc(). */
-typedef int (*get_func)(void *data);
-
-typedef struct {
- get_func get;
- void *data;
- char buffer[5];
- size_t buffer_pos;
- int state;
- int line;
- int column, last_column;
- size_t position;
-} stream_t;
-
-typedef struct {
- stream_t stream;
- strbuffer_t saved_text;
- size_t flags;
- size_t depth;
- int token;
- union {
- struct {
- char *val;
- size_t len;
- } string;
- json_int_t integer;
- double real;
- } value;
-} lex_t;
-
-#define stream_to_lex(stream) container_of(stream, lex_t, stream)
-
-
-/*** error reporting ***/
-
-static void error_set(json_error_t *error, const lex_t *lex,
- const char *msg, ...)
-{
- va_list ap;
- char msg_text[JSON_ERROR_TEXT_LENGTH];
- char msg_with_context[JSON_ERROR_TEXT_LENGTH];
-
- int line = -1, col = -1;
- size_t pos = 0;
- const char *result = msg_text;
-
- if(!error)
- return;
-
- va_start(ap, msg);
- vsnprintf(msg_text, JSON_ERROR_TEXT_LENGTH, msg, ap);
- msg_text[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
- va_end(ap);
-
- if(lex)
- {
- const char *saved_text = strbuffer_value(&lex->saved_text);
-
- line = lex->stream.line;
- col = lex->stream.column;
- pos = lex->stream.position;
-
- if(saved_text && saved_text[0])
- {
- if(lex->saved_text.length <= 20) {
- snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
- "%s near '%s'", msg_text, saved_text);
- msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
- result = msg_with_context;
- }
- }
- else
- {
- if(lex->stream.state == STREAM_STATE_ERROR) {
- /* No context for UTF-8 decoding errors */
- result = msg_text;
- }
- else {
- snprintf(msg_with_context, JSON_ERROR_TEXT_LENGTH,
- "%s near end of file", msg_text);
- msg_with_context[JSON_ERROR_TEXT_LENGTH - 1] = '\0';
- result = msg_with_context;
- }
- }
- }
-
- jsonp_error_set(error, line, col, pos, "%s", result);
-}
-
-
-/*** lexical analyzer ***/
-
-static void
-stream_init(stream_t *stream, get_func get, void *data)
-{
- stream->get = get;
- stream->data = data;
- stream->buffer[0] = '\0';
- stream->buffer_pos = 0;
-
- stream->state = STREAM_STATE_OK;
- stream->line = 1;
- stream->column = 0;
- stream->position = 0;
-}
-
-static int stream_get(stream_t *stream, json_error_t *error)
-{
- int c;
-
- if(stream->state != STREAM_STATE_OK)
- return stream->state;
-
- if(!stream->buffer[stream->buffer_pos])
- {
- c = stream->get(stream->data);
- if(c == EOF) {
- stream->state = STREAM_STATE_EOF;
- return STREAM_STATE_EOF;
- }
-
- stream->buffer[0] = c;
- stream->buffer_pos = 0;
-
- if(0x80 <= c && c <= 0xFF)
- {
- /* multi-byte UTF-8 sequence */
- size_t i, count;
-
- count = utf8_check_first(c);
- if(!count)
- goto out;
-
- assert(count >= 2);
-
- for(i = 1; i < count; i++)
- stream->buffer[i] = stream->get(stream->data);
-
- if(!utf8_check_full(stream->buffer, count, NULL))
- goto out;
-
- stream->buffer[count] = '\0';
- }
- else
- stream->buffer[1] = '\0';
- }
-
- c = stream->buffer[stream->buffer_pos++];
-
- stream->position++;
- if(c == '\n') {
- stream->line++;
- stream->last_column = stream->column;
- stream->column = 0;
- }
- else if(utf8_check_first(c)) {
- /* track the Unicode character column, so increment only if
- this is the first character of a UTF-8 sequence */
- stream->column++;
- }
-
- return c;
-
-out:
- stream->state = STREAM_STATE_ERROR;
- error_set(error, stream_to_lex(stream), "unable to decode byte 0x%x", c);
- return STREAM_STATE_ERROR;
-}
-
-static void stream_unget(stream_t *stream, int c)
-{
- if(c == STREAM_STATE_EOF || c == STREAM_STATE_ERROR)
- return;
-
- stream->position--;
- if(c == '\n') {
- stream->line--;
- stream->column = stream->last_column;
- }
- else if(utf8_check_first(c))
- stream->column--;
-
- assert(stream->buffer_pos > 0);
- stream->buffer_pos--;
- assert(stream->buffer[stream->buffer_pos] == c);
-}
-
-
-static int lex_get(lex_t *lex, json_error_t *error)
-{
- return stream_get(&lex->stream, error);
-}
-
-static void lex_save(lex_t *lex, int c)
-{
- strbuffer_append_byte(&lex->saved_text, c);
-}
-
-static int lex_get_save(lex_t *lex, json_error_t *error)
-{
- int c = stream_get(&lex->stream, error);
- if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR)
- lex_save(lex, c);
- return c;
-}
-
-static void lex_unget(lex_t *lex, int c)
-{
- stream_unget(&lex->stream, c);
-}
-
-static void lex_unget_unsave(lex_t *lex, int c)
-{
- if(c != STREAM_STATE_EOF && c != STREAM_STATE_ERROR) {
- /* Since we treat warnings as errors, when assertions are turned
- * off the "d" variable would be set but never used. Which is
- * treated as an error by GCC.
- */
- #ifndef NDEBUG
- char d;
- #endif
- stream_unget(&lex->stream, c);
- #ifndef NDEBUG
- d =
- #endif
- strbuffer_pop(&lex->saved_text);
- assert(c == d);
- }
-}
-
-static void lex_save_cached(lex_t *lex)
-{
- while(lex->stream.buffer[lex->stream.buffer_pos] != '\0')
- {
- lex_save(lex, lex->stream.buffer[lex->stream.buffer_pos]);
- lex->stream.buffer_pos++;
- lex->stream.position++;
- }
-}
-
-static void lex_free_string(lex_t *lex)
-{
- jsonp_free(lex->value.string.val);
- lex->value.string.val = NULL;
- lex->value.string.len = 0;
-}
-
-/* assumes that str points to 'u' plus at least 4 valid hex digits */
-static int32_t decode_unicode_escape(const char *str)
-{
- int i;
- int32_t value = 0;
-
- assert(str[0] == 'u');
-
- for(i = 1; i <= 4; i++) {
- char c = str[i];
- value <<= 4;
- if(l_isdigit(c))
- value += c - '0';
- else if(l_islower(c))
- value += c - 'a' + 10;
- else if(l_isupper(c))
- value += c - 'A' + 10;
- else
- return -1;
- }
-
- return value;
-}
-
-static void lex_scan_string(lex_t *lex, json_error_t *error)
-{
- int c;
- const char *p;
- char *t;
- int i;
-
- lex->value.string.val = NULL;
- lex->token = TOKEN_INVALID;
-
- c = lex_get_save(lex, error);
-
- while(c != '"') {
- if(c == STREAM_STATE_ERROR)
- goto out;
-
- else if(c == STREAM_STATE_EOF) {
- error_set(error, lex, "premature end of input");
- goto out;
- }
-
- else if(0 <= c && c <= 0x1F) {
- /* control character */
- lex_unget_unsave(lex, c);
- if(c == '\n')
- error_set(error, lex, "unexpected newline");
- else
- error_set(error, lex, "control character 0x%x", c);
- goto out;
- }
-
- else if(c == '\\') {
- c = lex_get_save(lex, error);
- if(c == 'u') {
- c = lex_get_save(lex, error);
- for(i = 0; i < 4; i++) {
- if(!l_isxdigit(c)) {
- error_set(error, lex, "invalid escape");
- goto out;
- }
- c = lex_get_save(lex, error);
- }
- }
- else if(c == '"' || c == '\\' || c == '/' || c == 'b' ||
- c == 'f' || c == 'n' || c == 'r' || c == 't')
- c = lex_get_save(lex, error);
- else {
- error_set(error, lex, "invalid escape");
- goto out;
- }
- }
- else
- c = lex_get_save(lex, error);
- }
-
- /* the actual value is at most of the same length as the source
- string, because:
- - shortcut escapes (e.g. "\t") (length 2) are converted to 1 byte
- - a single \uXXXX escape (length 6) is converted to at most 3 bytes
- - two \uXXXX escapes (length 12) forming an UTF-16 surrogate pair
- are converted to 4 bytes
- */
- t = jsonp_malloc(lex->saved_text.length + 1);
- if(!t) {
- /* this is not very nice, since TOKEN_INVALID is returned */
- goto out;
- }
- lex->value.string.val = t;
-
- /* + 1 to skip the " */
- p = strbuffer_value(&lex->saved_text) + 1;
-
- while(*p != '"') {
- if(*p == '\\') {
- p++;
- if(*p == 'u') {
- size_t length;
- int32_t value;
-
- value = decode_unicode_escape(p);
- if(value < 0) {
- error_set(error, lex, "invalid Unicode escape '%.6s'", p - 1);
- goto out;
- }
- p += 5;
-
- if(0xD800 <= value && value <= 0xDBFF) {
- /* surrogate pair */
- if(*p == '\\' && *(p + 1) == 'u') {
- int32_t value2 = decode_unicode_escape(++p);
- if(value2 < 0) {
- error_set(error, lex, "invalid Unicode escape '%.6s'", p - 1);
- goto out;
- }
- p += 5;
-
- if(0xDC00 <= value2 && value2 <= 0xDFFF) {
- /* valid second surrogate */
- value =
- ((value - 0xD800) << 10) +
- (value2 - 0xDC00) +
- 0x10000;
- }
- else {
- /* invalid second surrogate */
- error_set(error, lex,
- "invalid Unicode '\\u%04X\\u%04X'",
- value, value2);
- goto out;
- }
- }
- else {
- /* no second surrogate */
- error_set(error, lex, "invalid Unicode '\\u%04X'",
- value);
- goto out;
- }
- }
- else if(0xDC00 <= value && value <= 0xDFFF) {
- error_set(error, lex, "invalid Unicode '\\u%04X'", value);
- goto out;
- }
-
- if(utf8_encode(value, t, &length))
- assert(0);
- t += length;
- }
- else {
- switch(*p) {
- case '"': case '\\': case '/':
- *t = *p; break;
- case 'b': *t = '\b'; break;
- case 'f': *t = '\f'; break;
- case 'n': *t = '\n'; break;
- case 'r': *t = '\r'; break;
- case 't': *t = '\t'; break;
- default: assert(0);
- }
- t++;
- p++;
- }
- }
- else
- *(t++) = *(p++);
- }
- *t = '\0';
- lex->value.string.len = t - lex->value.string.val;
- lex->token = TOKEN_STRING;
- return;
-
-out:
- lex_free_string(lex);
-}
-
-#ifndef JANSSON_USING_CMAKE /* disabled if using cmake */
-#if JSON_INTEGER_IS_LONG_LONG
-#ifdef _MSC_VER /* Microsoft Visual Studio */
-#define json_strtoint _strtoi64
-#else
-#define json_strtoint strtoll
-#endif
-#else
-#define json_strtoint strtol
-#endif
-#endif
-
-static int lex_scan_number(lex_t *lex, int c, json_error_t *error)
-{
- const char *saved_text;
- char *end;
- double doubleval;
-
- lex->token = TOKEN_INVALID;
-
- if(c == '-')
- c = lex_get_save(lex, error);
-
- if(c == '0') {
- c = lex_get_save(lex, error);
- if(l_isdigit(c)) {
- lex_unget_unsave(lex, c);
- goto out;
- }
- }
- else if(l_isdigit(c)) {
- do
- c = lex_get_save(lex, error);
- while(l_isdigit(c));
- }
- else {
- lex_unget_unsave(lex, c);
- goto out;
- }
-
- if(!(lex->flags & JSON_DECODE_INT_AS_REAL) &&
- c != '.' && c != 'E' && c != 'e')
- {
- json_int_t intval;
-
- lex_unget_unsave(lex, c);
-
- saved_text = strbuffer_value(&lex->saved_text);
-
- errno = 0;
- intval = json_strtoint(saved_text, &end, 10);
- if(errno == ERANGE) {
- if(intval < 0)
- error_set(error, lex, "too big negative integer");
- else
- error_set(error, lex, "too big integer");
- goto out;
- }
-
- assert(end == saved_text + lex->saved_text.length);
-
- lex->token = TOKEN_INTEGER;
- lex->value.integer = intval;
- return 0;
- }
-
- if(c == '.') {
- c = lex_get(lex, error);
- if(!l_isdigit(c)) {
- lex_unget(lex, c);
- goto out;
- }
- lex_save(lex, c);
-
- do
- c = lex_get_save(lex, error);
- while(l_isdigit(c));
- }
-
- if(c == 'E' || c == 'e') {
- c = lex_get_save(lex, error);
- if(c == '+' || c == '-')
- c = lex_get_save(lex, error);
-
- if(!l_isdigit(c)) {
- lex_unget_unsave(lex, c);
- goto out;
- }
-
- do
- c = lex_get_save(lex, error);
- while(l_isdigit(c));
- }
-
- lex_unget_unsave(lex, c);
-
- if(jsonp_strtod(&lex->saved_text, &doubleval)) {
- error_set(error, lex, "real number overflow");
- goto out;
- }
-
- lex->token = TOKEN_REAL;
- lex->value.real = doubleval;
- return 0;
-
-out:
- return -1;
-}
-
-static int lex_scan(lex_t *lex, json_error_t *error)
-{
- int c;
-
- strbuffer_clear(&lex->saved_text);
-
- if(lex->token == TOKEN_STRING)
- lex_free_string(lex);
-
- do
- c = lex_get(lex, error);
- while(c == ' ' || c == '\t' || c == '\n' || c == '\r');
-
- if(c == STREAM_STATE_EOF) {
- lex->token = TOKEN_EOF;
- goto out;
- }
-
- if(c == STREAM_STATE_ERROR) {
- lex->token = TOKEN_INVALID;
- goto out;
- }
-
- lex_save(lex, c);
-
- if(c == '{' || c == '}' || c == '[' || c == ']' || c == ':' || c == ',')
- lex->token = c;
-
- else if(c == '"')
- lex_scan_string(lex, error);
-
- else if(l_isdigit(c) || c == '-') {
- if(lex_scan_number(lex, c, error))
- goto out;
- }
-
- else if(l_isalpha(c)) {
- /* eat up the whole identifier for clearer error messages */
- const char *saved_text;
-
- do
- c = lex_get_save(lex, error);
- while(l_isalpha(c));
- lex_unget_unsave(lex, c);
-
- saved_text = strbuffer_value(&lex->saved_text);
-
- if(strcmp(saved_text, "true") == 0)
- lex->token = TOKEN_TRUE;
- else if(strcmp(saved_text, "false") == 0)
- lex->token = TOKEN_FALSE;
- else if(strcmp(saved_text, "null") == 0)
- lex->token = TOKEN_NULL;
- else
- lex->token = TOKEN_INVALID;
- }
-
- else {
- /* save the rest of the input UTF-8 sequence to get an error
- message of valid UTF-8 */
- lex_save_cached(lex);
- lex->token = TOKEN_INVALID;
- }
-
-out:
- return lex->token;
-}
-
-static char *lex_steal_string(lex_t *lex, size_t *out_len)
-{
- char *result = NULL;
- if(lex->token == TOKEN_STRING) {
- result = lex->value.string.val;
- *out_len = lex->value.string.len;
- lex->value.string.val = NULL;
- lex->value.string.len = 0;
- }
- return result;
-}
-
-static int lex_init(lex_t *lex, get_func get, size_t flags, void *data)
-{
- stream_init(&lex->stream, get, data);
- if(strbuffer_init(&lex->saved_text))
- return -1;
-
- lex->flags = flags;
- lex->token = TOKEN_INVALID;
- return 0;
-}
-
-static void lex_close(lex_t *lex)
-{
- if(lex->token == TOKEN_STRING)
- lex_free_string(lex);
- strbuffer_close(&lex->saved_text);
-}
-
-
-/*** parser ***/
-
-static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error);
-
-static json_t *parse_object(lex_t *lex, size_t flags, json_error_t *error)
-{
- json_t *object = json_object();
- if(!object)
- return NULL;
-
- lex_scan(lex, error);
- if(lex->token == '}')
- return object;
-
- while(1) {
- char *key;
- size_t len;
- json_t *value;
-
- if(lex->token != TOKEN_STRING) {
- error_set(error, lex, "string or '}' expected");
- goto error;
- }
-
- key = lex_steal_string(lex, &len);
- if(!key)
- return NULL;
- if (memchr(key, '\0', len)) {
- jsonp_free(key);
- error_set(error, lex, "NUL byte in object key not supported");
- goto error;
- }
-
- if(flags & JSON_REJECT_DUPLICATES) {
- if(json_object_get(object, key)) {
- jsonp_free(key);
- error_set(error, lex, "duplicate object key");
- goto error;
- }
- }
-
- lex_scan(lex, error);
- if(lex->token != ':') {
- jsonp_free(key);
- error_set(error, lex, "':' expected");
- goto error;
- }
-
- lex_scan(lex, error);
- value = parse_value(lex, flags, error);
- if(!value) {
- jsonp_free(key);
- goto error;
- }
-
- if(json_object_set_nocheck(object, key, value)) {
- jsonp_free(key);
- json_decref(value);
- goto error;
- }
-
- json_decref(value);
- jsonp_free(key);
-
- lex_scan(lex, error);
- if(lex->token != ',')
- break;
-
- lex_scan(lex, error);
- }
-
- if(lex->token != '}') {
- error_set(error, lex, "'}' expected");
- goto error;
- }
-
- return object;
-
-error:
- json_decref(object);
- return NULL;
-}
-
-static json_t *parse_array(lex_t *lex, size_t flags, json_error_t *error)
-{
- json_t *array = json_array();
- if(!array)
- return NULL;
-
- lex_scan(lex, error);
- if(lex->token == ']')
- return array;
-
- while(lex->token) {
- json_t *elem = parse_value(lex, flags, error);
- if(!elem)
- goto error;
-
- if(json_array_append(array, elem)) {
- json_decref(elem);
- goto error;
- }
- json_decref(elem);
-
- lex_scan(lex, error);
- if(lex->token != ',')
- break;
-
- lex_scan(lex, error);
- }
-
- if(lex->token != ']') {
- error_set(error, lex, "']' expected");
- goto error;
- }
-
- return array;
-
-error:
- json_decref(array);
- return NULL;
-}
-
-static json_t *parse_value(lex_t *lex, size_t flags, json_error_t *error)
-{
- json_t *json;
-
- lex->depth++;
- if(lex->depth > JSON_PARSER_MAX_DEPTH) {
- error_set(error, lex, "maximum parsing depth reached");
- return NULL;
- }
-
- switch(lex->token) {
- case TOKEN_STRING: {
- const char *value = lex->value.string.val;
- size_t len = lex->value.string.len;
-
- if(!(flags & JSON_ALLOW_NUL)) {
- if(memchr(value, '\0', len)) {
- error_set(error, lex, "\\u0000 is not allowed without JSON_ALLOW_NUL");
- return NULL;
- }
- }
-
- json = jsonp_stringn_nocheck_own(value, len);
- if(json) {
- lex->value.string.val = NULL;
- lex->value.string.len = 0;
- }
- break;
- }
-
- case TOKEN_INTEGER: {
- json = json_integer(lex->value.integer);
- break;
- }
-
- case TOKEN_REAL: {
- json = json_real(lex->value.real);
- break;
- }
-
- case TOKEN_TRUE:
- json = json_true();
- break;
-
- case TOKEN_FALSE:
- json = json_false();
- break;
-
- case TOKEN_NULL:
- json = json_null();
- break;
-
- case '{':
- json = parse_object(lex, flags, error);
- break;
-
- case '[':
- json = parse_array(lex, flags, error);
- break;
-
- case TOKEN_INVALID:
- error_set(error, lex, "invalid token");
- return NULL;
-
- default:
- error_set(error, lex, "unexpected token");
- return NULL;
- }
-
- if(!json)
- return NULL;
-
- lex->depth--;
- return json;
-}
-
-static json_t *parse_json(lex_t *lex, size_t flags, json_error_t *error)
-{
- json_t *result;
-
- lex->depth = 0;
-
- lex_scan(lex, error);
- if(!(flags & JSON_DECODE_ANY)) {
- if(lex->token != '[' && lex->token != '{') {
- error_set(error, lex, "'[' or '{' expected");
- return NULL;
- }
- }
-
- result = parse_value(lex, flags, error);
- if(!result)
- return NULL;
-
- if(!(flags & JSON_DISABLE_EOF_CHECK)) {
- lex_scan(lex, error);
- if(lex->token != TOKEN_EOF) {
- error_set(error, lex, "end of file expected");
- json_decref(result);
- return NULL;
- }
- }
-
- if(error) {
- /* Save the position even though there was no error */
- error->position = (int)lex->stream.position;
- }
-
- return result;
-}
-
-typedef struct
-{
- const char *data;
- size_t pos;
-} string_data_t;
-
-static int string_get(void *data)
-{
- char c;
- string_data_t *stream = (string_data_t *)data;
- c = stream->data[stream->pos];
- if(c == '\0')
- return EOF;
- else
- {
- stream->pos++;
- return (unsigned char)c;
- }
-}
-
-json_t *json_loads(const char *string, size_t flags, json_error_t *error)
-{
- lex_t lex;
- json_t *result;
- string_data_t stream_data;
-
- jsonp_error_init(error, "");
-
- if (string == NULL) {
- error_set(error, NULL, "wrong arguments");
- return NULL;
- }
-
- stream_data.data = string;
- stream_data.pos = 0;
-
- if(lex_init(&lex, string_get, flags, (void *)&stream_data))
- return NULL;
-
- result = parse_json(&lex, flags, error);
-
- lex_close(&lex);
- return result;
-}
-
-typedef struct
-{
- const char *data;
- size_t len;
- size_t pos;
-} buffer_data_t;
-
-static int buffer_get(void *data)
-{
- char c;
- buffer_data_t *stream = data;
- if(stream->pos >= stream->len)
- return EOF;
-
- c = stream->data[stream->pos];
- stream->pos++;
- return (unsigned char)c;
-}
-
-json_t *json_loadb(const char *buffer, size_t buflen, size_t flags, json_error_t *error)
-{
- lex_t lex;
- json_t *result;
- buffer_data_t stream_data;
-
- jsonp_error_init(error, "");
-
- if (buffer == NULL) {
- error_set(error, NULL, "wrong arguments");
- return NULL;
- }
-
- stream_data.data = buffer;
- stream_data.pos = 0;
- stream_data.len = buflen;
-
- if(lex_init(&lex, buffer_get, flags, (void *)&stream_data))
- return NULL;
-
- result = parse_json(&lex, flags, error);
-
- lex_close(&lex);
- return result;
-}
-
-json_t *json_loadf(FILE *input, size_t flags, json_error_t *error)
-{
- lex_t lex;
- const char *source;
- json_t *result;
-
- if(input == stdin)
- source = "";
- else
- source = "";
-
- jsonp_error_init(error, source);
-
- if (input == NULL) {
- error_set(error, NULL, "wrong arguments");
- return NULL;
- }
-
- if(lex_init(&lex, (get_func)fgetc, flags, input))
- return NULL;
-
- result = parse_json(&lex, flags, error);
-
- lex_close(&lex);
- return result;
-}
-
-static int fd_get_func(int *fd)
-{
-#ifdef HAVE_UNISTD_H
- uint8_t c;
- if (read(*fd, &c, 1) == 1)
- return c;
-#endif
- return EOF;
-}
-
-json_t *json_loadfd(int input, size_t flags, json_error_t *error)
-{
- lex_t lex;
- const char *source;
- json_t *result;
-
-#ifdef HAVE_UNISTD_H
- if(input == STDIN_FILENO)
- source = "";
- else
-#endif
- source = "";
-
- jsonp_error_init(error, source);
-
- if (input < 0) {
- error_set(error, NULL, "wrong arguments");
- return NULL;
- }
-
- if(lex_init(&lex, (get_func)fd_get_func, flags, &input))
- return NULL;
-
- result = parse_json(&lex, flags, error);
-
- lex_close(&lex);
- return result;
-}
-
-json_t *json_load_file(const char *path, size_t flags, json_error_t *error)
-{
- json_t *result;
- FILE *fp;
-
- jsonp_error_init(error, path);
-
- if (path == NULL) {
- error_set(error, NULL, "wrong arguments");
- return NULL;
- }
-
- fp = fopen(path, "rb");
- if(!fp)
- {
- error_set(error, NULL, "unable to open %s: %s",
- path, strerror(errno));
- return NULL;
- }
-
- result = json_loadf(fp, flags, error);
-
- fclose(fp);
- return result;
-}
-
-#define MAX_BUF_LEN 1024
-
-typedef struct
-{
- char data[MAX_BUF_LEN];
- size_t len;
- size_t pos;
- json_load_callback_t callback;
- void *arg;
-} callback_data_t;
-
-static int callback_get(void *data)
-{
- char c;
- callback_data_t *stream = data;
-
- if(stream->pos >= stream->len) {
- stream->pos = 0;
- stream->len = stream->callback(stream->data, MAX_BUF_LEN, stream->arg);
- if(stream->len == 0 || stream->len == (size_t)-1)
- return EOF;
- }
-
- c = stream->data[stream->pos];
- stream->pos++;
- return (unsigned char)c;
-}
-
-json_t *json_load_callback(json_load_callback_t callback, void *arg, size_t flags, json_error_t *error)
-{
- lex_t lex;
- json_t *result;
-
- callback_data_t stream_data;
-
- memset(&stream_data, 0, sizeof(stream_data));
- stream_data.callback = callback;
- stream_data.arg = arg;
-
- jsonp_error_init(error, "");
-
- if (callback == NULL) {
- error_set(error, NULL, "wrong arguments");
- return NULL;
- }
-
- if(lex_init(&lex, (get_func)callback_get, flags, &stream_data))
- return NULL;
-
- result = parse_json(&lex, flags, error);
-
- lex_close(&lex);
- return result;
-}
diff --git a/src/3rdparty/jansson/lookup3.h b/src/3rdparty/jansson/lookup3.h
deleted file mode 100644
index 522a41ae..00000000
--- a/src/3rdparty/jansson/lookup3.h
+++ /dev/null
@@ -1,381 +0,0 @@
-/*
--------------------------------------------------------------------------------
-lookup3.c, by Bob Jenkins, May 2006, Public Domain.
-
-These are functions for producing 32-bit hashes for hash table lookup.
-hashword(), hashlittle(), hashlittle2(), hashbig(), mix(), and final()
-are externally useful functions. Routines to test the hash are included
-if SELF_TEST is defined. You can use this free for any purpose. It's in
-the public domain. It has no warranty.
-
-You probably want to use hashlittle(). hashlittle() and hashbig()
-hash byte arrays. hashlittle() is is faster than hashbig() on
-little-endian machines. Intel and AMD are little-endian machines.
-On second thought, you probably want hashlittle2(), which is identical to
-hashlittle() except it returns two 32-bit hashes for the price of one.
-You could implement hashbig2() if you wanted but I haven't bothered here.
-
-If you want to find a hash of, say, exactly 7 integers, do
- a = i1; b = i2; c = i3;
- mix(a,b,c);
- a += i4; b += i5; c += i6;
- mix(a,b,c);
- a += i7;
- final(a,b,c);
-then use c as the hash value. If you have a variable length array of
-4-byte integers to hash, use hashword(). If you have a byte array (like
-a character string), use hashlittle(). If you have several byte arrays, or
-a mix of things, see the comments above hashlittle().
-
-Why is this so big? I read 12 bytes at a time into 3 4-byte integers,
-then mix those integers. This is fast (you can do a lot more thorough
-mixing with 12*3 instructions on 3 integers than you can with 3 instructions
-on 1 byte), but shoehorning those bytes into integers efficiently is messy.
--------------------------------------------------------------------------------
-*/
-
-#include
-
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-
-#ifdef HAVE_STDINT_H
-#include /* defines uint32_t etc */
-#endif
-
-#ifdef HAVE_SYS_PARAM_H
-#include /* attempt to define endianness */
-#endif
-
-#ifdef HAVE_ENDIAN_H
-# include /* attempt to define endianness */
-#endif
-
-/*
- * My best guess at if you are big-endian or little-endian. This may
- * need adjustment.
- */
-#if (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && \
- __BYTE_ORDER == __LITTLE_ENDIAN) || \
- (defined(i386) || defined(__i386__) || defined(__i486__) || \
- defined(__i586__) || defined(__i686__) || defined(vax) || defined(MIPSEL))
-# define HASH_LITTLE_ENDIAN 1
-# define HASH_BIG_ENDIAN 0
-#elif (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && \
- __BYTE_ORDER == __BIG_ENDIAN) || \
- (defined(sparc) || defined(POWERPC) || defined(mc68000) || defined(sel))
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 1
-#else
-# define HASH_LITTLE_ENDIAN 0
-# define HASH_BIG_ENDIAN 0
-#endif
-
-#define hashsize(n) ((uint32_t)1<<(n))
-#define hashmask(n) (hashsize(n)-1)
-#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
-
-/*
--------------------------------------------------------------------------------
-mix -- mix 3 32-bit values reversibly.
-
-This is reversible, so any information in (a,b,c) before mix() is
-still in (a,b,c) after mix().
-
-If four pairs of (a,b,c) inputs are run through mix(), or through
-mix() in reverse, there are at least 32 bits of the output that
-are sometimes the same for one pair and different for another pair.
-This was tested for:
-* pairs that differed by one bit, by two bits, in any combination
- of top bits of (a,b,c), or in any combination of bottom bits of
- (a,b,c).
-* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
- the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
- is commonly produced by subtraction) look like a single 1-bit
- difference.
-* the base values were pseudorandom, all zero but one bit set, or
- all zero plus a counter that starts at zero.
-
-Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that
-satisfy this are
- 4 6 8 16 19 4
- 9 15 3 18 27 15
- 14 9 3 7 17 3
-Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing
-for "differ" defined as + with a one-bit base and a two-bit delta. I
-used http://burtleburtle.net/bob/hash/avalanche.html to choose
-the operations, constants, and arrangements of the variables.
-
-This does not achieve avalanche. There are input bits of (a,b,c)
-that fail to affect some output bits of (a,b,c), especially of a. The
-most thoroughly mixed value is c, but it doesn't really even achieve
-avalanche in c.
-
-This allows some parallelism. Read-after-writes are good at doubling
-the number of bits affected, so the goal of mixing pulls in the opposite
-direction as the goal of parallelism. I did what I could. Rotates
-seem to cost as much as shifts on every machine I could lay my hands
-on, and rotates are much kinder to the top and bottom bits, so I used
-rotates.
--------------------------------------------------------------------------------
-*/
-#define mix(a,b,c) \
-{ \
- a -= c; a ^= rot(c, 4); c += b; \
- b -= a; b ^= rot(a, 6); a += c; \
- c -= b; c ^= rot(b, 8); b += a; \
- a -= c; a ^= rot(c,16); c += b; \
- b -= a; b ^= rot(a,19); a += c; \
- c -= b; c ^= rot(b, 4); b += a; \
-}
-
-/*
--------------------------------------------------------------------------------
-final -- final mixing of 3 32-bit values (a,b,c) into c
-
-Pairs of (a,b,c) values differing in only a few bits will usually
-produce values of c that look totally different. This was tested for
-* pairs that differed by one bit, by two bits, in any combination
- of top bits of (a,b,c), or in any combination of bottom bits of
- (a,b,c).
-* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed
- the output delta to a Gray code (a^(a>>1)) so a string of 1's (as
- is commonly produced by subtraction) look like a single 1-bit
- difference.
-* the base values were pseudorandom, all zero but one bit set, or
- all zero plus a counter that starts at zero.
-
-These constants passed:
- 14 11 25 16 4 14 24
- 12 14 25 16 4 14 24
-and these came close:
- 4 8 15 26 3 22 24
- 10 8 15 26 3 22 24
- 11 8 15 26 3 22 24
--------------------------------------------------------------------------------
-*/
-#define final(a,b,c) \
-{ \
- c ^= b; c -= rot(b,14); \
- a ^= c; a -= rot(c,11); \
- b ^= a; b -= rot(a,25); \
- c ^= b; c -= rot(b,16); \
- a ^= c; a -= rot(c,4); \
- b ^= a; b -= rot(a,14); \
- c ^= b; c -= rot(b,24); \
-}
-
-/*
--------------------------------------------------------------------------------
-hashlittle() -- hash a variable-length key into a 32-bit value
- k : the key (the unaligned variable-length array of bytes)
- length : the length of the key, counting by bytes
- initval : can be any 4-byte value
-Returns a 32-bit value. Every bit of the key affects every bit of
-the return value. Two keys differing by one or two bits will have
-totally different hash values.
-
-The best hash table sizes are powers of 2. There is no need to do
-mod a prime (mod is sooo slow!). If you need less than 32 bits,
-use a bitmask. For example, if you need only 10 bits, do
- h = (h & hashmask(10));
-In which case, the hash table should have hashsize(10) elements.
-
-If you are hashing n strings (uint8_t **)k, do it like this:
- for (i=0, h=0; i 12)
- {
- a += k[0];
- b += k[1];
- c += k[2];
- mix(a,b,c);
- length -= 12;
- k += 3;
- }
-
- /*----------------------------- handle the last (probably partial) block */
- /*
- * "k[2]&0xffffff" actually reads beyond the end of the string, but
- * then masks off the part it's not allowed to read. Because the
- * string is aligned, the masked-off tail is in the same word as the
- * rest of the string. Every machine with memory protection I've seen
- * does it on word boundaries, so is OK with this. But VALGRIND will
- * still catch it and complain. The masking trick does make the hash
- * noticably faster for short strings (like English words).
- */
-#ifndef NO_MASKING_TRICK
-
- switch(length)
- {
- case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break;
- case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break;
- case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break;
- case 8 : b+=k[1]; a+=k[0]; break;
- case 7 : b+=k[1]&0xffffff; a+=k[0]; break;
- case 6 : b+=k[1]&0xffff; a+=k[0]; break;
- case 5 : b+=k[1]&0xff; a+=k[0]; break;
- case 4 : a+=k[0]; break;
- case 3 : a+=k[0]&0xffffff; break;
- case 2 : a+=k[0]&0xffff; break;
- case 1 : a+=k[0]&0xff; break;
- case 0 : return c; /* zero length strings require no mixing */
- }
-
-#else /* make valgrind happy */
-
- k8 = (const uint8_t *)k;
- switch(length)
- {
- case 12: c+=k[2]; b+=k[1]; a+=k[0]; break;
- case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
- case 10: c+=((uint32_t)k8[9])<<8; /* fall through */
- case 9 : c+=k8[8]; /* fall through */
- case 8 : b+=k[1]; a+=k[0]; break;
- case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
- case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */
- case 5 : b+=k8[4]; /* fall through */
- case 4 : a+=k[0]; break;
- case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
- case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */
- case 1 : a+=k8[0]; break;
- case 0 : return c;
- }
-
-#endif /* !valgrind */
-
- } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) {
- const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */
- const uint8_t *k8;
-
- /*--------------- all but last block: aligned reads and different mixing */
- while (length > 12)
- {
- a += k[0] + (((uint32_t)k[1])<<16);
- b += k[2] + (((uint32_t)k[3])<<16);
- c += k[4] + (((uint32_t)k[5])<<16);
- mix(a,b,c);
- length -= 12;
- k += 6;
- }
-
- /*----------------------------- handle the last (probably partial) block */
- k8 = (const uint8_t *)k;
- switch(length)
- {
- case 12: c+=k[4]+(((uint32_t)k[5])<<16);
- b+=k[2]+(((uint32_t)k[3])<<16);
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 11: c+=((uint32_t)k8[10])<<16; /* fall through */
- case 10: c+=k[4];
- b+=k[2]+(((uint32_t)k[3])<<16);
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 9 : c+=k8[8]; /* fall through */
- case 8 : b+=k[2]+(((uint32_t)k[3])<<16);
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */
- case 6 : b+=k[2];
- a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 5 : b+=k8[4]; /* fall through */
- case 4 : a+=k[0]+(((uint32_t)k[1])<<16);
- break;
- case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */
- case 2 : a+=k[0];
- break;
- case 1 : a+=k8[0];
- break;
- case 0 : return c; /* zero length requires no mixing */
- }
-
- } else { /* need to read the key one byte at a time */
- const uint8_t *k = (const uint8_t *)key;
-
- /*--------------- all but the last block: affect some 32 bits of (a,b,c) */
- while (length > 12)
- {
- a += k[0];
- a += ((uint32_t)k[1])<<8;
- a += ((uint32_t)k[2])<<16;
- a += ((uint32_t)k[3])<<24;
- b += k[4];
- b += ((uint32_t)k[5])<<8;
- b += ((uint32_t)k[6])<<16;
- b += ((uint32_t)k[7])<<24;
- c += k[8];
- c += ((uint32_t)k[9])<<8;
- c += ((uint32_t)k[10])<<16;
- c += ((uint32_t)k[11])<<24;
- mix(a,b,c);
- length -= 12;
- k += 12;
- }
-
- /*-------------------------------- last block: affect all 32 bits of (c) */
- switch(length) /* all the case statements fall through */
- {
- case 12: c+=((uint32_t)k[11])<<24;
- case 11: c+=((uint32_t)k[10])<<16;
- case 10: c+=((uint32_t)k[9])<<8;
- case 9 : c+=k[8];
- case 8 : b+=((uint32_t)k[7])<<24;
- case 7 : b+=((uint32_t)k[6])<<16;
- case 6 : b+=((uint32_t)k[5])<<8;
- case 5 : b+=k[4];
- case 4 : a+=((uint32_t)k[3])<<24;
- case 3 : a+=((uint32_t)k[2])<<16;
- case 2 : a+=((uint32_t)k[1])<<8;
- case 1 : a+=k[0];
- break;
- case 0 : return c;
- }
- }
-
- final(a,b,c);
- return c;
-}
diff --git a/src/3rdparty/jansson/memory.c b/src/3rdparty/jansson/memory.c
deleted file mode 100644
index a2be5d23..00000000
--- a/src/3rdparty/jansson/memory.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- * Copyright (c) 2011-2012 Basile Starynkevitch
- *
- * Jansson is free software; you can redistribute it and/or modify it
- * under the terms of the MIT license. See LICENSE for details.
- */
-
-#include
-#include
-
-#include "jansson.h"
-#include "jansson_private.h"
-
-/* C89 allows these to be macros */
-#undef malloc
-#undef free
-
-/* memory function pointers */
-static json_malloc_t do_malloc = malloc;
-static json_free_t do_free = free;
-
-void *jsonp_malloc(size_t size)
-{
- if(!size)
- return NULL;
-
- return (*do_malloc)(size);
-}
-
-void jsonp_free(void *ptr)
-{
- if(!ptr)
- return;
-
- (*do_free)(ptr);
-}
-
-char *jsonp_strdup(const char *str)
-{
- return jsonp_strndup(str, strlen(str));
-}
-
-char *jsonp_strndup(const char *str, size_t len)
-{
- char *new_str;
-
- new_str = jsonp_malloc(len + 1);
- if(!new_str)
- return NULL;
-
- memcpy(new_str, str, len);
- new_str[len] = '\0';
- return new_str;
-}
-
-void json_set_alloc_funcs(json_malloc_t malloc_fn, json_free_t free_fn)
-{
- do_malloc = malloc_fn;
- do_free = free_fn;
-}
-
-void json_get_alloc_funcs(json_malloc_t *malloc_fn, json_free_t *free_fn)
-{
- if (malloc_fn)
- *malloc_fn = do_malloc;
- if (free_fn)
- *free_fn = do_free;
-}
diff --git a/src/3rdparty/jansson/pack_unpack.c b/src/3rdparty/jansson/pack_unpack.c
deleted file mode 100644
index 2a2da353..00000000
--- a/src/3rdparty/jansson/pack_unpack.c
+++ /dev/null
@@ -1,871 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- * Copyright (c) 2011-2012 Graeme Smecher
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include
-#include "jansson.h"
-#include "jansson_private.h"
-#include "utf.h"
-
-typedef struct {
- int line;
- int column;
- size_t pos;
- char token;
-} token_t;
-
-typedef struct {
- const char *start;
- const char *fmt;
- token_t prev_token;
- token_t token;
- token_t next_token;
- json_error_t *error;
- size_t flags;
- int line;
- int column;
- size_t pos;
-} scanner_t;
-
-#define token(scanner) ((scanner)->token.token)
-
-static const char * const type_names[] = {
- "object",
- "array",
- "string",
- "integer",
- "real",
- "true",
- "false",
- "null"
-};
-
-#define type_name(x) type_names[json_typeof(x)]
-
-static const char unpack_value_starters[] = "{[siIbfFOon";
-
-static void scanner_init(scanner_t *s, json_error_t *error,
- size_t flags, const char *fmt)
-{
- s->error = error;
- s->flags = flags;
- s->fmt = s->start = fmt;
- memset(&s->prev_token, 0, sizeof(token_t));
- memset(&s->token, 0, sizeof(token_t));
- memset(&s->next_token, 0, sizeof(token_t));
- s->line = 1;
- s->column = 0;
- s->pos = 0;
-}
-
-static void next_token(scanner_t *s)
-{
- const char *t;
- s->prev_token = s->token;
-
- if(s->next_token.line) {
- s->token = s->next_token;
- s->next_token.line = 0;
- return;
- }
-
- t = s->fmt;
- s->column++;
- s->pos++;
-
- /* skip space and ignored chars */
- while(*t == ' ' || *t == '\t' || *t == '\n' || *t == ',' || *t == ':') {
- if(*t == '\n') {
- s->line++;
- s->column = 1;
- }
- else
- s->column++;
-
- s->pos++;
- t++;
- }
-
- s->token.token = *t;
- s->token.line = s->line;
- s->token.column = s->column;
- s->token.pos = s->pos;
-
- t++;
- s->fmt = t;
-}
-
-static void prev_token(scanner_t *s)
-{
- s->next_token = s->token;
- s->token = s->prev_token;
-}
-
-static void set_error(scanner_t *s, const char *source, const char *fmt, ...)
-{
- va_list ap;
- va_start(ap, fmt);
-
- jsonp_error_vset(s->error, s->token.line, s->token.column, s->token.pos,
- fmt, ap);
-
- jsonp_error_set_source(s->error, source);
-
- va_end(ap);
-}
-
-static json_t *pack(scanner_t *s, va_list *ap);
-
-
-/* ours will be set to 1 if jsonp_free() must be called for the result
- afterwards */
-static char *read_string(scanner_t *s, va_list *ap,
- const char *purpose, size_t *out_len, int *ours)
-{
- char t;
- strbuffer_t strbuff;
- const char *str;
- size_t length;
-
- next_token(s);
- t = token(s);
- prev_token(s);
-
- if(t != '#' && t != '%' && t != '+') {
- /* Optimize the simple case */
- str = va_arg(*ap, const char *);
-
- if(!str) {
- set_error(s, "", "NULL string argument");
- return NULL;
- }
-
- length = strlen(str);
-
- if(!utf8_check_string(str, length)) {
- set_error(s, "", "Invalid UTF-8 %s", purpose);
- return NULL;
- }
-
- *out_len = length;
- *ours = 0;
- return (char *)str;
- }
-
- strbuffer_init(&strbuff);
-
- while(1) {
- str = va_arg(*ap, const char *);
- if(!str) {
- set_error(s, "", "NULL string argument");
- strbuffer_close(&strbuff);
- return NULL;
- }
-
- next_token(s);
-
- if(token(s) == '#') {
- length = va_arg(*ap, int);
- }
- else if(token(s) == '%') {
- length = va_arg(*ap, size_t);
- }
- else {
- prev_token(s);
- length = strlen(str);
- }
-
- if(strbuffer_append_bytes(&strbuff, str, length) == -1) {
- set_error(s, "", "Out of memory");
- strbuffer_close(&strbuff);
- return NULL;
- }
-
- next_token(s);
- if(token(s) != '+') {
- prev_token(s);
- break;
- }
- }
-
- if(!utf8_check_string(strbuff.value, strbuff.length)) {
- set_error(s, "", "Invalid UTF-8 %s", purpose);
- strbuffer_close(&strbuff);
- return NULL;
- }
-
- *out_len = strbuff.length;
- *ours = 1;
- return strbuffer_steal_value(&strbuff);
-}
-
-static json_t *pack_object(scanner_t *s, va_list *ap)
-{
- json_t *object = json_object();
- next_token(s);
-
- while(token(s) != '}') {
- char *key;
- size_t len;
- int ours;
- json_t *value;
-
- if(!token(s)) {
- set_error(s, "", "Unexpected end of format string");
- goto error;
- }
-
- if(token(s) != 's') {
- set_error(s, "", "Expected format 's', got '%c'", token(s));
- goto error;
- }
-
- key = read_string(s, ap, "object key", &len, &ours);
- if(!key)
- goto error;
-
- next_token(s);
-
- value = pack(s, ap);
- if(!value) {
- if(ours)
- jsonp_free(key);
-
- goto error;
- }
-
- if(json_object_set_new_nocheck(object, key, value)) {
- set_error(s, "", "Unable to add key \"%s\"", key);
- if(ours)
- jsonp_free(key);
-
- goto error;
- }
-
- if(ours)
- jsonp_free(key);
-
- next_token(s);
- }
-
- return object;
-
-error:
- json_decref(object);
- return NULL;
-}
-
-static json_t *pack_array(scanner_t *s, va_list *ap)
-{
- json_t *array = json_array();
- next_token(s);
-
- while(token(s) != ']') {
- json_t *value;
-
- if(!token(s)) {
- set_error(s, "", "Unexpected end of format string");
- goto error;
- }
-
- value = pack(s, ap);
- if(!value)
- goto error;
-
- if(json_array_append_new(array, value)) {
- set_error(s, "", "Unable to append to array");
- goto error;
- }
-
- next_token(s);
- }
- return array;
-
-error:
- json_decref(array);
- return NULL;
-}
-
-static json_t *pack_string(scanner_t *s, va_list *ap)
-{
- char *str;
- size_t len;
- int ours;
- int nullable;
-
- next_token(s);
- nullable = token(s) == '?';
- if (!nullable)
- prev_token(s);
-
- str = read_string(s, ap, "string", &len, &ours);
- if (!str) {
- return nullable ? json_null() : NULL;
- } else if (ours) {
- return jsonp_stringn_nocheck_own(str, len);
- } else {
- return json_stringn_nocheck(str, len);
- }
-}
-
-static json_t *pack(scanner_t *s, va_list *ap)
-{
- switch(token(s)) {
- case '{':
- return pack_object(s, ap);
-
- case '[':
- return pack_array(s, ap);
-
- case 's': /* string */
- return pack_string(s, ap);
-
- case 'n': /* null */
- return json_null();
-
- case 'b': /* boolean */
- return va_arg(*ap, int) ? json_true() : json_false();
-
- case 'i': /* integer from int */
- return json_integer(va_arg(*ap, int));
-
- case 'I': /* integer from json_int_t */
- return json_integer(va_arg(*ap, json_int_t));
-
- case 'f': /* real */
- return json_real(va_arg(*ap, double));
-
- case 'O': /* a json_t object; increments refcount */
- {
- int nullable;
- json_t *json;
-
- next_token(s);
- nullable = token(s) == '?';
- if (!nullable)
- prev_token(s);
-
- json = va_arg(*ap, json_t *);
- if (!json && nullable) {
- return json_null();
- } else {
- return json_incref(json);
- }
- }
-
- case 'o': /* a json_t object; doesn't increment refcount */
- {
- int nullable;
- json_t *json;
-
- next_token(s);
- nullable = token(s) == '?';
- if (!nullable)
- prev_token(s);
-
- json = va_arg(*ap, json_t *);
- if (!json && nullable) {
- return json_null();
- } else {
- return json;
- }
- }
-
- default:
- set_error(s, "", "Unexpected format character '%c'",
- token(s));
- return NULL;
- }
-}
-
-static int unpack(scanner_t *s, json_t *root, va_list *ap);
-
-static int unpack_object(scanner_t *s, json_t *root, va_list *ap)
-{
- int ret = -1;
- int strict = 0;
- int gotopt = 0;
-
- /* Use a set (emulated by a hashtable) to check that all object
- keys are accessed. Checking that the correct number of keys
- were accessed is not enough, as the same key can be unpacked
- multiple times.
- */
- hashtable_t key_set;
-
- if(hashtable_init(&key_set)) {
- set_error(s, "", "Out of memory");
- return -1;
- }
-
- if(root && !json_is_object(root)) {
- set_error(s, "", "Expected object, got %s",
- type_name(root));
- goto out;
- }
- next_token(s);
-
- while(token(s) != '}') {
- const char *key;
- json_t *value;
- int opt = 0;
-
- if(strict != 0) {
- set_error(s, "", "Expected '}' after '%c', got '%c'",
- (strict == 1 ? '!' : '*'), token(s));
- goto out;
- }
-
- if(!token(s)) {
- set_error(s, "", "Unexpected end of format string");
- goto out;
- }
-
- if(token(s) == '!' || token(s) == '*') {
- strict = (token(s) == '!' ? 1 : -1);
- next_token(s);
- continue;
- }
-
- if(token(s) != 's') {
- set_error(s, "", "Expected format 's', got '%c'", token(s));
- goto out;
- }
-
- key = va_arg(*ap, const char *);
- if(!key) {
- set_error(s, "", "NULL object key");
- goto out;
- }
-
- next_token(s);
-
- if(token(s) == '?') {
- opt = gotopt = 1;
- next_token(s);
- }
-
- if(!root) {
- /* skipping */
- value = NULL;
- }
- else {
- value = json_object_get(root, key);
- if(!value && !opt) {
- set_error(s, "", "Object item not found: %s", key);
- goto out;
- }
- }
-
- if(unpack(s, value, ap))
- goto out;
-
- hashtable_set(&key_set, key, json_null());
- next_token(s);
- }
-
- if(strict == 0 && (s->flags & JSON_STRICT))
- strict = 1;
-
- if(root && strict == 1) {
- /* We need to check that all non optional items have been parsed */
- const char *key;
- int have_unrecognized_keys = 0;
- strbuffer_t unrecognized_keys;
- json_t *value;
- long unpacked = 0;
- if (gotopt) {
- /* We have optional keys, we need to iter on each key */
- json_object_foreach(root, key, value) {
- if(!hashtable_get(&key_set, key)) {
- unpacked++;
-
- /* Save unrecognized keys for the error message */
- if (!have_unrecognized_keys) {
- strbuffer_init(&unrecognized_keys);
- have_unrecognized_keys = 1;
- } else {
- strbuffer_append_bytes(&unrecognized_keys, ", ", 2);
- }
- strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));
- }
- }
- } else {
- /* No optional keys, we can just compare the number of items */
- unpacked = (long)json_object_size(root) - (long)key_set.size;
- }
- if (unpacked) {
- if (!gotopt) {
- /* Save unrecognized keys for the error message */
- json_object_foreach(root, key, value) {
- if(!hashtable_get(&key_set, key)) {
- if (!have_unrecognized_keys) {
- strbuffer_init(&unrecognized_keys);
- have_unrecognized_keys = 1;
- } else {
- strbuffer_append_bytes(&unrecognized_keys, ", ", 2);
- }
- strbuffer_append_bytes(&unrecognized_keys, key, strlen(key));
- }
- }
- }
- set_error(s, "",
- "%li object item(s) left unpacked: %s",
- unpacked, strbuffer_value(&unrecognized_keys));
- strbuffer_close(&unrecognized_keys);
- goto out;
- }
- }
-
- ret = 0;
-
-out:
- hashtable_close(&key_set);
- return ret;
-}
-
-static int unpack_array(scanner_t *s, json_t *root, va_list *ap)
-{
- size_t i = 0;
- int strict = 0;
-
- if(root && !json_is_array(root)) {
- set_error(s, "", "Expected array, got %s", type_name(root));
- return -1;
- }
- next_token(s);
-
- while(token(s) != ']') {
- json_t *value;
-
- if(strict != 0) {
- set_error(s, "", "Expected ']' after '%c', got '%c'",
- (strict == 1 ? '!' : '*'),
- token(s));
- return -1;
- }
-
- if(!token(s)) {
- set_error(s, "", "Unexpected end of format string");
- return -1;
- }
-
- if(token(s) == '!' || token(s) == '*') {
- strict = (token(s) == '!' ? 1 : -1);
- next_token(s);
- continue;
- }
-
- if(!strchr(unpack_value_starters, token(s))) {
- set_error(s, "", "Unexpected format character '%c'",
- token(s));
- return -1;
- }
-
- if(!root) {
- /* skipping */
- value = NULL;
- }
- else {
- value = json_array_get(root, i);
- if(!value) {
- set_error(s, "", "Array index %lu out of range",
- (unsigned long)i);
- return -1;
- }
- }
-
- if(unpack(s, value, ap))
- return -1;
-
- next_token(s);
- i++;
- }
-
- if(strict == 0 && (s->flags & JSON_STRICT))
- strict = 1;
-
- if(root && strict == 1 && i != json_array_size(root)) {
- long diff = (long)json_array_size(root) - (long)i;
- set_error(s, "", "%li array item(s) left unpacked", diff);
- return -1;
- }
-
- return 0;
-}
-
-static int unpack(scanner_t *s, json_t *root, va_list *ap)
-{
- switch(token(s))
- {
- case '{':
- return unpack_object(s, root, ap);
-
- case '[':
- return unpack_array(s, root, ap);
-
- case 's':
- if(root && !json_is_string(root)) {
- set_error(s, "", "Expected string, got %s",
- type_name(root));
- return -1;
- }
-
- if(!(s->flags & JSON_VALIDATE_ONLY)) {
- const char **str_target;
- size_t *len_target = NULL;
-
- str_target = va_arg(*ap, const char **);
- if(!str_target) {
- set_error(s, "", "NULL string argument");
- return -1;
- }
-
- next_token(s);
-
- if(token(s) == '%') {
- len_target = va_arg(*ap, size_t *);
- if(!len_target) {
- set_error(s, "", "NULL string length argument");
- return -1;
- }
- }
- else
- prev_token(s);
-
- if(root) {
- *str_target = json_string_value(root);
- if(len_target)
- *len_target = json_string_length(root);
- }
- }
- return 0;
-
- case 'i':
- if(root && !json_is_integer(root)) {
- set_error(s, "", "Expected integer, got %s",
- type_name(root));
- return -1;
- }
-
- if(!(s->flags & JSON_VALIDATE_ONLY)) {
- int *target = va_arg(*ap, int*);
- if(root)
- *target = (int)json_integer_value(root);
- }
-
- return 0;
-
- case 'I':
- if(root && !json_is_integer(root)) {
- set_error(s, "", "Expected integer, got %s",
- type_name(root));
- return -1;
- }
-
- if(!(s->flags & JSON_VALIDATE_ONLY)) {
- json_int_t *target = va_arg(*ap, json_int_t*);
- if(root)
- *target = json_integer_value(root);
- }
-
- return 0;
-
- case 'b':
- if(root && !json_is_boolean(root)) {
- set_error(s, "", "Expected true or false, got %s",
- type_name(root));
- return -1;
- }
-
- if(!(s->flags & JSON_VALIDATE_ONLY)) {
- int *target = va_arg(*ap, int*);
- if(root)
- *target = json_is_true(root);
- }
-
- return 0;
-
- case 'f':
- if(root && !json_is_real(root)) {
- set_error(s, "", "Expected real, got %s",
- type_name(root));
- return -1;
- }
-
- if(!(s->flags & JSON_VALIDATE_ONLY)) {
- double *target = va_arg(*ap, double*);
- if(root)
- *target = json_real_value(root);
- }
-
- return 0;
-
- case 'F':
- if(root && !json_is_number(root)) {
- set_error(s, "", "Expected real or integer, got %s",
- type_name(root));
- return -1;
- }
-
- if(!(s->flags & JSON_VALIDATE_ONLY)) {
- double *target = va_arg(*ap, double*);
- if(root)
- *target = json_number_value(root);
- }
-
- return 0;
-
- case 'O':
- if(root && !(s->flags & JSON_VALIDATE_ONLY))
- json_incref(root);
- /* Fall through */
-
- case 'o':
- if(!(s->flags & JSON_VALIDATE_ONLY)) {
- json_t **target = va_arg(*ap, json_t**);
- if(root)
- *target = root;
- }
-
- return 0;
-
- case 'n':
- /* Never assign, just validate */
- if(root && !json_is_null(root)) {
- set_error(s, "", "Expected null, got %s",
- type_name(root));
- return -1;
- }
- return 0;
-
- default:
- set_error(s, "", "Unexpected format character '%c'",
- token(s));
- return -1;
- }
-}
-
-json_t *json_vpack_ex(json_error_t *error, size_t flags,
- const char *fmt, va_list ap)
-{
- scanner_t s;
- va_list ap_copy;
- json_t *value;
-
- if(!fmt || !*fmt) {
- jsonp_error_init(error, "");
- jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
- return NULL;
- }
- jsonp_error_init(error, NULL);
-
- scanner_init(&s, error, flags, fmt);
- next_token(&s);
-
- va_copy(ap_copy, ap);
- value = pack(&s, &ap_copy);
- va_end(ap_copy);
-
- if(!value)
- return NULL;
-
- next_token(&s);
- if(token(&s)) {
- json_decref(value);
- set_error(&s, "", "Garbage after format string");
- return NULL;
- }
-
- return value;
-}
-
-json_t *json_pack_ex(json_error_t *error, size_t flags, const char *fmt, ...)
-{
- json_t *value;
- va_list ap;
-
- va_start(ap, fmt);
- value = json_vpack_ex(error, flags, fmt, ap);
- va_end(ap);
-
- return value;
-}
-
-json_t *json_pack(const char *fmt, ...)
-{
- json_t *value;
- va_list ap;
-
- va_start(ap, fmt);
- value = json_vpack_ex(NULL, 0, fmt, ap);
- va_end(ap);
-
- return value;
-}
-
-int json_vunpack_ex(json_t *root, json_error_t *error, size_t flags,
- const char *fmt, va_list ap)
-{
- scanner_t s;
- va_list ap_copy;
-
- if(!root) {
- jsonp_error_init(error, "");
- jsonp_error_set(error, -1, -1, 0, "NULL root value");
- return -1;
- }
-
- if(!fmt || !*fmt) {
- jsonp_error_init(error, "");
- jsonp_error_set(error, -1, -1, 0, "NULL or empty format string");
- return -1;
- }
- jsonp_error_init(error, NULL);
-
- scanner_init(&s, error, flags, fmt);
- next_token(&s);
-
- va_copy(ap_copy, ap);
- if(unpack(&s, root, &ap_copy)) {
- va_end(ap_copy);
- return -1;
- }
- va_end(ap_copy);
-
- next_token(&s);
- if(token(&s)) {
- set_error(&s, "", "Garbage after format string");
- return -1;
- }
-
- return 0;
-}
-
-int json_unpack_ex(json_t *root, json_error_t *error, size_t flags, const char *fmt, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = json_vunpack_ex(root, error, flags, fmt, ap);
- va_end(ap);
-
- return ret;
-}
-
-int json_unpack(json_t *root, const char *fmt, ...)
-{
- int ret;
- va_list ap;
-
- va_start(ap, fmt);
- ret = json_vunpack_ex(root, NULL, 0, fmt, ap);
- va_end(ap);
-
- return ret;
-}
diff --git a/src/3rdparty/jansson/strbuffer.c b/src/3rdparty/jansson/strbuffer.c
deleted file mode 100644
index 5e8c0039..00000000
--- a/src/3rdparty/jansson/strbuffer.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#include
-#include
-#include "jansson_private.h"
-#include "strbuffer.h"
-
-#define STRBUFFER_MIN_SIZE 16
-#define STRBUFFER_FACTOR 2
-#define STRBUFFER_SIZE_MAX ((size_t)-1)
-
-int strbuffer_init(strbuffer_t *strbuff)
-{
- strbuff->size = STRBUFFER_MIN_SIZE;
- strbuff->length = 0;
-
- strbuff->value = jsonp_malloc(strbuff->size);
- if(!strbuff->value)
- return -1;
-
- /* initialize to empty */
- strbuff->value[0] = '\0';
- return 0;
-}
-
-void strbuffer_close(strbuffer_t *strbuff)
-{
- if(strbuff->value)
- jsonp_free(strbuff->value);
-
- strbuff->size = 0;
- strbuff->length = 0;
- strbuff->value = NULL;
-}
-
-void strbuffer_clear(strbuffer_t *strbuff)
-{
- strbuff->length = 0;
- strbuff->value[0] = '\0';
-}
-
-const char *strbuffer_value(const strbuffer_t *strbuff)
-{
- return strbuff->value;
-}
-
-char *strbuffer_steal_value(strbuffer_t *strbuff)
-{
- char *result = strbuff->value;
- strbuff->value = NULL;
- return result;
-}
-
-int strbuffer_append_byte(strbuffer_t *strbuff, char byte)
-{
- return strbuffer_append_bytes(strbuff, &byte, 1);
-}
-
-int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size)
-{
- if(size >= strbuff->size - strbuff->length)
- {
- size_t new_size;
- char *new_value;
-
- /* avoid integer overflow */
- if (strbuff->size > STRBUFFER_SIZE_MAX / STRBUFFER_FACTOR
- || size > STRBUFFER_SIZE_MAX - 1
- || strbuff->length > STRBUFFER_SIZE_MAX - 1 - size)
- return -1;
-
- new_size = max(strbuff->size * STRBUFFER_FACTOR,
- strbuff->length + size + 1);
-
- new_value = jsonp_malloc(new_size);
- if(!new_value)
- return -1;
-
- memcpy(new_value, strbuff->value, strbuff->length);
-
- jsonp_free(strbuff->value);
- strbuff->value = new_value;
- strbuff->size = new_size;
- }
-
- memcpy(strbuff->value + strbuff->length, data, size);
- strbuff->length += size;
- strbuff->value[strbuff->length] = '\0';
-
- return 0;
-}
-
-char strbuffer_pop(strbuffer_t *strbuff)
-{
- if(strbuff->length > 0) {
- char c = strbuff->value[--strbuff->length];
- strbuff->value[strbuff->length] = '\0';
- return c;
- }
- else
- return '\0';
-}
diff --git a/src/3rdparty/jansson/strbuffer.h b/src/3rdparty/jansson/strbuffer.h
deleted file mode 100644
index 615b7f5f..00000000
--- a/src/3rdparty/jansson/strbuffer.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef STRBUFFER_H
-#define STRBUFFER_H
-
-#include
-
-typedef struct {
- char *value;
- size_t length; /* bytes used */
- size_t size; /* bytes allocated */
-} strbuffer_t;
-
-int strbuffer_init(strbuffer_t *strbuff);
-void strbuffer_close(strbuffer_t *strbuff);
-
-void strbuffer_clear(strbuffer_t *strbuff);
-
-const char *strbuffer_value(const strbuffer_t *strbuff);
-
-/* Steal the value and close the strbuffer */
-char *strbuffer_steal_value(strbuffer_t *strbuff);
-
-int strbuffer_append_byte(strbuffer_t *strbuff, char byte);
-int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size);
-
-char strbuffer_pop(strbuffer_t *strbuff);
-
-#endif
diff --git a/src/3rdparty/jansson/strconv.c b/src/3rdparty/jansson/strconv.c
deleted file mode 100644
index 8075481e..00000000
--- a/src/3rdparty/jansson/strconv.c
+++ /dev/null
@@ -1,145 +0,0 @@
-#include
-#include
-#include
-#include
-#include
-#ifdef __MINGW32__
-#undef __NO_ISOCEXT /* ensure stdlib.h will declare prototypes for mingw own 'strtod' replacement, called '__strtod' */
-#endif
-#include "jansson_private.h"
-#include "strbuffer.h"
-
-/* need jansson_private_config.h to get the correct snprintf */
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-
-#ifdef __MINGW32__
-#define strtod __strtod
-#endif
-
-#if JSON_HAVE_LOCALECONV
-#include
-
-/*
- - This code assumes that the decimal separator is exactly one
- character.
-
- - If setlocale() is called by another thread between the call to
- localeconv() and the call to sprintf() or strtod(), the result may
- be wrong. setlocale() is not thread-safe and should not be used
- this way. Multi-threaded programs should use uselocale() instead.
-*/
-
-static void to_locale(strbuffer_t *strbuffer)
-{
- const char *point;
- char *pos;
-
- point = localeconv()->decimal_point;
- if(*point == '.') {
- /* No conversion needed */
- return;
- }
-
- pos = strchr(strbuffer->value, '.');
- if(pos)
- *pos = *point;
-}
-
-static void from_locale(char *buffer)
-{
- const char *point;
- char *pos;
-
- point = localeconv()->decimal_point;
- if(*point == '.') {
- /* No conversion needed */
- return;
- }
-
- pos = strchr(buffer, *point);
- if(pos)
- *pos = '.';
-}
-#endif
-
-int jsonp_strtod(strbuffer_t *strbuffer, double *out)
-{
- double value;
- char *end;
-
-#if JSON_HAVE_LOCALECONV
- to_locale(strbuffer);
-#endif
-
- errno = 0;
- value = strtod(strbuffer->value, &end);
- assert(end == strbuffer->value + strbuffer->length);
-
- if((value == HUGE_VAL || value == -HUGE_VAL) && errno == ERANGE) {
- /* Overflow */
- return -1;
- }
-
- *out = value;
- return 0;
-}
-
-int jsonp_dtostr(char *buffer, size_t size, double value, int precision)
-{
- int ret;
- char *start, *end;
- size_t length;
-
- if (precision == 0)
- precision = 17;
-
- ret = snprintf(buffer, size, "%.*g", precision, value);
- if(ret < 0)
- return -1;
-
- length = (size_t)ret;
- if(length >= size)
- return -1;
-
-#if JSON_HAVE_LOCALECONV
- from_locale(buffer);
-#endif
-
- /* Make sure there's a dot or 'e' in the output. Otherwise
- a real is converted to an integer when decoding */
- if(strchr(buffer, '.') == NULL &&
- strchr(buffer, 'e') == NULL)
- {
- if(length + 3 >= size) {
- /* No space to append ".0" */
- return -1;
- }
- buffer[length] = '.';
- buffer[length + 1] = '0';
- buffer[length + 2] = '\0';
- length += 2;
- }
-
- /* Remove leading '+' from positive exponent. Also remove leading
- zeros from exponents (added by some printf() implementations) */
- start = strchr(buffer, 'e');
- if(start) {
- start++;
- end = start + 1;
-
- if(*start == '-')
- start++;
-
- while(*end == '0')
- end++;
-
- if(end != start) {
- memmove(start, end, length - (size_t)(end - buffer));
- length -= (size_t)(end - start);
- }
- }
-
- return (int)length;
-}
diff --git a/src/3rdparty/jansson/utf.c b/src/3rdparty/jansson/utf.c
deleted file mode 100644
index be966cbd..00000000
--- a/src/3rdparty/jansson/utf.c
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#include
-#include "utf.h"
-
-int utf8_encode(int32_t codepoint, char *buffer, size_t *size)
-{
- if(codepoint < 0)
- return -1;
- else if(codepoint < 0x80)
- {
- buffer[0] = (char)codepoint;
- *size = 1;
- }
- else if(codepoint < 0x800)
- {
- buffer[0] = 0xC0 + ((codepoint & 0x7C0) >> 6);
- buffer[1] = 0x80 + ((codepoint & 0x03F));
- *size = 2;
- }
- else if(codepoint < 0x10000)
- {
- buffer[0] = 0xE0 + ((codepoint & 0xF000) >> 12);
- buffer[1] = 0x80 + ((codepoint & 0x0FC0) >> 6);
- buffer[2] = 0x80 + ((codepoint & 0x003F));
- *size = 3;
- }
- else if(codepoint <= 0x10FFFF)
- {
- buffer[0] = 0xF0 + ((codepoint & 0x1C0000) >> 18);
- buffer[1] = 0x80 + ((codepoint & 0x03F000) >> 12);
- buffer[2] = 0x80 + ((codepoint & 0x000FC0) >> 6);
- buffer[3] = 0x80 + ((codepoint & 0x00003F));
- *size = 4;
- }
- else
- return -1;
-
- return 0;
-}
-
-size_t utf8_check_first(char byte)
-{
- unsigned char u = (unsigned char)byte;
-
- if(u < 0x80)
- return 1;
-
- if(0x80 <= u && u <= 0xBF) {
- /* second, third or fourth byte of a multi-byte
- sequence, i.e. a "continuation byte" */
- return 0;
- }
- else if(u == 0xC0 || u == 0xC1) {
- /* overlong encoding of an ASCII byte */
- return 0;
- }
- else if(0xC2 <= u && u <= 0xDF) {
- /* 2-byte sequence */
- return 2;
- }
-
- else if(0xE0 <= u && u <= 0xEF) {
- /* 3-byte sequence */
- return 3;
- }
- else if(0xF0 <= u && u <= 0xF4) {
- /* 4-byte sequence */
- return 4;
- }
- else { /* u >= 0xF5 */
- /* Restricted (start of 4-, 5- or 6-byte sequence) or invalid
- UTF-8 */
- return 0;
- }
-}
-
-size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint)
-{
- size_t i;
- int32_t value = 0;
- unsigned char u = (unsigned char)buffer[0];
-
- if(size == 2)
- {
- value = u & 0x1F;
- }
- else if(size == 3)
- {
- value = u & 0xF;
- }
- else if(size == 4)
- {
- value = u & 0x7;
- }
- else
- return 0;
-
- for(i = 1; i < size; i++)
- {
- u = (unsigned char)buffer[i];
-
- if(u < 0x80 || u > 0xBF) {
- /* not a continuation byte */
- return 0;
- }
-
- value = (value << 6) + (u & 0x3F);
- }
-
- if(value > 0x10FFFF) {
- /* not in Unicode range */
- return 0;
- }
-
- else if(0xD800 <= value && value <= 0xDFFF) {
- /* invalid code point (UTF-16 surrogate halves) */
- return 0;
- }
-
- else if((size == 2 && value < 0x80) ||
- (size == 3 && value < 0x800) ||
- (size == 4 && value < 0x10000)) {
- /* overlong encoding */
- return 0;
- }
-
- if(codepoint)
- *codepoint = value;
-
- return 1;
-}
-
-const char *utf8_iterate(const char *buffer, size_t bufsize, int32_t *codepoint)
-{
- size_t count;
- int32_t value;
-
- if(!bufsize)
- return buffer;
-
- count = utf8_check_first(buffer[0]);
- if(count <= 0)
- return NULL;
-
- if(count == 1)
- value = (unsigned char)buffer[0];
- else
- {
- if(count > bufsize || !utf8_check_full(buffer, count, &value))
- return NULL;
- }
-
- if(codepoint)
- *codepoint = value;
-
- return buffer + count;
-}
-
-int utf8_check_string(const char *string, size_t length)
-{
- size_t i;
-
- for(i = 0; i < length; i++)
- {
- size_t count = utf8_check_first(string[i]);
- if(count == 0)
- return 0;
- else if(count > 1)
- {
- if(count > length - i)
- return 0;
-
- if(!utf8_check_full(&string[i], count, NULL))
- return 0;
-
- i += count - 1;
- }
- }
-
- return 1;
-}
diff --git a/src/3rdparty/jansson/utf.h b/src/3rdparty/jansson/utf.h
deleted file mode 100644
index e182df78..00000000
--- a/src/3rdparty/jansson/utf.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef UTF_H
-#define UTF_H
-
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-
-#ifdef HAVE_STDINT_H
-#include
-#endif
-
-int utf8_encode(int32_t codepoint, char *buffer, size_t *size);
-
-size_t utf8_check_first(char byte);
-size_t utf8_check_full(const char *buffer, size_t size, int32_t *codepoint);
-const char *utf8_iterate(const char *buffer, size_t size, int32_t *codepoint);
-
-int utf8_check_string(const char *string, size_t length);
-
-#endif
diff --git a/src/3rdparty/jansson/value.c b/src/3rdparty/jansson/value.c
deleted file mode 100644
index 82e60a5f..00000000
--- a/src/3rdparty/jansson/value.c
+++ /dev/null
@@ -1,1045 +0,0 @@
-/*
- * Copyright (c) 2009-2016 Petri Lehtinen
- *
- * Jansson is free software; you can redistribute it and/or modify
- * it under the terms of the MIT license. See LICENSE for details.
- */
-
-#ifndef _GNU_SOURCE
-#define _GNU_SOURCE
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include
-#endif
-
-#include
-#include
-#include
-#include
-
-#ifdef HAVE_STDINT_H
-#include
-#endif
-
-#include "jansson.h"
-#include "hashtable.h"
-#include "jansson_private.h"
-#include "utf.h"
-
-/* Work around nonstandard isnan() and isinf() implementations */
-#ifndef isnan
-#ifndef __sun
-static JSON_INLINE int isnan(double x) { return x != x; }
-#endif
-#endif
-#ifndef isinf
-static JSON_INLINE int isinf(double x) { return !isnan(x) && isnan(x - x); }
-#endif
-
-static JSON_INLINE void json_init(json_t *json, json_type type)
-{
- json->type = type;
- json->refcount = 1;
-}
-
-
-/*** object ***/
-
-extern volatile uint32_t hashtable_seed;
-
-json_t *json_object(void)
-{
- json_object_t *object = jsonp_malloc(sizeof(json_object_t));
- if(!object)
- return NULL;
-
- if (!hashtable_seed) {
- /* Autoseed */
- json_object_seed(0);
- }
-
- json_init(&object->json, JSON_OBJECT);
-
- if(hashtable_init(&object->hashtable))
- {
- jsonp_free(object);
- return NULL;
- }
-
- object->visited = 0;
-
- return &object->json;
-}
-
-static void json_delete_object(json_object_t *object)
-{
- hashtable_close(&object->hashtable);
- jsonp_free(object);
-}
-
-size_t json_object_size(const json_t *json)
-{
- json_object_t *object;
-
- if(!json_is_object(json))
- return 0;
-
- object = json_to_object(json);
- return object->hashtable.size;
-}
-
-json_t *json_object_get(const json_t *json, const char *key)
-{
- json_object_t *object;
-
- if(!key || !json_is_object(json))
- return NULL;
-
- object = json_to_object(json);
- return hashtable_get(&object->hashtable, key);
-}
-
-int json_object_set_new_nocheck(json_t *json, const char *key, json_t *value)
-{
- json_object_t *object;
-
- if(!value)
- return -1;
-
- if(!key || !json_is_object(json) || json == value)
- {
- json_decref(value);
- return -1;
- }
- object = json_to_object(json);
-
- if(hashtable_set(&object->hashtable, key, value))
- {
- json_decref(value);
- return -1;
- }
-
- return 0;
-}
-
-int json_object_set_new(json_t *json, const char *key, json_t *value)
-{
- if(!key || !utf8_check_string(key, strlen(key)))
- {
- json_decref(value);
- return -1;
- }
-
- return json_object_set_new_nocheck(json, key, value);
-}
-
-int json_object_del(json_t *json, const char *key)
-{
- json_object_t *object;
-
- if(!key || !json_is_object(json))
- return -1;
-
- object = json_to_object(json);
- return hashtable_del(&object->hashtable, key);
-}
-
-int json_object_clear(json_t *json)
-{
- json_object_t *object;
-
- if(!json_is_object(json))
- return -1;
-
- object = json_to_object(json);
- hashtable_clear(&object->hashtable);
-
- return 0;
-}
-
-int json_object_update(json_t *object, json_t *other)
-{
- const char *key;
- json_t *value;
-
- if(!json_is_object(object) || !json_is_object(other))
- return -1;
-
- json_object_foreach(other, key, value) {
- if(json_object_set_nocheck(object, key, value))
- return -1;
- }
-
- return 0;
-}
-
-int json_object_update_existing(json_t *object, json_t *other)
-{
- const char *key;
- json_t *value;
-
- if(!json_is_object(object) || !json_is_object(other))
- return -1;
-
- json_object_foreach(other, key, value) {
- if(json_object_get(object, key))
- json_object_set_nocheck(object, key, value);
- }
-
- return 0;
-}
-
-int json_object_update_missing(json_t *object, json_t *other)
-{
- const char *key;
- json_t *value;
-
- if(!json_is_object(object) || !json_is_object(other))
- return -1;
-
- json_object_foreach(other, key, value) {
- if(!json_object_get(object, key))
- json_object_set_nocheck(object, key, value);
- }
-
- return 0;
-}
-
-void *json_object_iter(json_t *json)
-{
- json_object_t *object;
-
- if(!json_is_object(json))
- return NULL;
-
- object = json_to_object(json);
- return hashtable_iter(&object->hashtable);
-}
-
-void *json_object_iter_at(json_t *json, const char *key)
-{
- json_object_t *object;
-
- if(!key || !json_is_object(json))
- return NULL;
-
- object = json_to_object(json);
- return hashtable_iter_at(&object->hashtable, key);
-}
-
-void *json_object_iter_next(json_t *json, void *iter)
-{
- json_object_t *object;
-
- if(!json_is_object(json) || iter == NULL)
- return NULL;
-
- object = json_to_object(json);
- return hashtable_iter_next(&object->hashtable, iter);
-}
-
-const char *json_object_iter_key(void *iter)
-{
- if(!iter)
- return NULL;
-
- return hashtable_iter_key(iter);
-}
-
-json_t *json_object_iter_value(void *iter)
-{
- if(!iter)
- return NULL;
-
- return (json_t *)hashtable_iter_value(iter);
-}
-
-int json_object_iter_set_new(json_t *json, void *iter, json_t *value)
-{
- if(!json_is_object(json) || !iter || !value)
- return -1;
-
- hashtable_iter_set(iter, value);
- return 0;
-}
-
-void *json_object_key_to_iter(const char *key)
-{
- if(!key)
- return NULL;
-
- return hashtable_key_to_iter(key);
-}
-
-static int json_object_equal(json_t *object1, json_t *object2)
-{
- const char *key;
- json_t *value1, *value2;
-
- if(json_object_size(object1) != json_object_size(object2))
- return 0;
-
- json_object_foreach(object1, key, value1) {
- value2 = json_object_get(object2, key);
-
- if(!json_equal(value1, value2))
- return 0;
- }
-
- return 1;
-}
-
-static json_t *json_object_copy(json_t *object)
-{
- json_t *result;
-
- const char *key;
- json_t *value;
-
- result = json_object();
- if(!result)
- return NULL;
-
- json_object_foreach(object, key, value)
- json_object_set_nocheck(result, key, value);
-
- return result;
-}
-
-static json_t *json_object_deep_copy(const json_t *object)
-{
- json_t *result;
- void *iter;
-
- result = json_object();
- if(!result)
- return NULL;
-
- /* Cannot use json_object_foreach because object has to be cast
- non-const */
- iter = json_object_iter((json_t *)object);
- while(iter) {
- const char *key;
- const json_t *value;
- key = json_object_iter_key(iter);
- value = json_object_iter_value(iter);
-
- json_object_set_new_nocheck(result, key, json_deep_copy(value));
- iter = json_object_iter_next((json_t *)object, iter);
- }
-
- return result;
-}
-
-
-/*** array ***/
-
-json_t *json_array(void)
-{
- json_array_t *array = jsonp_malloc(sizeof(json_array_t));
- if(!array)
- return NULL;
- json_init(&array->json, JSON_ARRAY);
-
- array->entries = 0;
- array->size = 8;
-
- array->table = jsonp_malloc(array->size * sizeof(json_t *));
- if(!array->table) {
- jsonp_free(array);
- return NULL;
- }
-
- array->visited = 0;
-
- return &array->json;
-}
-
-static void json_delete_array(json_array_t *array)
-{
- size_t i;
-
- for(i = 0; i < array->entries; i++)
- json_decref(array->table[i]);
-
- jsonp_free(array->table);
- jsonp_free(array);
-}
-
-size_t json_array_size(const json_t *json)
-{
- if(!json_is_array(json))
- return 0;
-
- return json_to_array(json)->entries;
-}
-
-json_t *json_array_get(const json_t *json, size_t index)
-{
- json_array_t *array;
- if(!json_is_array(json))
- return NULL;
- array = json_to_array(json);
-
- if(index >= array->entries)
- return NULL;
-
- return array->table[index];
-}
-
-int json_array_set_new(json_t *json, size_t index, json_t *value)
-{
- json_array_t *array;
-
- if(!value)
- return -1;
-
- if(!json_is_array(json) || json == value)
- {
- json_decref(value);
- return -1;
- }
- array = json_to_array(json);
-
- if(index >= array->entries)
- {
- json_decref(value);
- return -1;
- }
-
- json_decref(array->table[index]);
- array->table[index] = value;
-
- return 0;
-}
-
-static void array_move(json_array_t *array, size_t dest,
- size_t src, size_t count)
-{
- memmove(&array->table[dest], &array->table[src], count * sizeof(json_t *));
-}
-
-static void array_copy(json_t **dest, size_t dpos,
- json_t **src, size_t spos,
- size_t count)
-{
- memcpy(&dest[dpos], &src[spos], count * sizeof(json_t *));
-}
-
-static json_t **json_array_grow(json_array_t *array,
- size_t amount,
- int copy)
-{
- size_t new_size;
- json_t **old_table, **new_table;
-
- if(array->entries + amount <= array->size)
- return array->table;
-
- old_table = array->table;
-
- new_size = max(array->size + amount, array->size * 2);
- new_table = jsonp_malloc(new_size * sizeof(json_t *));
- if(!new_table)
- return NULL;
-
- array->size = new_size;
- array->table = new_table;
-
- if(copy) {
- array_copy(array->table, 0, old_table, 0, array->entries);
- jsonp_free(old_table);
- return array->table;
- }
-
- return old_table;
-}
-
-int json_array_append_new(json_t *json, json_t *value)
-{
- json_array_t *array;
-
- if(!value)
- return -1;
-
- if(!json_is_array(json) || json == value)
- {
- json_decref(value);
- return -1;
- }
- array = json_to_array(json);
-
- if(!json_array_grow(array, 1, 1)) {
- json_decref(value);
- return -1;
- }
-
- array->table[array->entries] = value;
- array->entries++;
-
- return 0;
-}
-
-int json_array_insert_new(json_t *json, size_t index, json_t *value)
-{
- json_array_t *array;
- json_t **old_table;
-
- if(!value)
- return -1;
-
- if(!json_is_array(json) || json == value) {
- json_decref(value);
- return -1;
- }
- array = json_to_array(json);
-
- if(index > array->entries) {
- json_decref(value);
- return -1;
- }
-
- old_table = json_array_grow(array, 1, 0);
- if(!old_table) {
- json_decref(value);
- return -1;
- }
-
- if(old_table != array->table) {
- array_copy(array->table, 0, old_table, 0, index);
- array_copy(array->table, index + 1, old_table, index,
- array->entries - index);
- jsonp_free(old_table);
- }
- else
- array_move(array, index + 1, index, array->entries - index);
-
- array->table[index] = value;
- array->entries++;
-
- return 0;
-}
-
-int json_array_remove(json_t *json, size_t index)
-{
- json_array_t *array;
-
- if(!json_is_array(json))
- return -1;
- array = json_to_array(json);
-
- if(index >= array->entries)
- return -1;
-
- json_decref(array->table[index]);
-
- /* If we're removing the last element, nothing has to be moved */
- if(index < array->entries - 1)
- array_move(array, index, index + 1, array->entries - index - 1);
-
- array->entries--;
-
- return 0;
-}
-
-int json_array_clear(json_t *json)
-{
- json_array_t *array;
- size_t i;
-
- if(!json_is_array(json))
- return -1;
- array = json_to_array(json);
-
- for(i = 0; i < array->entries; i++)
- json_decref(array->table[i]);
-
- array->entries = 0;
- return 0;
-}
-
-int json_array_extend(json_t *json, json_t *other_json)
-{
- json_array_t *array, *other;
- size_t i;
-
- if(!json_is_array(json) || !json_is_array(other_json))
- return -1;
- array = json_to_array(json);
- other = json_to_array(other_json);
-
- if(!json_array_grow(array, other->entries, 1))
- return -1;
-
- for(i = 0; i < other->entries; i++)
- json_incref(other->table[i]);
-
- array_copy(array->table, array->entries, other->table, 0, other->entries);
-
- array->entries += other->entries;
- return 0;
-}
-
-static int json_array_equal(json_t *array1, json_t *array2)
-{
- size_t i, size;
-
- size = json_array_size(array1);
- if(size != json_array_size(array2))
- return 0;
-
- for(i = 0; i < size; i++)
- {
- json_t *value1, *value2;
-
- value1 = json_array_get(array1, i);
- value2 = json_array_get(array2, i);
-
- if(!json_equal(value1, value2))
- return 0;
- }
-
- return 1;
-}
-
-static json_t *json_array_copy(json_t *array)
-{
- json_t *result;
- size_t i;
-
- result = json_array();
- if(!result)
- return NULL;
-
- for(i = 0; i < json_array_size(array); i++)
- json_array_append(result, json_array_get(array, i));
-
- return result;
-}
-
-static json_t *json_array_deep_copy(const json_t *array)
-{
- json_t *result;
- size_t i;
-
- result = json_array();
- if(!result)
- return NULL;
-
- for(i = 0; i < json_array_size(array); i++)
- json_array_append_new(result, json_deep_copy(json_array_get(array, i)));
-
- return result;
-}
-
-/*** string ***/
-
-static json_t *string_create(const char *value, size_t len, int own)
-{
- char *v;
- json_string_t *string;
-
- if(!value)
- return NULL;
-
- if(own)
- v = (char *)value;
- else {
- v = jsonp_strndup(value, len);
- if(!v)
- return NULL;
- }
-
- string = jsonp_malloc(sizeof(json_string_t));
- if(!string) {
- if(!own)
- jsonp_free(v);
- return NULL;
- }
- json_init(&string->json, JSON_STRING);
- string->value = v;
- string->length = len;
-
- return &string->json;
-}
-
-json_t *json_string_nocheck(const char *value)
-{
- if(!value)
- return NULL;
-
- return string_create(value, strlen(value), 0);
-}
-
-json_t *json_stringn_nocheck(const char *value, size_t len)
-{
- return string_create(value, len, 0);
-}
-
-/* this is private; "steal" is not a public API concept */
-json_t *jsonp_stringn_nocheck_own(const char *value, size_t len)
-{
- return string_create(value, len, 1);
-}
-
-json_t *json_string(const char *value)
-{
- if(!value)
- return NULL;
-
- return json_stringn(value, strlen(value));
-}
-
-json_t *json_stringn(const char *value, size_t len)
-{
- if(!value || !utf8_check_string(value, len))
- return NULL;
-
- return json_stringn_nocheck(value, len);
-}
-
-const char *json_string_value(const json_t *json)
-{
- if(!json_is_string(json))
- return NULL;
-
- return json_to_string(json)->value;
-}
-
-size_t json_string_length(const json_t *json)
-{
- if(!json_is_string(json))
- return 0;
-
- return json_to_string(json)->length;
-}
-
-int json_string_set_nocheck(json_t *json, const char *value)
-{
- if(!value)
- return -1;
-
- return json_string_setn_nocheck(json, value, strlen(value));
-}
-
-int json_string_setn_nocheck(json_t *json, const char *value, size_t len)
-{
- char *dup;
- json_string_t *string;
-
- if(!json_is_string(json) || !value)
- return -1;
-
- dup = jsonp_strndup(value, len);
- if(!dup)
- return -1;
-
- string = json_to_string(json);
- jsonp_free(string->value);
- string->value = dup;
- string->length = len;
-
- return 0;
-}
-
-int json_string_set(json_t *json, const char *value)
-{
- if(!value)
- return -1;
-
- return json_string_setn(json, value, strlen(value));
-}
-
-int json_string_setn(json_t *json, const char *value, size_t len)
-{
- if(!value || !utf8_check_string(value, len))
- return -1;
-
- return json_string_setn_nocheck(json, value, len);
-}
-
-static void json_delete_string(json_string_t *string)
-{
- jsonp_free(string->value);
- jsonp_free(string);
-}
-
-static int json_string_equal(json_t *string1, json_t *string2)
-{
- json_string_t *s1, *s2;
-
- if(!json_is_string(string1) || !json_is_string(string2))
- return 0;
-
- s1 = json_to_string(string1);
- s2 = json_to_string(string2);
- return s1->length == s2->length && !memcmp(s1->value, s2->value, s1->length);
-}
-
-static json_t *json_string_copy(const json_t *string)
-{
- json_string_t *s;
-
- if(!json_is_string(string))
- return NULL;
-
- s = json_to_string(string);
- return json_stringn_nocheck(s->value, s->length);
-}
-
-
-/*** integer ***/
-
-json_t *json_integer(json_int_t value)
-{
- json_integer_t *integer = jsonp_malloc(sizeof(json_integer_t));
- if(!integer)
- return NULL;
- json_init(&integer->json, JSON_INTEGER);
-
- integer->value = value;
- return &integer->json;
-}
-
-json_int_t json_integer_value(const json_t *json)
-{
- if(!json_is_integer(json))
- return 0;
-
- return json_to_integer(json)->value;
-}
-
-int json_integer_set(json_t *json, json_int_t value)
-{
- if(!json_is_integer(json))
- return -1;
-
- json_to_integer(json)->value = value;
-
- return 0;
-}
-
-static void json_delete_integer(json_integer_t *integer)
-{
- jsonp_free(integer);
-}
-
-static int json_integer_equal(json_t *integer1, json_t *integer2)
-{
- return json_integer_value(integer1) == json_integer_value(integer2);
-}
-
-static json_t *json_integer_copy(const json_t *integer)
-{
- return json_integer(json_integer_value(integer));
-}
-
-
-/*** real ***/
-
-json_t *json_real(double value)
-{
- json_real_t *real;
-
- if(isnan(value) || isinf(value))
- return NULL;
-
- real = jsonp_malloc(sizeof(json_real_t));
- if(!real)
- return NULL;
- json_init(&real->json, JSON_REAL);
-
- real->value = value;
- return &real->json;
-}
-
-double json_real_value(const json_t *json)
-{
- if(!json_is_real(json))
- return 0;
-
- return json_to_real(json)->value;
-}
-
-int json_real_set(json_t *json, double value)
-{
- if(!json_is_real(json) || isnan(value) || isinf(value))
- return -1;
-
- json_to_real(json)->value = value;
-
- return 0;
-}
-
-static void json_delete_real(json_real_t *real)
-{
- jsonp_free(real);
-}
-
-static int json_real_equal(json_t *real1, json_t *real2)
-{
- return json_real_value(real1) == json_real_value(real2);
-}
-
-static json_t *json_real_copy(const json_t *real)
-{
- return json_real(json_real_value(real));
-}
-
-
-/*** number ***/
-
-double json_number_value(const json_t *json)
-{
- if(json_is_integer(json))
- return (double)json_integer_value(json);
- else if(json_is_real(json))
- return json_real_value(json);
- else
- return 0.0;
-}
-
-
-/*** simple values ***/
-
-json_t *json_true(void)
-{
- static json_t the_true = {JSON_TRUE, (size_t)-1};
- return &the_true;
-}
-
-
-json_t *json_false(void)
-{
- static json_t the_false = {JSON_FALSE, (size_t)-1};
- return &the_false;
-}
-
-
-json_t *json_null(void)
-{
- static json_t the_null = {JSON_NULL, (size_t)-1};
- return &the_null;
-}
-
-
-/*** deletion ***/
-
-void json_delete(json_t *json)
-{
- if (!json)
- return;
-
- switch(json_typeof(json)) {
- case JSON_OBJECT:
- json_delete_object(json_to_object(json));
- break;
- case JSON_ARRAY:
- json_delete_array(json_to_array(json));
- break;
- case JSON_STRING:
- json_delete_string(json_to_string(json));
- break;
- case JSON_INTEGER:
- json_delete_integer(json_to_integer(json));
- break;
- case JSON_REAL:
- json_delete_real(json_to_real(json));
- break;
- default:
- return;
- }
-
- /* json_delete is not called for true, false or null */
-}
-
-
-/*** equality ***/
-
-int json_equal(json_t *json1, json_t *json2)
-{
- if(!json1 || !json2)
- return 0;
-
- if(json_typeof(json1) != json_typeof(json2))
- return 0;
-
- /* this covers true, false and null as they are singletons */
- if(json1 == json2)
- return 1;
-
- switch(json_typeof(json1)) {
- case JSON_OBJECT:
- return json_object_equal(json1, json2);
- case JSON_ARRAY:
- return json_array_equal(json1, json2);
- case JSON_STRING:
- return json_string_equal(json1, json2);
- case JSON_INTEGER:
- return json_integer_equal(json1, json2);
- case JSON_REAL:
- return json_real_equal(json1, json2);
- default:
- return 0;
- }
-}
-
-
-/*** copying ***/
-
-json_t *json_copy(json_t *json)
-{
- if(!json)
- return NULL;
-
- switch(json_typeof(json)) {
- case JSON_OBJECT:
- return json_object_copy(json);
- case JSON_ARRAY:
- return json_array_copy(json);
- case JSON_STRING:
- return json_string_copy(json);
- case JSON_INTEGER:
- return json_integer_copy(json);
- case JSON_REAL:
- return json_real_copy(json);
- case JSON_TRUE:
- case JSON_FALSE:
- case JSON_NULL:
- return json;
- default:
- return NULL;
- }
-
- return NULL;
-}
-
-json_t *json_deep_copy(const json_t *json)
-{
- if(!json)
- return NULL;
-
- switch(json_typeof(json)) {
- case JSON_OBJECT:
- return json_object_deep_copy(json);
- case JSON_ARRAY:
- return json_array_deep_copy(json);
- /* for the rest of the types, deep copying doesn't differ from
- shallow copying */
- case JSON_STRING:
- return json_string_copy(json);
- case JSON_INTEGER:
- return json_integer_copy(json);
- case JSON_REAL:
- return json_real_copy(json);
- case JSON_TRUE:
- case JSON_FALSE:
- case JSON_NULL:
- return (json_t *)json;
- default:
- return NULL;
- }
-
- return NULL;
-}
diff --git a/src/3rdparty/rapidjson/allocators.h b/src/3rdparty/rapidjson/allocators.h
new file mode 100644
index 00000000..98affe03
--- /dev/null
+++ b/src/3rdparty/rapidjson/allocators.h
@@ -0,0 +1,271 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_ALLOCATORS_H_
+#define RAPIDJSON_ALLOCATORS_H_
+
+#include "rapidjson.h"
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+///////////////////////////////////////////////////////////////////////////////
+// Allocator
+
+/*! \class rapidjson::Allocator
+ \brief Concept for allocating, resizing and freeing memory block.
+
+ Note that Malloc() and Realloc() are non-static but Free() is static.
+
+ So if an allocator need to support Free(), it needs to put its pointer in
+ the header of memory block.
+
+\code
+concept Allocator {
+ static const bool kNeedFree; //!< Whether this allocator needs to call Free().
+
+ // Allocate a memory block.
+ // \param size of the memory block in bytes.
+ // \returns pointer to the memory block.
+ void* Malloc(size_t size);
+
+ // Resize a memory block.
+ // \param originalPtr The pointer to current memory block. Null pointer is permitted.
+ // \param originalSize The current size in bytes. (Design issue: since some allocator may not book-keep this, explicitly pass to it can save memory.)
+ // \param newSize the new size in bytes.
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize);
+
+ // Free a memory block.
+ // \param pointer to the memory block. Null pointer is permitted.
+ static void Free(void *ptr);
+};
+\endcode
+*/
+
+///////////////////////////////////////////////////////////////////////////////
+// CrtAllocator
+
+//! C-runtime library allocator.
+/*! This class is just wrapper for standard C library memory routines.
+ \note implements Allocator concept
+*/
+class CrtAllocator {
+public:
+ static const bool kNeedFree = true;
+ void* Malloc(size_t size) {
+ if (size) // behavior of malloc(0) is implementation defined.
+ return std::malloc(size);
+ else
+ return NULL; // standardize to returning NULL.
+ }
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+ (void)originalSize;
+ if (newSize == 0) {
+ std::free(originalPtr);
+ return NULL;
+ }
+ return std::realloc(originalPtr, newSize);
+ }
+ static void Free(void *ptr) { std::free(ptr); }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// MemoryPoolAllocator
+
+//! Default memory allocator used by the parser and DOM.
+/*! This allocator allocate memory blocks from pre-allocated memory chunks.
+
+ It does not free memory blocks. And Realloc() only allocate new memory.
+
+ The memory chunks are allocated by BaseAllocator, which is CrtAllocator by default.
+
+ User may also supply a buffer as the first chunk.
+
+ If the user-buffer is full then additional chunks are allocated by BaseAllocator.
+
+ The user-buffer is not deallocated by this allocator.
+
+ \tparam BaseAllocator the allocator type for allocating memory chunks. Default is CrtAllocator.
+ \note implements Allocator concept
+*/
+template
+class MemoryPoolAllocator {
+public:
+ static const bool kNeedFree = false; //!< Tell users that no need to call Free() with this allocator. (concept Allocator)
+
+ //! Constructor with chunkSize.
+ /*! \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
+ \param baseAllocator The allocator for allocating memory chunks.
+ */
+ MemoryPoolAllocator(size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
+ chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(0), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+ {
+ }
+
+ //! Constructor with user-supplied buffer.
+ /*! The user buffer will be used firstly. When it is full, memory pool allocates new chunk with chunk size.
+
+ The user buffer will not be deallocated when this allocator is destructed.
+
+ \param buffer User supplied buffer.
+ \param size Size of the buffer in bytes. It must at least larger than sizeof(ChunkHeader).
+ \param chunkSize The size of memory chunk. The default is kDefaultChunkSize.
+ \param baseAllocator The allocator for allocating memory chunks.
+ */
+ MemoryPoolAllocator(void *buffer, size_t size, size_t chunkSize = kDefaultChunkCapacity, BaseAllocator* baseAllocator = 0) :
+ chunkHead_(0), chunk_capacity_(chunkSize), userBuffer_(buffer), baseAllocator_(baseAllocator), ownBaseAllocator_(0)
+ {
+ RAPIDJSON_ASSERT(buffer != 0);
+ RAPIDJSON_ASSERT(size > sizeof(ChunkHeader));
+ chunkHead_ = reinterpret_cast(buffer);
+ chunkHead_->capacity = size - sizeof(ChunkHeader);
+ chunkHead_->size = 0;
+ chunkHead_->next = 0;
+ }
+
+ //! Destructor.
+ /*! This deallocates all memory chunks, excluding the user-supplied buffer.
+ */
+ ~MemoryPoolAllocator() {
+ Clear();
+ RAPIDJSON_DELETE(ownBaseAllocator_);
+ }
+
+ //! Deallocates all memory chunks, excluding the user-supplied buffer.
+ void Clear() {
+ while (chunkHead_ && chunkHead_ != userBuffer_) {
+ ChunkHeader* next = chunkHead_->next;
+ baseAllocator_->Free(chunkHead_);
+ chunkHead_ = next;
+ }
+ if (chunkHead_ && chunkHead_ == userBuffer_)
+ chunkHead_->size = 0; // Clear user buffer
+ }
+
+ //! Computes the total capacity of allocated memory chunks.
+ /*! \return total capacity in bytes.
+ */
+ size_t Capacity() const {
+ size_t capacity = 0;
+ for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+ capacity += c->capacity;
+ return capacity;
+ }
+
+ //! Computes the memory blocks allocated.
+ /*! \return total used bytes.
+ */
+ size_t Size() const {
+ size_t size = 0;
+ for (ChunkHeader* c = chunkHead_; c != 0; c = c->next)
+ size += c->size;
+ return size;
+ }
+
+ //! Allocates a memory block. (concept Allocator)
+ void* Malloc(size_t size) {
+ if (!size)
+ return NULL;
+
+ size = RAPIDJSON_ALIGN(size);
+ if (chunkHead_ == 0 || chunkHead_->size + size > chunkHead_->capacity)
+ if (!AddChunk(chunk_capacity_ > size ? chunk_capacity_ : size))
+ return NULL;
+
+ void *buffer = reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size;
+ chunkHead_->size += size;
+ return buffer;
+ }
+
+ //! Resizes a memory block (concept Allocator)
+ void* Realloc(void* originalPtr, size_t originalSize, size_t newSize) {
+ if (originalPtr == 0)
+ return Malloc(newSize);
+
+ if (newSize == 0)
+ return NULL;
+
+ originalSize = RAPIDJSON_ALIGN(originalSize);
+ newSize = RAPIDJSON_ALIGN(newSize);
+
+ // Do not shrink if new size is smaller than original
+ if (originalSize >= newSize)
+ return originalPtr;
+
+ // Simply expand it if it is the last allocation and there is sufficient space
+ if (originalPtr == reinterpret_cast(chunkHead_) + RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + chunkHead_->size - originalSize) {
+ size_t increment = static_cast(newSize - originalSize);
+ if (chunkHead_->size + increment <= chunkHead_->capacity) {
+ chunkHead_->size += increment;
+ return originalPtr;
+ }
+ }
+
+ // Realloc process: allocate and copy memory, do not free original buffer.
+ if (void* newBuffer = Malloc(newSize)) {
+ if (originalSize)
+ std::memcpy(newBuffer, originalPtr, originalSize);
+ return newBuffer;
+ }
+ else
+ return NULL;
+ }
+
+ //! Frees a memory block (concept Allocator)
+ static void Free(void *ptr) { (void)ptr; } // Do nothing
+
+private:
+ //! Copy constructor is not permitted.
+ MemoryPoolAllocator(const MemoryPoolAllocator& rhs) /* = delete */;
+ //! Copy assignment operator is not permitted.
+ MemoryPoolAllocator& operator=(const MemoryPoolAllocator& rhs) /* = delete */;
+
+ //! Creates a new chunk.
+ /*! \param capacity Capacity of the chunk in bytes.
+ \return true if success.
+ */
+ bool AddChunk(size_t capacity) {
+ if (!baseAllocator_)
+ ownBaseAllocator_ = baseAllocator_ = RAPIDJSON_NEW(BaseAllocator());
+ if (ChunkHeader* chunk = reinterpret_cast(baseAllocator_->Malloc(RAPIDJSON_ALIGN(sizeof(ChunkHeader)) + capacity))) {
+ chunk->capacity = capacity;
+ chunk->size = 0;
+ chunk->next = chunkHead_;
+ chunkHead_ = chunk;
+ return true;
+ }
+ else
+ return false;
+ }
+
+ static const int kDefaultChunkCapacity = 64 * 1024; //!< Default chunk capacity.
+
+ //! Chunk header for perpending to each chunk.
+ /*! Chunks are stored as a singly linked list.
+ */
+ struct ChunkHeader {
+ size_t capacity; //!< Capacity of the chunk in bytes (excluding the header itself).
+ size_t size; //!< Current size of allocated memory in bytes.
+ ChunkHeader *next; //!< Next chunk in the linked list.
+ };
+
+ ChunkHeader *chunkHead_; //!< Head of the chunk linked-list. Only the head chunk serves allocation.
+ size_t chunk_capacity_; //!< The minimum capacity of chunk when they are allocated.
+ void *userBuffer_; //!< User supplied buffer.
+ BaseAllocator* baseAllocator_; //!< base allocator for allocating memory chunks.
+ BaseAllocator* ownBaseAllocator_; //!< base allocator created by this object.
+};
+
+RAPIDJSON_NAMESPACE_END
+
+#endif // RAPIDJSON_ENCODINGS_H_
diff --git a/src/3rdparty/rapidjson/document.h b/src/3rdparty/rapidjson/document.h
new file mode 100644
index 00000000..e3e20dfb
--- /dev/null
+++ b/src/3rdparty/rapidjson/document.h
@@ -0,0 +1,2575 @@
+// Tencent is pleased to support the open source community by making RapidJSON available.
+//
+// Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved.
+//
+// Licensed under the MIT License (the "License"); you may not use this file except
+// in compliance with the License. You may obtain a copy of the License at
+//
+// http://opensource.org/licenses/MIT
+//
+// Unless required by applicable law or agreed to in writing, software distributed
+// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+
+#ifndef RAPIDJSON_DOCUMENT_H_
+#define RAPIDJSON_DOCUMENT_H_
+
+/*! \file document.h */
+
+#include "reader.h"
+#include "internal/meta.h"
+#include "internal/strfunc.h"
+#include "memorystream.h"
+#include "encodedstream.h"
+#include // placement new
+#include
+
+RAPIDJSON_DIAG_PUSH
+#ifdef _MSC_VER
+RAPIDJSON_DIAG_OFF(4127) // conditional expression is constant
+RAPIDJSON_DIAG_OFF(4244) // conversion from kXxxFlags to 'uint16_t', possible loss of data
+#endif
+
+#ifdef __clang__
+RAPIDJSON_DIAG_OFF(padded)
+RAPIDJSON_DIAG_OFF(switch-enum)
+RAPIDJSON_DIAG_OFF(c++98-compat)
+#endif
+
+#ifdef __GNUC__
+RAPIDJSON_DIAG_OFF(effc++)
+#if __GNUC__ >= 6
+RAPIDJSON_DIAG_OFF(terminate) // ignore throwing RAPIDJSON_ASSERT in RAPIDJSON_NOEXCEPT functions
+#endif
+#endif // __GNUC__
+
+#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
+#include // std::iterator, std::random_access_iterator_tag
+#endif
+
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+#include // std::move
+#endif
+
+RAPIDJSON_NAMESPACE_BEGIN
+
+// Forward declaration.
+template
+class GenericValue;
+
+template
+class GenericDocument;
+
+//! Name-value pair in a JSON object value.
+/*!
+ This class was internal to GenericValue. It used to be a inner struct.
+ But a compiler (IBM XL C/C++ for AIX) have reported to have problem with that so it moved as a namespace scope struct.
+ https://code.google.com/p/rapidjson/issues/detail?id=64
+*/
+template
+struct GenericMember {
+ GenericValue name; //!< name of member (must be a string)
+ GenericValue value; //!< value of member.
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericMemberIterator
+
+#ifndef RAPIDJSON_NOMEMBERITERATORCLASS
+
+//! (Constant) member iterator for a JSON object value
+/*!
+ \tparam Const Is this a constant iterator?
+ \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
+ \tparam Allocator Allocator type for allocating memory of object, array and string.
+
+ This class implements a Random Access Iterator for GenericMember elements
+ of a GenericValue, see ISO/IEC 14882:2003(E) C++ standard, 24.1 [lib.iterator.requirements].
+
+ \note This iterator implementation is mainly intended to avoid implicit
+ conversions from iterator values to \c NULL,
+ e.g. from GenericValue::FindMember.
+
+ \note Define \c RAPIDJSON_NOMEMBERITERATORCLASS to fall back to a
+ pointer-based implementation, if your platform doesn't provide
+ the C++ header.
+
+ \see GenericMember, GenericValue::MemberIterator, GenericValue::ConstMemberIterator
+ */
+template
+class GenericMemberIterator
+ : public std::iterator >::Type> {
+
+ friend class GenericValue;
+ template friend class GenericMemberIterator;
+
+ typedef GenericMember PlainType;
+ typedef typename internal::MaybeAddConst::Type ValueType;
+ typedef std::iterator BaseType;
+
+public:
+ //! Iterator type itself
+ typedef GenericMemberIterator Iterator;
+ //! Constant iterator type
+ typedef GenericMemberIterator ConstIterator;
+ //! Non-constant iterator type
+ typedef GenericMemberIterator NonConstIterator;
+
+ //! Pointer to (const) GenericMember
+ typedef typename BaseType::pointer Pointer;
+ //! Reference to (const) GenericMember
+ typedef typename BaseType::reference Reference;
+ //! Signed integer type (e.g. \c ptrdiff_t)
+ typedef typename BaseType::difference_type DifferenceType;
+
+ //! Default constructor (singular value)
+ /*! Creates an iterator pointing to no element.
+ \note All operations, except for comparisons, are undefined on such values.
+ */
+ GenericMemberIterator() : ptr_() {}
+
+ //! Iterator conversions to more const
+ /*!
+ \param it (Non-const) iterator to copy from
+
+ Allows the creation of an iterator from another GenericMemberIterator
+ that is "less const". Especially, creating a non-constant iterator
+ from a constant iterator are disabled:
+ \li const -> non-const (not ok)
+ \li const -> const (ok)
+ \li non-const -> const (ok)
+ \li non-const -> non-const (ok)
+
+ \note If the \c Const template parameter is already \c false, this
+ constructor effectively defines a regular copy-constructor.
+ Otherwise, the copy constructor is implicitly defined.
+ */
+ GenericMemberIterator(const NonConstIterator & it) : ptr_(it.ptr_) {}
+ Iterator& operator=(const NonConstIterator & it) { ptr_ = it.ptr_; return *this; }
+
+ //! @name stepping
+ //@{
+ Iterator& operator++(){ ++ptr_; return *this; }
+ Iterator& operator--(){ --ptr_; return *this; }
+ Iterator operator++(int){ Iterator old(*this); ++ptr_; return old; }
+ Iterator operator--(int){ Iterator old(*this); --ptr_; return old; }
+ //@}
+
+ //! @name increment/decrement
+ //@{
+ Iterator operator+(DifferenceType n) const { return Iterator(ptr_+n); }
+ Iterator operator-(DifferenceType n) const { return Iterator(ptr_-n); }
+
+ Iterator& operator+=(DifferenceType n) { ptr_+=n; return *this; }
+ Iterator& operator-=(DifferenceType n) { ptr_-=n; return *this; }
+ //@}
+
+ //! @name relations
+ //@{
+ bool operator==(ConstIterator that) const { return ptr_ == that.ptr_; }
+ bool operator!=(ConstIterator that) const { return ptr_ != that.ptr_; }
+ bool operator<=(ConstIterator that) const { return ptr_ <= that.ptr_; }
+ bool operator>=(ConstIterator that) const { return ptr_ >= that.ptr_; }
+ bool operator< (ConstIterator that) const { return ptr_ < that.ptr_; }
+ bool operator> (ConstIterator that) const { return ptr_ > that.ptr_; }
+ //@}
+
+ //! @name dereference
+ //@{
+ Reference operator*() const { return *ptr_; }
+ Pointer operator->() const { return ptr_; }
+ Reference operator[](DifferenceType n) const { return ptr_[n]; }
+ //@}
+
+ //! Distance
+ DifferenceType operator-(ConstIterator that) const { return ptr_-that.ptr_; }
+
+private:
+ //! Internal constructor from plain pointer
+ explicit GenericMemberIterator(Pointer p) : ptr_(p) {}
+
+ Pointer ptr_; //!< raw pointer
+};
+
+#else // RAPIDJSON_NOMEMBERITERATORCLASS
+
+// class-based member iterator implementation disabled, use plain pointers
+
+template
+struct GenericMemberIterator;
+
+//! non-const GenericMemberIterator
+template
+struct GenericMemberIterator {
+ //! use plain pointer as iterator type
+ typedef GenericMember* Iterator;
+};
+//! const GenericMemberIterator
+template
+struct GenericMemberIterator {
+ //! use plain const pointer as iterator type
+ typedef const GenericMember* Iterator;
+};
+
+#endif // RAPIDJSON_NOMEMBERITERATORCLASS
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericStringRef
+
+//! Reference to a constant string (not taking a copy)
+/*!
+ \tparam CharType character type of the string
+
+ This helper class is used to automatically infer constant string
+ references for string literals, especially from \c const \b (!)
+ character arrays.
+
+ The main use is for creating JSON string values without copying the
+ source string via an \ref Allocator. This requires that the referenced
+ string pointers have a sufficient lifetime, which exceeds the lifetime
+ of the associated GenericValue.
+
+ \b Example
+ \code
+ Value v("foo"); // ok, no need to copy & calculate length
+ const char foo[] = "foo";
+ v.SetString(foo); // ok
+
+ const char* bar = foo;
+ // Value x(bar); // not ok, can't rely on bar's lifetime
+ Value x(StringRef(bar)); // lifetime explicitly guaranteed by user
+ Value y(StringRef(bar, 3)); // ok, explicitly pass length
+ \endcode
+
+ \see StringRef, GenericValue::SetString
+*/
+template
+struct GenericStringRef {
+ typedef CharType Ch; //!< character type of the string
+
+ //! Create string reference from \c const character array
+#ifndef __clang__ // -Wdocumentation
+ /*!
+ This constructor implicitly creates a constant string reference from
+ a \c const character array. It has better performance than
+ \ref StringRef(const CharType*) by inferring the string \ref length
+ from the array length, and also supports strings containing null
+ characters.
+
+ \tparam N length of the string, automatically inferred
+
+ \param str Constant character array, lifetime assumed to be longer
+ than the use of the string in e.g. a GenericValue
+
+ \post \ref s == str
+
+ \note Constant complexity.
+ \note There is a hidden, private overload to disallow references to
+ non-const character arrays to be created via this constructor.
+ By this, e.g. function-scope arrays used to be filled via
+ \c snprintf are excluded from consideration.
+ In such cases, the referenced string should be \b copied to the
+ GenericValue instead.
+ */
+#endif
+ template
+ GenericStringRef(const CharType (&str)[N]) RAPIDJSON_NOEXCEPT
+ : s(str), length(N-1) {}
+
+ //! Explicitly create string reference from \c const character pointer
+#ifndef __clang__ // -Wdocumentation
+ /*!
+ This constructor can be used to \b explicitly create a reference to
+ a constant string pointer.
+
+ \see StringRef(const CharType*)
+
+ \param str Constant character pointer, lifetime assumed to be longer
+ than the use of the string in e.g. a GenericValue
+
+ \post \ref s == str
+
+ \note There is a hidden, private overload to disallow references to
+ non-const character arrays to be created via this constructor.
+ By this, e.g. function-scope arrays used to be filled via
+ \c snprintf are excluded from consideration.
+ In such cases, the referenced string should be \b copied to the
+ GenericValue instead.
+ */
+#endif
+ explicit GenericStringRef(const CharType* str)
+ : s(str), length(internal::StrLen(str)){ RAPIDJSON_ASSERT(s != 0); }
+
+ //! Create constant string reference from pointer and length
+#ifndef __clang__ // -Wdocumentation
+ /*! \param str constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
+ \param len length of the string, excluding the trailing NULL terminator
+
+ \post \ref s == str && \ref length == len
+ \note Constant complexity.
+ */
+#endif
+ GenericStringRef(const CharType* str, SizeType len)
+ : s(str), length(len) { RAPIDJSON_ASSERT(s != 0); }
+
+ GenericStringRef(const GenericStringRef& rhs) : s(rhs.s), length(rhs.length) {}
+
+ GenericStringRef& operator=(const GenericStringRef& rhs) { s = rhs.s; length = rhs.length; }
+
+ //! implicit conversion to plain CharType pointer
+ operator const Ch *() const { return s; }
+
+ const Ch* const s; //!< plain CharType pointer
+ const SizeType length; //!< length of the string (excluding the trailing NULL terminator)
+
+private:
+ //! Disallow construction from non-const array
+ template
+ GenericStringRef(CharType (&str)[N]) /* = delete */;
+};
+
+//! Mark a character pointer as constant string
+/*! Mark a plain character pointer as a "string literal". This function
+ can be used to avoid copying a character string to be referenced as a
+ value in a JSON GenericValue object, if the string's lifetime is known
+ to be valid long enough.
+ \tparam CharType Character type of the string
+ \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
+ \return GenericStringRef string reference object
+ \relatesalso GenericStringRef
+
+ \see GenericValue::GenericValue(StringRefType), GenericValue::operator=(StringRefType), GenericValue::SetString(StringRefType), GenericValue::PushBack(StringRefType, Allocator&), GenericValue::AddMember
+*/
+template
+inline GenericStringRef StringRef(const CharType* str) {
+ return GenericStringRef(str, internal::StrLen(str));
+}
+
+//! Mark a character pointer as constant string
+/*! Mark a plain character pointer as a "string literal". This function
+ can be used to avoid copying a character string to be referenced as a
+ value in a JSON GenericValue object, if the string's lifetime is known
+ to be valid long enough.
+
+ This version has better performance with supplied length, and also
+ supports string containing null characters.
+
+ \tparam CharType character type of the string
+ \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
+ \param length The length of source string.
+ \return GenericStringRef string reference object
+ \relatesalso GenericStringRef
+*/
+template
+inline GenericStringRef StringRef(const CharType* str, size_t length) {
+ return GenericStringRef(str, SizeType(length));
+}
+
+#if RAPIDJSON_HAS_STDSTRING
+//! Mark a string object as constant string
+/*! Mark a string object (e.g. \c std::string) as a "string literal".
+ This function can be used to avoid copying a string to be referenced as a
+ value in a JSON GenericValue object, if the string's lifetime is known
+ to be valid long enough.
+
+ \tparam CharType character type of the string
+ \param str Constant string, lifetime assumed to be longer than the use of the string in e.g. a GenericValue
+ \return GenericStringRef string reference object
+ \relatesalso GenericStringRef
+ \note Requires the definition of the preprocessor symbol \ref RAPIDJSON_HAS_STDSTRING.
+*/
+template
+inline GenericStringRef StringRef(const std::basic_string& str) {
+ return GenericStringRef(str.data(), SizeType(str.size()));
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericValue type traits
+namespace internal {
+
+template
+struct IsGenericValueImpl : FalseType {};
+
+// select candidates according to nested encoding and allocator types
+template struct IsGenericValueImpl::Type, typename Void::Type>
+ : IsBaseOf, T>::Type {};
+
+// helper to match arbitrary GenericValue instantiations, including derived classes
+template struct IsGenericValue : IsGenericValueImpl::Type {};
+
+} // namespace internal
+
+///////////////////////////////////////////////////////////////////////////////
+// TypeHelper
+
+namespace internal {
+
+template
+struct TypeHelper {};
+
+template
+struct TypeHelper {
+ static bool Is(const ValueType& v) { return v.IsBool(); }
+ static bool Get(const ValueType& v) { return v.GetBool(); }
+ static ValueType& Set(ValueType& v, bool data) { return v.SetBool(data); }
+ static ValueType& Set(ValueType& v, bool data, typename ValueType::AllocatorType&) { return v.SetBool(data); }
+};
+
+template
+struct TypeHelper {
+ static bool Is(const ValueType& v) { return v.IsInt(); }
+ static int Get(const ValueType& v) { return v.GetInt(); }
+ static ValueType& Set(ValueType& v, int data) { return v.SetInt(data); }
+ static ValueType& Set(ValueType& v, int data, typename ValueType::AllocatorType&) { return v.SetInt(data); }
+};
+
+template
+struct TypeHelper {
+ static bool Is(const ValueType& v) { return v.IsUint(); }
+ static unsigned Get(const ValueType& v) { return v.GetUint(); }
+ static ValueType& Set(ValueType& v, unsigned data) { return v.SetUint(data); }
+ static ValueType& Set(ValueType& v, unsigned data, typename ValueType::AllocatorType&) { return v.SetUint(data); }
+};
+
+template
+struct TypeHelper {
+ static bool Is(const ValueType& v) { return v.IsInt64(); }
+ static int64_t Get(const ValueType& v) { return v.GetInt64(); }
+ static ValueType& Set(ValueType& v, int64_t data) { return v.SetInt64(data); }
+ static ValueType& Set(ValueType& v, int64_t data, typename ValueType::AllocatorType&) { return v.SetInt64(data); }
+};
+
+template
+struct TypeHelper {
+ static bool Is(const ValueType& v) { return v.IsUint64(); }
+ static uint64_t Get(const ValueType& v) { return v.GetUint64(); }
+ static ValueType& Set(ValueType& v, uint64_t data) { return v.SetUint64(data); }
+ static ValueType& Set(ValueType& v, uint64_t data, typename ValueType::AllocatorType&) { return v.SetUint64(data); }
+};
+
+template
+struct TypeHelper {
+ static bool Is(const ValueType& v) { return v.IsDouble(); }
+ static double Get(const ValueType& v) { return v.GetDouble(); }
+ static ValueType& Set(ValueType& v, double data) { return v.SetDouble(data); }
+ static ValueType& Set(ValueType& v, double data, typename ValueType::AllocatorType&) { return v.SetDouble(data); }
+};
+
+template
+struct TypeHelper {
+ static bool Is(const ValueType& v) { return v.IsFloat(); }
+ static float Get(const ValueType& v) { return v.GetFloat(); }
+ static ValueType& Set(ValueType& v, float data) { return v.SetFloat(data); }
+ static ValueType& Set(ValueType& v, float data, typename ValueType::AllocatorType&) { return v.SetFloat(data); }
+};
+
+template
+struct TypeHelper {
+ typedef const typename ValueType::Ch* StringType;
+ static bool Is(const ValueType& v) { return v.IsString(); }
+ static StringType Get(const ValueType& v) { return v.GetString(); }
+ static ValueType& Set(ValueType& v, const StringType data) { return v.SetString(typename ValueType::StringRefType(data)); }
+ static ValueType& Set(ValueType& v, const StringType data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
+};
+
+#if RAPIDJSON_HAS_STDSTRING
+template
+struct TypeHelper > {
+ typedef std::basic_string StringType;
+ static bool Is(const ValueType& v) { return v.IsString(); }
+ static StringType Get(const ValueType& v) { return StringType(v.GetString(), v.GetStringLength()); }
+ static ValueType& Set(ValueType& v, const StringType& data, typename ValueType::AllocatorType& a) { return v.SetString(data, a); }
+};
+#endif
+
+template
+struct TypeHelper {
+ typedef typename ValueType::Array ArrayType;
+ static bool Is(const ValueType& v) { return v.IsArray(); }
+ static ArrayType Get(ValueType& v) { return v.GetArray(); }
+ static ValueType& Set(ValueType& v, ArrayType data) { return v = data; }
+ static ValueType& Set(ValueType& v, ArrayType data, typename ValueType::AllocatorType&) { return v = data; }
+};
+
+template
+struct TypeHelper {
+ typedef typename ValueType::ConstArray ArrayType;
+ static bool Is(const ValueType& v) { return v.IsArray(); }
+ static ArrayType Get(const ValueType& v) { return v.GetArray(); }
+};
+
+template
+struct TypeHelper {
+ typedef typename ValueType::Object ObjectType;
+ static bool Is(const ValueType& v) { return v.IsObject(); }
+ static ObjectType Get(ValueType& v) { return v.GetObject(); }
+ static ValueType& Set(ValueType& v, ObjectType data) { return v = data; }
+ static ValueType& Set(ValueType& v, ObjectType data, typename ValueType::AllocatorType&) { v = data; }
+};
+
+template
+struct TypeHelper {
+ typedef typename ValueType::ConstObject ObjectType;
+ static bool Is(const ValueType& v) { return v.IsObject(); }
+ static ObjectType Get(const ValueType& v) { return v.GetObject(); }
+};
+
+} // namespace internal
+
+// Forward declarations
+template class GenericArray;
+template class GenericObject;
+
+///////////////////////////////////////////////////////////////////////////////
+// GenericValue
+
+//! Represents a JSON value. Use Value for UTF8 encoding and default allocator.
+/*!
+ A JSON value can be one of 7 types. This class is a variant type supporting
+ these types.
+
+ Use the Value if UTF8 and default allocator
+
+ \tparam Encoding Encoding of the value. (Even non-string values need to have the same encoding in a document)
+ \tparam Allocator Allocator type for allocating memory of object, array and string.
+*/
+template >
+class GenericValue {
+public:
+ //! Name-value pair in an object.
+ typedef GenericMember Member;
+ typedef Encoding EncodingType; //!< Encoding type from template parameter.
+ typedef Allocator AllocatorType; //!< Allocator type from template parameter.
+ typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding.
+ typedef GenericStringRef StringRefType; //!< Reference to a constant string
+ typedef typename GenericMemberIterator::Iterator MemberIterator; //!< Member iterator for iterating in object.
+ typedef typename GenericMemberIterator::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object.
+ typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array.
+ typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array.
+ typedef GenericValue ValueType; //!< Value type of itself.
+ typedef GenericArray Array;
+ typedef GenericArray ConstArray;
+ typedef GenericObject Object;
+ typedef GenericObject ConstObject;
+
+ //!@name Constructors and destructor.
+ //@{
+
+ //! Default constructor creates a null value.
+ GenericValue() RAPIDJSON_NOEXCEPT : data_() { data_.f.flags = kNullFlag; }
+
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+ //! Move constructor in C++11
+ GenericValue(GenericValue&& rhs) RAPIDJSON_NOEXCEPT : data_(rhs.data_) {
+ rhs.data_.f.flags = kNullFlag; // give up contents
+ }
+#endif
+
+private:
+ //! Copy constructor is not permitted.
+ GenericValue(const GenericValue& rhs);
+
+#if RAPIDJSON_HAS_CXX11_RVALUE_REFS
+ //! Moving from a GenericDocument is not permitted.
+ template
+ GenericValue(GenericDocument&& rhs);
+
+ //! Move assignment from a GenericDocument is not permitted.
+ template
+ GenericValue& operator=(GenericDocument&& rhs);
+#endif
+
+public:
+
+ //! Constructor with JSON value type.
+ /*! This creates a Value of specified type with default content.
+ \param type Type of the value.
+ \note Default content for number is zero.
+ */
+ explicit GenericValue(Type type) RAPIDJSON_NOEXCEPT : data_() {
+ static const uint16_t defaultFlags[7] = {
+ kNullFlag, kFalseFlag, kTrueFlag, kObjectFlag, kArrayFlag, kShortStringFlag,
+ kNumberAnyFlag
+ };
+ RAPIDJSON_ASSERT(type <= kNumberType);
+ data_.f.flags = defaultFlags[type];
+
+ // Use ShortString to store empty string.
+ if (type == kStringType)
+ data_.ss.SetLength(0);
+ }
+
+ //! Explicit copy constructor (with allocator)
+ /*! Creates a copy of a Value by using the given Allocator
+ \tparam SourceAllocator allocator of \c rhs
+ \param rhs Value to copy from (read-only)
+ \param allocator Allocator for allocating copied elements and buffers. Commonly use GenericDocument::GetAllocator().
+ \see CopyFrom()
+ */
+ template< typename SourceAllocator >
+ GenericValue(const GenericValue& rhs, Allocator & allocator);
+
+ //! Constructor for boolean value.
+ /*! \param b Boolean value
+ \note This constructor is limited to \em real boolean values and rejects
+ implicitly converted types like arbitrary pointers. Use an explicit cast
+ to \c bool, if you want to construct a boolean JSON value in such cases.
+ */
+#ifndef RAPIDJSON_DOXYGEN_RUNNING // hide SFINAE from Doxygen
+ template
+ explicit GenericValue(T b, RAPIDJSON_ENABLEIF((internal::IsSame))) RAPIDJSON_NOEXCEPT // See #472
+#else
+ explicit GenericValue(bool b) RAPIDJSON_NOEXCEPT
+#endif
+ : data_() {
+ // safe-guard against failing SFINAE
+ RAPIDJSON_STATIC_ASSERT((internal::IsSame::Value));
+ data_.f.flags = b ? kTrueFlag : kFalseFlag;
+ }
+
+ //! Constructor for int value.
+ explicit GenericValue(int i) RAPIDJSON_NOEXCEPT : data_() {
+ data_.n.i64 = i;
+ data_.f.flags = (i >= 0) ? (kNumberIntFlag | kUintFlag | kUint64Flag) : kNumberIntFlag;
+ }
+
+ //! Constructor for unsigned value.
+ explicit GenericValue(unsigned u) RAPIDJSON_NOEXCEPT : data_() {
+ data_.n.u64 = u;
+ data_.f.flags = (u & 0x80000000) ? kNumberUintFlag : (kNumberUintFlag | kIntFlag | kInt64Flag);
+ }
+
+ //! Constructor for int64_t value.
+ explicit GenericValue(int64_t i64) RAPIDJSON_NOEXCEPT : data_() {
+ data_.n.i64 = i64;
+ data_.f.flags = kNumberInt64Flag;
+ if (i64 >= 0) {
+ data_.f.flags |= kNumberUint64Flag;
+ if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x00000000)))
+ data_.f.flags |= kUintFlag;
+ if (!(static_cast(i64) & RAPIDJSON_UINT64_C2(0xFFFFFFFF, 0x80000000)))
+ data_.f.flags |= kIntFlag;
+ }
+ else if (i64 >= static_cast