From d8fdd6eb3866c069c7500ae333f300779ed2a939 Mon Sep 17 00:00:00 2001 From: beuschl Date: Sun, 2 Dec 2018 09:13:33 +0100 Subject: [PATCH 1/6] C++11 enabled in makefiles --- makefile.mingw | 2 +- makefile.unix | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/makefile.mingw b/makefile.mingw index 229bdac..e278d39 100644 --- a/makefile.mingw +++ b/makefile.mingw @@ -28,7 +28,7 @@ LIBS= \ DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE DEBUGFLAGS=-g -CFLAGS=-static -static-libgcc -static-libstdc++ -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) +CFLAGS=-static -static-libgcc -static-libstdc++ -std=c++11 -O2 -w -Wno-invalid-offsetof -Wformat $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) LIBS +=-l kernel32 -l user32 -l gdi32 -l comdlg32 -l winspool -l winmm -l shell32 -l comctl32 -l ole32 -l oleaut32 -l uuid -l rpcrt4 -l advapi32 -l ws2_32 -l shlwapi HEADERS = $(wildcard *.h) diff --git a/makefile.unix b/makefile.unix index de50360..5f0173b 100644 --- a/makefile.unix +++ b/makefile.unix @@ -24,7 +24,7 @@ LIBS += \ DEBUGFLAGS=-g -ggdb CXXFLAGS=-O2 -xCXXFLAGS=-pthread -static-libgcc -static-libstdc++ -Wall -Wextra -Wno-sign-compare -Wno-invalid-offsetof -Wno-unused-parameter -Wformat -Wformat-security \ +xCXXFLAGS=-pthread -static-libgcc -static-libstdc++ -std=c++11 -Wall -Wextra -Wno-sign-compare -Wno-invalid-offsetof -Wno-unused-parameter -Wformat -Wformat-security \ $(DEBUGFLAGS) $(DEFS) $(CXXFLAGS) HEADERS = $(wildcard *.h) From 4d20c7ad858ebce3efb847f60cd0029cafc6fbdb Mon Sep 17 00:00:00 2001 From: beuschl Date: Sun, 2 Dec 2018 09:14:11 +0100 Subject: [PATCH 2/6] Block refactoring --- src/LLP/block.h | 48 +++++++++++++++++++++++++++++++++ src/LLP/daemon.cpp | 57 ++++++++++++++++++++++------------------ src/LLP/daemon.h | 4 +-- src/LLP/pool.cpp | 21 ++++++--------- src/LLP/pool.h | 17 +++++------- src/core.cpp | 2 +- src/core.h | 33 +---------------------- src/hash/uint1024.h | 5 ++++ vs2017/PrimePool.vcxproj | 1 + 9 files changed, 104 insertions(+), 84 deletions(-) create mode 100644 src/LLP/block.h diff --git a/src/LLP/block.h b/src/LLP/block.h new file mode 100644 index 0000000..cbab2b8 --- /dev/null +++ b/src/LLP/block.h @@ -0,0 +1,48 @@ +#ifndef NEXUS_LLP_BLOCK_H +#define NEXUS_LLP_BLOCK_H + +#include "../hash/uint1024.h" +#include "../hash/templates.h" +#include + +#define BEGIN(a) ((char*)&(a)) +#define END(a) ((char*)&((&(a))[1])) + +namespace LLP { + + /** Mock Class for Building Block Hash. **/ + class CBlock + { + public: + using Uptr = std::unique_ptr; + using Sptr = std::shared_ptr; + + /** Begin of Header. BEGIN(nVersion) **/ + unsigned int nVersion; + uint1024 hashPrevBlock; + uint512 hashMerkleRoot; + unsigned int nChannel; + unsigned int nHeight; + unsigned int nBits; + uint64 nNonce; + /** End of Header. END(nNonce). + All the components to build an SK1024 Block Hash. **/ + + + CBlock() + { + nVersion = 0; + hashPrevBlock = 0; + hashMerkleRoot = 0; + nChannel = 0; + nHeight = 0; + nBits = 0; + nNonce = 0; + } + + inline uint1024 GetHash() const { return SK1024(BEGIN(nVersion), END(nBits)); } + inline uint1024 GetPrime() const { return GetHash() + nNonce; } + }; +} + +#endif \ No newline at end of file diff --git a/src/LLP/daemon.cpp b/src/LLP/daemon.cpp index 7109761..865c93a 100644 --- a/src/LLP/daemon.cpp +++ b/src/LLP/daemon.cpp @@ -50,9 +50,9 @@ namespace LLP } - Core::CBlock* DaemonConnection::DeserializeBlock(std::vector DATA) + CBlock::Uptr DaemonConnection::DeserializeBlock(std::vector const& DATA) { - Core::CBlock* BLOCK = new Core::CBlock(); + CBlock::Uptr BLOCK = std::make_unique(); BLOCK->nVersion = bytes2uint(std::vector(DATA.begin(), DATA.begin() + 4)); BLOCK->hashPrevBlock.SetBytes (std::vector(DATA.begin() + 4, DATA.begin() + 132)); @@ -208,32 +208,38 @@ namespace LLP /** Add a Block to the Stack if it is received by the Daemon Connection. **/ else if(PACKET.HEADER == CLIENT->BLOCK_DATA) { - Core::CBlock* BLOCK = CLIENT->DeserializeBlock(PACKET.DATA); - if(BLOCK->nHeight == Core::nBestHeight) + CBlock::Uptr BLOCK = CLIENT->DeserializeBlock(PACKET.DATA); + /** If the Block isn't less than 1024-bits request a new one **/ + if(BLOCK->GetHash().high_bits(0x80000000)) { - { LOCK(CONNECTION_MUTEX); - for(int nIndex = 0; nIndex < CONNECTIONS.size(); nIndex++) - { - if(!CONNECTIONS[nIndex]) - continue; - - if(CONNECTIONS[nIndex]->nBlocksWaiting > 0) + printf("[DAEMON] Block isn't less than 1024-bits. Request new one on Handle %u\n", ID); + CLIENT->GetBlock(); + } + else + { + if(BLOCK->nHeight == Core::nBestHeight) + { + { LOCK(CONNECTION_MUTEX); + for(int nIndex = 0; nIndex < CONNECTIONS.size(); nIndex++) { - CONNECTIONS[nIndex]->AddBlock(BLOCK); - - //printf("[DAEMON] Block Received Height = %u on Handle %u Assigned to %u\n", nBestHeight, ID, nIndex); - break; + if(!CONNECTIONS[nIndex]) + continue; + + if(CONNECTIONS[nIndex]->nBlocksWaiting > 0) + { + CONNECTIONS[nIndex]->AddBlock(std::move(BLOCK)); + + printf("[DAEMON] Block Received Height = %u on Handle %u Assigned to %u\n", Core::nBestHeight, ID, nIndex); + break; + } } - } + } } - + else + printf("[DAEMON] Block Obsolete Height = %u, Skipping over on Handle %u\n", BLOCK->nHeight, ID); } - else - printf("[DAEMON] Block Obsolete Height = %u, Skipping over on Handle %u\n", BLOCK->nHeight, ID); - } - - } - + } + } /** Don't Request Anything if Waiting for New Round to Reset. **/ if(Core::fCoinbasePending || Core::fSubmittingBlock || Core::fNewRound || fCoinbasePending) @@ -289,7 +295,7 @@ namespace LLP /** Reset the Submission Block Pointer. **/ - CONNECTIONS[nIndex]->SUBMISSION_BLOCK = NULL; + CONNECTIONS[nIndex]->SUBMISSION_BLOCK = nullptr; break; } } @@ -302,9 +308,8 @@ namespace LLP CONNECTIONS[nIndex]->nBlocksWaiting++; CLIENT->GetBlock(); - //CLIENT->GetBlock(); - //printf("[DAEMON] Requesting Block from Daemon Handle %u\n", ID); + printf("[DAEMON] Requesting Block from Daemon Handle %u\n", ID); } } } diff --git a/src/LLP/daemon.h b/src/LLP/daemon.h index 0ecab91..bc0a90f 100644 --- a/src/LLP/daemon.h +++ b/src/LLP/daemon.h @@ -1,8 +1,8 @@ #ifndef COINSHEILD_DAEMON_H #define COINSHIELD_DAEMON_H - #include "types.h" +#include "block.h" #include "../hash/uint1024.h" class Coinbase; @@ -157,7 +157,7 @@ namespace LLP return false; } - Core::CBlock* DeserializeBlock(std::vector DATA); + CBlock::Uptr DeserializeBlock(std::vector const& DATA); }; diff --git a/src/LLP/pool.cpp b/src/LLP/pool.cpp index 32a042d..03c6fb3 100644 --- a/src/LLP/pool.cpp +++ b/src/LLP/pool.cpp @@ -21,22 +21,17 @@ namespace LLP while(!NEW_BLOCKS.empty()) { - Core::CBlock* BLOCK = NEW_BLOCKS.top(); + NEW_BLOCKS.top(); NEW_BLOCKS.pop(); - - delete BLOCK; } - - for(std::map::iterator IT = MAP_BLOCKS.begin(); IT != MAP_BLOCKS.end(); ++ IT) - delete IT->second; MAP_BLOCKS.clear(); } - void PoolConnection::AddBlock(Core::CBlock* BLOCK) + void PoolConnection::AddBlock(CBlock::Uptr BLOCK) { LOCK(BLOCK_MUTEX); - NEW_BLOCKS.push(BLOCK); + NEW_BLOCKS.push(std::move(BLOCK)); nBlocksWaiting--; } @@ -119,15 +114,15 @@ namespace LLP { LOCK(BLOCK_MUTEX); while(!NEW_BLOCKS.empty()) { - Core::CBlock* BLOCK = NEW_BLOCKS.top(); + CBlock::Sptr BLOCK{std::move(NEW_BLOCKS.top())}; NEW_BLOCKS.pop(); /** Add to the block map. **/ MAP_BLOCKS[BLOCK->GetHash()] = BLOCK; - + /** Construct a response packet by serializing the Block. **/ Packet RESPONSE = GetPacket(BLOCK_DATA); - RESPONSE.DATA = SerializeBlock(BLOCK); + RESPONSE.DATA = SerializeBlock(std::move(BLOCK)); RESPONSE.LENGTH = RESPONSE.DATA.size(); this->WritePacket(RESPONSE); @@ -283,7 +278,7 @@ namespace LLP { uint1024 hashPrimeOrigin; hashPrimeOrigin.SetBytes(std::vector(PACKET.DATA.begin(), PACKET.DATA.end() - 8)); - + /** Don't Accept a Share with no Correlated Block. **/ if(!MAP_BLOCKS.count(hashPrimeOrigin)) @@ -450,7 +445,7 @@ namespace LLP } /** Convert the Header of a Block into a Byte Stream for Reading and Writing Across Sockets. **/ - std::vector PoolConnection::SerializeBlock(Core::CBlock* BLOCK) + std::vector PoolConnection::SerializeBlock(CBlock::Sptr BLOCK) { std::vector HASH = BLOCK->GetHash().GetBytes(); std::vector MINIMUM = uint2bytes(Core::nMinimumShare); diff --git a/src/LLP/pool.h b/src/LLP/pool.h index fce352f..e6a3a99 100644 --- a/src/LLP/pool.h +++ b/src/LLP/pool.h @@ -4,9 +4,9 @@ #include #include "types.h" +#include "block.h" #include "../hash/uint1024.h" -namespace Core { class CBlock; } namespace LLP { /** Forward Declarations. **/ @@ -16,8 +16,8 @@ namespace LLP /** Template Connection to be used by LLP Server. **/ class PoolConnection : public Connection { - std::map MAP_BLOCKS; - std::stack NEW_BLOCKS; + std::map MAP_BLOCKS; + std::stack NEW_BLOCKS; DaemonHandle* DAEMON; @@ -64,10 +64,7 @@ namespace LLP PoolConnection( Socket_t SOCKET_IN, DDOS_Filter* DDOS_IN, bool isDDOS) : Connection( SOCKET_IN, DDOS_IN, isDDOS ), BLOCK_TIMER() {} ~PoolConnection() - { - for(std::map::iterator IT = MAP_BLOCKS.begin(); IT != MAP_BLOCKS.end(); ++ IT) - delete IT->second; - + { MAP_BLOCKS.clear(); } @@ -84,13 +81,13 @@ namespace LLP std::string GUID; /** Block Set by Connection if it is Above Difficulty. **/ - Core::CBlock* SUBMISSION_BLOCK = NULL; + CBlock::Sptr SUBMISSION_BLOCK = nullptr; /** Mutex for Modifying Submission Block Pointer. **/ boost::mutex SUBMISSION_MUTEX; /** Add a Block to the Pool Connection Stacks. **/ - void AddBlock(Core::CBlock* BLOCK); + void AddBlock(CBlock::Uptr BLOCK); /** Event Function to Customize Code For Inheriting Class Happening on the LLP Data Threads. **/ void Event(unsigned char EVENT, unsigned int LENGTH = 0); @@ -112,7 +109,7 @@ namespace LLP inline void Respond(unsigned char HEADER) { this->WritePacket(GetPacket(HEADER)); } /** Convert the Header of a Block into a Byte Stream for Reading and Writing Across Sockets. **/ - inline std::vector SerializeBlock(Core::CBlock* BLOCK); + inline std::vector SerializeBlock(CBlock::Sptr BLOCK); }; } diff --git a/src/core.cpp b/src/core.cpp index 778a591..3b042e2 100644 --- a/src/core.cpp +++ b/src/core.cpp @@ -23,7 +23,7 @@ namespace Core /** Coinbase Transaction for this Block. **/ Coinbase cGlobalCoinbase; - std::string POOL_VERSION = "1.0.1"; + std::string POOL_VERSION = "1.0.2"; /** Wallet Connection Variables. **/ diff --git a/src/core.h b/src/core.h index fef0783..6d5723a 100644 --- a/src/core.h +++ b/src/core.h @@ -10,6 +10,7 @@ #endif #include "config.h" +#include class Coinbase; @@ -28,38 +29,6 @@ namespace Core /** Global Best Height Tracker. Keeps track of Current Block. **/ extern unsigned int nBestHeight; - - /** Mock Class for Building Block Hash. **/ - class CBlock - { - public: - - /** Begin of Header. BEGIN(nVersion) **/ - unsigned int nVersion; - uint1024 hashPrevBlock; - uint512 hashMerkleRoot; - unsigned int nChannel; - unsigned int nHeight; - unsigned int nBits; - uint64 nNonce; - /** End of Header. END(nNonce). - All the components to build an SK1024 Block Hash. **/ - - - CBlock() - { - nVersion = 0; - hashPrevBlock = 0; - hashMerkleRoot = 0; - nChannel = 0; - nHeight = 0; - nBits = 0; - nNonce = 0; - } - - inline uint1024 GetHash() const { return SK1024(BEGIN(nVersion), END(nBits)); } - inline CBigNum GetPrime() const { return CBigNum(GetHash() + nNonce); } - }; /** Pool Configuration **/ extern Config CONFIG; diff --git a/src/hash/uint1024.h b/src/hash/uint1024.h index 263c67e..47abc28 100644 --- a/src/hash/uint1024.h +++ b/src/hash/uint1024.h @@ -822,6 +822,11 @@ class uint1024 : public base_uint1024 return *this; } + + unsigned int high_bits(unsigned int mask) + { + return pn[WIDTH - 1] & mask; + } /** This method should only be used to retrieve an uint256 when stored inside an uint1024. This is necessary for for ambiguous function declaration. */ diff --git a/vs2017/PrimePool.vcxproj b/vs2017/PrimePool.vcxproj index 8974a77..4aec887 100644 --- a/vs2017/PrimePool.vcxproj +++ b/vs2017/PrimePool.vcxproj @@ -47,6 +47,7 @@ + From fc9189ff99cdbd7f7e9af96fcac331f445e1270d Mon Sep 17 00:00:00 2001 From: beuschl Date: Sun, 2 Dec 2018 11:18:22 +0100 Subject: [PATCH 3/6] Replaced boost json with nlohmann json --- .gitignore | 3 +- pool.conf.example | 2 +- src/config.cpp | 84 +- src/json/LICENSE.txt | 37 +- src/json/json.hpp | 20274 +++++++++++++++++++++++ src/json/json_spirit.h | 18 - src/json/json_spirit_error_position.h | 54 - src/json/json_spirit_reader.cpp | 137 - src/json/json_spirit_reader.h | 62 - src/json/json_spirit_reader_template.h | 612 - src/json/json_spirit_stream_reader.h | 70 - src/json/json_spirit_utils.h | 61 - src/json/json_spirit_value.cpp | 8 - src/json/json_spirit_value.h | 534 - src/json/json_spirit_writer.cpp | 95 - src/json/json_spirit_writer.h | 50 - src/json/json_spirit_writer_template.h | 248 - src/statscollector.cpp | 4 - src/statscollector.h | 2 - vs2017/PrimePool.vcxproj | 13 +- 20 files changed, 20336 insertions(+), 2032 deletions(-) create mode 100644 src/json/json.hpp delete mode 100644 src/json/json_spirit.h delete mode 100644 src/json/json_spirit_error_position.h delete mode 100644 src/json/json_spirit_reader.cpp delete mode 100644 src/json/json_spirit_reader.h delete mode 100644 src/json/json_spirit_reader_template.h delete mode 100644 src/json/json_spirit_stream_reader.h delete mode 100644 src/json/json_spirit_utils.h delete mode 100644 src/json/json_spirit_value.cpp delete mode 100644 src/json/json_spirit_value.h delete mode 100644 src/json/json_spirit_writer.cpp delete mode 100644 src/json/json_spirit_writer.h delete mode 100644 src/json/json_spirit_writer_template.h diff --git a/.gitignore b/.gitignore index ef853da..d4c816b 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,6 @@ *.P *.bat *.exe -*.filter +*.filters +*.log *.user \ No newline at end of file diff --git a/pool.conf.example b/pool.conf.example index d2f2388..a10a92f 100644 --- a/pool.conf.example +++ b/pool.conf.example @@ -4,7 +4,7 @@ "daemon_threads" : 10, "pool_threads" : 20, - "enable_ddos" : "true", + "enable_ddos" : true, "ddos_rscore" : 20, "ddos_cscore" : 2, "min_share" : 40000000, diff --git a/src/config.cpp b/src/config.cpp index b7aa46f..6ec3d2c 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -1,11 +1,11 @@ #include "config.h" -#include -#include +#include "json/json.hpp" -#include +using json = nlohmann::json; -namespace pt = boost::property_tree; +#include +#include namespace Core { @@ -33,28 +33,28 @@ namespace Core void Config::PrintConfig() { - printf("Configuration: \n"); - printf("-------------\n"); - printf("Wallet IP: %s \n", strWalletIP.c_str()); - printf("Port: %i \n", nPort); + std::cout << "Configuration: " << std::endl; + std::cout << "-------------" << std::endl; + std::cout << "Wallet IP: " << strWalletIP << std::endl; + std::cout << "Port: " << nPort << std::endl; - printf("Daemon Threads: %i \n", nDaemonThreads); - printf("Pool Threads: %i \n", nPoolThreads); + std::cout << "Daemon Threads: " << nDaemonThreads << std::endl; + std::cout << "Pool Threads: " << nPoolThreads << std::endl; - printf("bDDOS: %i \n", bDDOS); - printf("rScore: %i \n", rScore); - printf("cScore: %i \n", cScore); - printf("Min Share Diff: %i \n", nShare); - printf("Pool Fee: %i \n", nPoolFee); + std::cout << "bDDOS: " << bDDOS << std::endl;; + std::cout << "rScore: " << rScore << std::endl; + std::cout << "cScore: " << cScore << std::endl; + std::cout << "Min Share Diff: " << nShare << std::endl; + std::cout << "Pool Fee: " << nPoolFee << std::endl; - printf("Stats DB Server IP: %s \n", strStatsDBServerIP.c_str()); - printf("Stats DB Port: %i \n", nStatsDBServerPort); - printf("Stats DB Username: %s \n", strStatsDBUsername.c_str()); - printf("Stats DB Password: %s \n", strStatsDBPassword.c_str()); - printf("Save Connection Stats Frequency: %i seconds \n", nSaveConnectionStatsFrequency); - printf("Save Connection Stats Series Frequency: %i seconds \n", nSaveConnectionStatsSeriesFrequency); + std::cout << "Stats DB Server IP: " << strStatsDBServerIP << std::endl; + std::cout << "Stats DB Port: " << nStatsDBServerPort << std::endl; + std::cout << "Stats DB Username: " << strStatsDBUsername << std::endl; + std::cout << "Stats DB Password: " << strStatsDBPassword << std::endl; + std::cout << "Save Connection Stats Frequency: " << nSaveConnectionStatsFrequency << " seconds" << std::endl; + std::cout << "Save Connection Stats Series Frequency: " << nSaveConnectionStatsSeriesFrequency << " seconds" << std::endl; - printf("-------------\n"); + std::cout << "-------------" << std::endl; } @@ -62,30 +62,28 @@ namespace Core { bool bSuccess = true; - printf("Reading config file pool.conf\n"); + std::cout << "Reading config file pool.conf" << std::endl; std::ifstream lConfigFile("pool.conf"); - pt::ptree root; - pt::read_json("pool.conf", root); - - strWalletIP = root.get("wallet_ip"); - nPort = root.get("port"); - - nDaemonThreads = root.get("daemon_threads"); - nPoolThreads = root.get("pool_threads"); - bDDOS = root.get("enable_ddos"); - rScore = root.get("ddos_rscore"); - cScore = root.get("ddos_cscore"); - nShare = root.get("min_share"); - nPoolFee = root.get("pool_fee"); - - strStatsDBServerIP = root.get("stats_db_server_ip"); - nStatsDBServerPort = root.get("stats_db_server_port"); - strStatsDBUsername = root.get("stats_db_username"); - strStatsDBPassword = root.get("stats_db_password"); - nSaveConnectionStatsFrequency = root.get("connection_stats_frequency"); - nSaveConnectionStatsSeriesFrequency = root.get("connection_stats_series_frequency"); + json j = json::parse(lConfigFile); + j.at("wallet_ip").get_to(strWalletIP); + j.at("port").get_to(nPort); + + j.at("daemon_threads").get_to(nDaemonThreads); + j.at("pool_threads").get_to(nPoolThreads); + j.at("enable_ddos").get_to(bDDOS); + j.at("ddos_rscore").get_to(rScore); + j.at("ddos_cscore").get_to(cScore); + j.at("min_share").get_to(nShare); + j.at("pool_fee").get_to(nPoolFee); + + j.at("stats_db_server_ip").get_to(strStatsDBServerIP); + j.at("stats_db_server_port").get_to(nStatsDBServerPort); + j.at("stats_db_username").get_to(strStatsDBUsername); + j.at("stats_db_password").get_to(strStatsDBPassword); + j.at("connection_stats_frequency").get_to(nSaveConnectionStatsFrequency); + j.at("connection_stats_series_frequency").get_to(nSaveConnectionStatsSeriesFrequency); PrintConfig(); // TODO Need to add exception handling here and set bSuccess appropriately diff --git a/src/json/LICENSE.txt b/src/json/LICENSE.txt index 797d536..d0bb630 100644 --- a/src/json/LICENSE.txt +++ b/src/json/LICENSE.txt @@ -1,24 +1,21 @@ -The MIT License +MIT License -Copyright (c) 2007 - 2009 John W. Wilkinson +Copyright (c) 2013-2018 Niels Lohmann -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: +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 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. +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. \ No newline at end of file diff --git a/src/json/json.hpp b/src/json/json.hpp new file mode 100644 index 0000000..1e7cf51 --- /dev/null +++ b/src/json/json.hpp @@ -0,0 +1,20274 @@ +/* + __ _____ _____ _____ + __| | __| | | | JSON for Modern C++ +| | |__ | | | | | | version 3.4.0 +|_____|_____|_____|_|___| https://github.com/nlohmann/json + +Licensed under the MIT License . +SPDX-License-Identifier: MIT +Copyright (c) 2013-2018 Niels Lohmann . + +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. +*/ + +#ifndef NLOHMANN_JSON_HPP +#define NLOHMANN_JSON_HPP + +#define NLOHMANN_JSON_VERSION_MAJOR 3 +#define NLOHMANN_JSON_VERSION_MINOR 4 +#define NLOHMANN_JSON_VERSION_PATCH 0 + +#include // all_of, find, for_each +#include // assert +#include // and, not, or +#include // nullptr_t, ptrdiff_t, size_t +#include // hash, less +#include // initializer_list +#include // istream, ostream +#include // iterator_traits, random_access_iterator_tag +#include // accumulate +#include // string, stoi, to_string +#include // declval, forward, move, pair, swap + +// #include +#ifndef NLOHMANN_JSON_FWD_HPP +#define NLOHMANN_JSON_FWD_HPP + +#include // int64_t, uint64_t +#include // map +#include // allocator +#include // string +#include // vector + +/*! +@brief namespace for Niels Lohmann +@see https://github.com/nlohmann +@since version 1.0.0 +*/ +namespace nlohmann +{ +/*! +@brief default JSONSerializer template argument + +This serializer ignores the template arguments and uses ADL +([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) +for serialization. +*/ +template +struct adl_serializer; + +template class ObjectType = + std::map, + template class ArrayType = std::vector, + class StringType = std::string, class BooleanType = bool, + class NumberIntegerType = std::int64_t, + class NumberUnsignedType = std::uint64_t, + class NumberFloatType = double, + template class AllocatorType = std::allocator, + template class JSONSerializer = + adl_serializer> +class basic_json; + +/*! +@brief JSON Pointer + +A JSON pointer defines a string syntax for identifying a specific value +within a JSON document. It can be used with functions `at` and +`operator[]`. Furthermore, JSON pointers are the base for JSON patches. + +@sa [RFC 6901](https://tools.ietf.org/html/rfc6901) + +@since version 2.0.0 +*/ +template +class json_pointer; + +/*! +@brief default JSON class + +This type is the default specialization of the @ref basic_json class which +uses the standard template types. + +@since version 1.0.0 +*/ +using json = basic_json<>; +} // namespace nlohmann + +#endif + +// #include + + +// This file contains all internal macro definitions +// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them + +// exclude unsupported compilers +#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) + #if defined(__clang__) + #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 + #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) + #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 + #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" + #endif + #endif +#endif + +// disable float-equal warnings on GCC/clang +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wfloat-equal" +#endif + +// disable documentation warnings on clang +#if defined(__clang__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wdocumentation" +#endif + +// allow for portable deprecation warnings +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #define JSON_DEPRECATED __attribute__((deprecated)) +#elif defined(_MSC_VER) + #define JSON_DEPRECATED __declspec(deprecated) +#else + #define JSON_DEPRECATED +#endif + +// allow to disable exceptions +#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) + #define JSON_THROW(exception) throw exception + #define JSON_TRY try + #define JSON_CATCH(exception) catch(exception) + #define JSON_INTERNAL_CATCH(exception) catch(exception) +#else + #define JSON_THROW(exception) std::abort() + #define JSON_TRY if(true) + #define JSON_CATCH(exception) if(false) + #define JSON_INTERNAL_CATCH(exception) if(false) +#endif + +// override exception macros +#if defined(JSON_THROW_USER) + #undef JSON_THROW + #define JSON_THROW JSON_THROW_USER +#endif +#if defined(JSON_TRY_USER) + #undef JSON_TRY + #define JSON_TRY JSON_TRY_USER +#endif +#if defined(JSON_CATCH_USER) + #undef JSON_CATCH + #define JSON_CATCH JSON_CATCH_USER + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_CATCH_USER +#endif +#if defined(JSON_INTERNAL_CATCH_USER) + #undef JSON_INTERNAL_CATCH + #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER +#endif + +// manual branch prediction +#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__) + #define JSON_LIKELY(x) __builtin_expect(!!(x), 1) + #define JSON_UNLIKELY(x) __builtin_expect(!!(x), 0) +#else + #define JSON_LIKELY(x) x + #define JSON_UNLIKELY(x) x +#endif + +// C++ language standard detection +#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 + #define JSON_HAS_CPP_17 + #define JSON_HAS_CPP_14 +#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) + #define JSON_HAS_CPP_14 +#endif + +/*! +@brief macro to briefly define a mapping between an enum and JSON +@def NLOHMANN_JSON_SERIALIZE_ENUM +@since version 3.4.0 +*/ +#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ + template \ + inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [e](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.first == e; \ + }); \ + j = ((it != std::end(m)) ? it : std::begin(m))->second; \ + } \ + template \ + inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ + { \ + static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ + static const std::pair m[] = __VA_ARGS__; \ + auto it = std::find_if(std::begin(m), std::end(m), \ + [j](const std::pair& ej_pair) -> bool \ + { \ + return ej_pair.second == j; \ + }); \ + e = ((it != std::end(m)) ? it : std::begin(m))->first; \ + } + +// Ugly macros to avoid uglier copy-paste when specializing basic_json. They +// may be removed in the future once the class is split. + +#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ + template class ObjectType, \ + template class ArrayType, \ + class StringType, class BooleanType, class NumberIntegerType, \ + class NumberUnsignedType, class NumberFloatType, \ + template class AllocatorType, \ + template class JSONSerializer> + +#define NLOHMANN_BASIC_JSON_TPL \ + basic_json + +// #include + + +#include // not +#include // size_t +#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type + +namespace nlohmann +{ +namespace detail +{ +// alias templates to reduce boilerplate +template +using enable_if_t = typename std::enable_if::type; + +template +using uncvref_t = typename std::remove_cv::type>::type; + +// implementation of C++14 index_sequence and affiliates +// source: https://stackoverflow.com/a/32223343 +template +struct index_sequence +{ + using type = index_sequence; + using value_type = std::size_t; + static constexpr std::size_t size() noexcept + { + return sizeof...(Ints); + } +}; + +template +struct merge_and_renumber; + +template +struct merge_and_renumber, index_sequence> + : index_sequence < I1..., (sizeof...(I1) + I2)... > {}; + +template +struct make_index_sequence + : merge_and_renumber < typename make_index_sequence < N / 2 >::type, + typename make_index_sequence < N - N / 2 >::type > {}; + +template<> struct make_index_sequence<0> : index_sequence<> {}; +template<> struct make_index_sequence<1> : index_sequence<0> {}; + +template +using index_sequence_for = make_index_sequence; + +// dispatch utility (taken from ranges-v3) +template struct priority_tag : priority_tag < N - 1 > {}; +template<> struct priority_tag<0> {}; + +// taken from ranges-v3 +template +struct static_const +{ + static constexpr T value{}; +}; + +template +constexpr T static_const::value; +} // namespace detail +} // namespace nlohmann + +// #include + + +#include // not +#include // numeric_limits +#include // false_type, is_constructible, is_integral, is_same, true_type +#include // declval + +// #include + +// #include + +// #include + + +#include + +// #include + + +namespace nlohmann +{ +namespace detail +{ +template struct make_void +{ + using type = void; +}; +template using void_t = typename make_void::type; +} // namespace detail +} // namespace nlohmann + + +// http://en.cppreference.com/w/cpp/experimental/is_detected +namespace nlohmann +{ +namespace detail +{ +struct nonesuch +{ + nonesuch() = delete; + ~nonesuch() = delete; + nonesuch(nonesuch const&) = delete; + void operator=(nonesuch const&) = delete; +}; + +template class Op, + class... Args> +struct detector +{ + using value_t = std::false_type; + using type = Default; +}; + +template class Op, class... Args> +struct detector>, Op, Args...> +{ + using value_t = std::true_type; + using type = Op; +}; + +template