diff --git a/.gitmodules b/.gitmodules index 1045506..8b8595a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "external/keccak"] path = external/keccak url = https://github.com/gvanas/KeccakCodePackage +[submodule "external/rapidjson"] + path = external/rapidjson + url = https://github.com/Tencent/rapidjson diff --git a/CMakeLists.txt b/CMakeLists.txt index c663c7a..f437d51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -65,7 +65,7 @@ configure_file(cmake/version.hpp.in file(GLOB_RECURSE PROJECT_SOURCE_FILES ${PROJECT_SOURCE_DIR}/*.cpp) include_directories("${PROJECT_INCLUDE_DIR}") -include_directories("external/json/src") +include_directories("external/rapidjson/include") ########## DEPENDENCIES ########## diff --git a/external/rapidjson b/external/rapidjson new file mode 160000 index 0000000..67a17cf --- /dev/null +++ b/external/rapidjson @@ -0,0 +1 @@ +Subproject commit 67a17cfdbc25ff1fc8d01714be87e242b03a4cc9 diff --git a/include/iota/api/requests/add_neighbors.hpp b/include/iota/api/requests/add_neighbors.hpp index 9cdb948..509f28c 100644 --- a/include/iota/api/requests/add_neighbors.hpp +++ b/include/iota/api/requests/add_neighbors.hpp @@ -27,6 +27,8 @@ #include +#include + namespace IOTA { namespace API { @@ -60,7 +62,7 @@ class AddNeighbors : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/attach_to_tangle.hpp b/include/iota/api/requests/attach_to_tangle.hpp index e9fb7f0..393797b 100644 --- a/include/iota/api/requests/attach_to_tangle.hpp +++ b/include/iota/api/requests/attach_to_tangle.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -74,7 +76,7 @@ class AttachToTangle : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/base.hpp b/include/iota/api/requests/base.hpp index 73ffb23..68b745a 100644 --- a/include/iota/api/requests/base.hpp +++ b/include/iota/api/requests/base.hpp @@ -25,9 +25,9 @@ #pragma once -#include +#include -using json = nlohmann::json; +#include namespace IOTA { @@ -58,7 +58,7 @@ class Base { * * @param data where to store serialisation. */ - virtual void serialize(json& data) const; + virtual void serialize(Utils::json& data) const; public: /** diff --git a/include/iota/api/requests/broadcast_transactions.hpp b/include/iota/api/requests/broadcast_transactions.hpp index 9b237d6..3b7a210 100644 --- a/include/iota/api/requests/broadcast_transactions.hpp +++ b/include/iota/api/requests/broadcast_transactions.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -62,7 +64,7 @@ class BroadcastTransactions : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/find_transactions.hpp b/include/iota/api/requests/find_transactions.hpp index 37ac579..83b67a4 100644 --- a/include/iota/api/requests/find_transactions.hpp +++ b/include/iota/api/requests/find_transactions.hpp @@ -73,7 +73,7 @@ class FindTransactions : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/get_balances.hpp b/include/iota/api/requests/get_balances.hpp index 0d312a8..8029f20 100644 --- a/include/iota/api/requests/get_balances.hpp +++ b/include/iota/api/requests/get_balances.hpp @@ -67,7 +67,7 @@ class GetBalances : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/get_inclusion_states.hpp b/include/iota/api/requests/get_inclusion_states.hpp index 17f1947..410d026 100644 --- a/include/iota/api/requests/get_inclusion_states.hpp +++ b/include/iota/api/requests/get_inclusion_states.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -68,7 +70,7 @@ class GetInclusionStates : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/get_transactions_to_approve.hpp b/include/iota/api/requests/get_transactions_to_approve.hpp index 3b899b2..8132f57 100644 --- a/include/iota/api/requests/get_transactions_to_approve.hpp +++ b/include/iota/api/requests/get_transactions_to_approve.hpp @@ -63,7 +63,7 @@ class GetTransactionsToApprove : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/get_trytes.hpp b/include/iota/api/requests/get_trytes.hpp index c8f2384..1b819a5 100644 --- a/include/iota/api/requests/get_trytes.hpp +++ b/include/iota/api/requests/get_trytes.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -62,7 +64,7 @@ class GetTrytes : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/remove_neighbors.hpp b/include/iota/api/requests/remove_neighbors.hpp index 4e425e2..99ae012 100644 --- a/include/iota/api/requests/remove_neighbors.hpp +++ b/include/iota/api/requests/remove_neighbors.hpp @@ -27,6 +27,8 @@ #include +#include + namespace IOTA { namespace API { @@ -61,7 +63,7 @@ class RemoveNeighbors : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/requests/store_transactions.hpp b/include/iota/api/requests/store_transactions.hpp index c757919..865987c 100644 --- a/include/iota/api/requests/store_transactions.hpp +++ b/include/iota/api/requests/store_transactions.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -62,7 +64,7 @@ class StoreTransactions : public Base { * * @param data where to store serialisation. */ - void serialize(json& data) const override; + void serialize(Utils::json& data) const override; public: /** diff --git a/include/iota/api/responses/add_neighbors.hpp b/include/iota/api/responses/add_neighbors.hpp index 3cc4dff..014f42e 100644 --- a/include/iota/api/responses/add_neighbors.hpp +++ b/include/iota/api/responses/add_neighbors.hpp @@ -55,7 +55,7 @@ class AddNeighbors : public Base { * * @param res json to be used for deserialization. */ - explicit AddNeighbors(const json& res); + explicit AddNeighbors(const Utils::json& res); /** * Default dtor. @@ -68,7 +68,7 @@ class AddNeighbors : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/attach_to_tangle.hpp b/include/iota/api/responses/attach_to_tangle.hpp index 7e5f9e8..4d5e49a 100644 --- a/include/iota/api/responses/attach_to_tangle.hpp +++ b/include/iota/api/responses/attach_to_tangle.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -62,7 +64,7 @@ class AttachToTangle : public Base { * * @param res json to be used for deserialization. */ - explicit AttachToTangle(const json& res); + explicit AttachToTangle(const Utils::json& res); /** * Default dtor. @@ -75,7 +77,7 @@ class AttachToTangle : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/base.hpp b/include/iota/api/responses/base.hpp index 562aa9b..a10057f 100644 --- a/include/iota/api/responses/base.hpp +++ b/include/iota/api/responses/base.hpp @@ -27,9 +27,7 @@ #include -#include - -using json = nlohmann::json; +#include namespace IOTA { @@ -54,7 +52,7 @@ class Base { * * @param res json to be used for deserialization. */ - explicit Base(const json& res); + explicit Base(const Utils::json& res); /** * Default dtor. @@ -67,7 +65,7 @@ class Base { * * @param res json data to be used for deserialization. */ - virtual void deserialize(const json& res); + virtual void deserialize(const Utils::json& res); public: /** diff --git a/include/iota/api/responses/find_transactions.hpp b/include/iota/api/responses/find_transactions.hpp index 461f4c1..6f215a6 100644 --- a/include/iota/api/responses/find_transactions.hpp +++ b/include/iota/api/responses/find_transactions.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -58,7 +60,7 @@ class FindTransactions : public Base { * * @param res json to be used for deserialization. */ - explicit FindTransactions(const json& res); + explicit FindTransactions(const Utils::json& res); /** * Default dtor. @@ -71,7 +73,7 @@ class FindTransactions : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/get_account_data.hpp b/include/iota/api/responses/get_account_data.hpp index 0c986ce..e1fa85b 100644 --- a/include/iota/api/responses/get_account_data.hpp +++ b/include/iota/api/responses/get_account_data.hpp @@ -29,6 +29,8 @@ #include #include +#include + namespace IOTA { namespace API { diff --git a/include/iota/api/responses/get_balances.hpp b/include/iota/api/responses/get_balances.hpp index 2873cfa..6d7331a 100644 --- a/include/iota/api/responses/get_balances.hpp +++ b/include/iota/api/responses/get_balances.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -60,7 +62,7 @@ class GetBalances : public Base { * * @param res json to be used for deserialization. */ - explicit GetBalances(const json& res); + explicit GetBalances(const Utils::json& res); /** * Default dtor. @@ -73,7 +75,7 @@ class GetBalances : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/get_balances_and_format.hpp b/include/iota/api/responses/get_balances_and_format.hpp index 3378442..19fd9c9 100644 --- a/include/iota/api/responses/get_balances_and_format.hpp +++ b/include/iota/api/responses/get_balances_and_format.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { diff --git a/include/iota/api/responses/get_bundle.hpp b/include/iota/api/responses/get_bundle.hpp index 8fe75a7..a8565a2 100644 --- a/include/iota/api/responses/get_bundle.hpp +++ b/include/iota/api/responses/get_bundle.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { diff --git a/include/iota/api/responses/get_inclusion_states.hpp b/include/iota/api/responses/get_inclusion_states.hpp index f888e1c..8b49679 100644 --- a/include/iota/api/responses/get_inclusion_states.hpp +++ b/include/iota/api/responses/get_inclusion_states.hpp @@ -27,6 +27,8 @@ #include +#include + namespace IOTA { namespace API { @@ -59,7 +61,7 @@ class GetInclusionStates : public Base { * * @param res json to be used for deserialization. */ - explicit GetInclusionStates(const json& res); + explicit GetInclusionStates(const Utils::json& res); /** * Default dtor. @@ -72,7 +74,7 @@ class GetInclusionStates : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/get_neighbors.hpp b/include/iota/api/responses/get_neighbors.hpp index e51e09b..f5e5135 100644 --- a/include/iota/api/responses/get_neighbors.hpp +++ b/include/iota/api/responses/get_neighbors.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -56,7 +58,7 @@ class GetNeighbors : public Base { * * @param res json to be used for deserialization. */ - explicit GetNeighbors(const json& res); + explicit GetNeighbors(const Utils::json& res); /** * Default dtor. @@ -69,7 +71,7 @@ class GetNeighbors : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/get_node_info.hpp b/include/iota/api/responses/get_node_info.hpp index 8de22dd..a7259a3 100644 --- a/include/iota/api/responses/get_node_info.hpp +++ b/include/iota/api/responses/get_node_info.hpp @@ -80,7 +80,7 @@ class GetNodeInfo : public Base { * * @param res json to be used for deserialization. */ - explicit GetNodeInfo(const json& res); + explicit GetNodeInfo(const Utils::json& res); /** * Default dtor. @@ -93,7 +93,7 @@ class GetNodeInfo : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/get_tips.hpp b/include/iota/api/responses/get_tips.hpp index b70d2f6..8952041 100644 --- a/include/iota/api/responses/get_tips.hpp +++ b/include/iota/api/responses/get_tips.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -55,7 +57,7 @@ class GetTips : public Base { * * @param res json to be used for deserialization. */ - explicit GetTips(const json& res); + explicit GetTips(const Utils::json& res); /** * Default dtor. @@ -68,7 +70,7 @@ class GetTips : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/get_transactions_to_approve.hpp b/include/iota/api/responses/get_transactions_to_approve.hpp index f63751d..f2e856e 100644 --- a/include/iota/api/responses/get_transactions_to_approve.hpp +++ b/include/iota/api/responses/get_transactions_to_approve.hpp @@ -60,7 +60,7 @@ class GetTransactionsToApprove : public Base { * * @param res json to be used for deserialization. */ - explicit GetTransactionsToApprove(const json& res); + explicit GetTransactionsToApprove(const Utils::json& res); /** * Default dtor. @@ -73,7 +73,7 @@ class GetTransactionsToApprove : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/get_transfers.hpp b/include/iota/api/responses/get_transfers.hpp index 46d80f0..d3945d7 100644 --- a/include/iota/api/responses/get_transfers.hpp +++ b/include/iota/api/responses/get_transfers.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { diff --git a/include/iota/api/responses/get_trytes.hpp b/include/iota/api/responses/get_trytes.hpp index 0684b21..a76b391 100644 --- a/include/iota/api/responses/get_trytes.hpp +++ b/include/iota/api/responses/get_trytes.hpp @@ -28,6 +28,8 @@ #include #include +#include + namespace IOTA { namespace API { @@ -56,7 +58,7 @@ class GetTrytes : public Base { * * @param res json to be used for deserialization. */ - explicit GetTrytes(const json& res); + explicit GetTrytes(const Utils::json& res); /** * Default dtor. @@ -69,7 +71,7 @@ class GetTrytes : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/remove_neighbors.hpp b/include/iota/api/responses/remove_neighbors.hpp index 3862f47..d0547ae 100644 --- a/include/iota/api/responses/remove_neighbors.hpp +++ b/include/iota/api/responses/remove_neighbors.hpp @@ -55,7 +55,7 @@ class RemoveNeighbors : public Base { * * @param res json to be used for deserialization. */ - explicit RemoveNeighbors(const json& res); + explicit RemoveNeighbors(const Utils::json& res); /** * Default dtor. @@ -68,7 +68,7 @@ class RemoveNeighbors : public Base { * * @param res json data to be used for deserialization. */ - void deserialize(const json& res) override; + void deserialize(const Utils::json& res) override; public: /** diff --git a/include/iota/api/responses/replay_bundle.hpp b/include/iota/api/responses/replay_bundle.hpp index 47b4c1b..f39c155 100644 --- a/include/iota/api/responses/replay_bundle.hpp +++ b/include/iota/api/responses/replay_bundle.hpp @@ -27,6 +27,8 @@ #include +#include + namespace IOTA { namespace API { diff --git a/include/iota/api/responses/send_transfer.hpp b/include/iota/api/responses/send_transfer.hpp index cebf23a..d9a1cd1 100644 --- a/include/iota/api/responses/send_transfer.hpp +++ b/include/iota/api/responses/send_transfer.hpp @@ -27,6 +27,8 @@ #include +#include + namespace IOTA { namespace API { diff --git a/include/iota/api/service.hpp b/include/iota/api/service.hpp index 6debb08..8417d02 100644 --- a/include/iota/api/service.hpp +++ b/include/iota/api/service.hpp @@ -26,7 +26,6 @@ #pragma once #include -#include #include #include @@ -34,8 +33,7 @@ #include #include #include - -using json = nlohmann::json; +#include namespace IOTA { @@ -71,11 +69,11 @@ class Service { Response request(Args&&... args) const { auto request = Request{ args... }; - json data; + Utils::json data; request.serialize(data); auto url = cpr::Url{ "http://" + host_ + ":" + std::to_string(port_) }; - auto body = cpr::Body{ data.dump() }; + auto body = cpr::Body{ data.dumps() }; auto headers = cpr::Header{ { "Content-Type", "application/json" }, { "Content-Length", std::to_string(body.size()) }, { "X-IOTA-API-Version", APIVersion } }; @@ -84,14 +82,13 @@ class Service { if (res.error.code != cpr::ErrorCode::OK) throw Errors::Network(res.error.message); - json resJson; std::string error; try { - resJson = json::parse(res.text); + data.loads(res.text); - if (resJson.count("error")) { - error = resJson["error"].get(); + if (data.has("error")) { + error = data.getString("error"); } } catch (const std::runtime_error&) { if (res.elapsed >= timeout_) { @@ -104,7 +101,7 @@ class Service { Response response; switch (res.status_code) { case 200: - return Response{ resJson }; + return Response{ data }; case 400: throw Errors::BadRequest(error); case 401: @@ -127,10 +124,12 @@ class Service { * Host of the node. */ std::string host_; + /** * Port of the node. */ unsigned int port_; + /** * Timeout for requests. */ diff --git a/include/iota/utils/json.hpp b/include/iota/utils/json.hpp new file mode 100644 index 0000000..172ec4e --- /dev/null +++ b/include/iota/utils/json.hpp @@ -0,0 +1,218 @@ +// +// MIT License +// +// Copyright (c) 2017-2018 Thibault Martinez and Simon Ninon +// +// 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. +// +// + +#pragma once + +#include +#include +#include + +#include +#include +#include +#include + +namespace IOTA { + +namespace Utils { + +/** + * json 3rd party library wrapper + * hides some internal mechanisms related to the json library + * also makes it easier to switch from one libary to another in the future + */ +class json { +public: + /** + * Default ctor + */ + json(void); + + /** + * Default dtor + */ + ~json(void) = default; + + /** + * Move constructor + */ + json(json&&) = default; + + /** + * Move operator + */ + json& operator=(json&&) = default; + + /** + * Disabled copy constructor to ensure memory efficiency + */ + json(const json&) = delete; + + /** + * Disabled assignment operator to ensure memory efficiency + */ + json& operator=(const json&) = delete; + +private: + /** + * ctor from json value + * move the json value + */ + json(const rapidjson::Value& val); + +public: + /** + * parse the given json string and loads the content in the current object + * @param json_str the json string to be parsed + */ + void loads(const std::string& json_str); + + /** + * convert the json object into a json string + * @return the converted json string + */ + std::string dumps(void) const; + +public: + /** + * check key existence in json object + * @param the key to check + * @return whether the object contains the given key + */ + bool has(const std::string& key) const; + +public: + /** + * set the key with the integer value + * @param key the key to be set + * @param value the value to set the key with + */ + void set(const std::string& key, int64_t value); + + /** + * set the key with the string value + * @param key the key to be set + * @param value the value to set the key with + */ + void set(const std::string& key, const std::string& value); + + /** + * set the key with the string array value + * @param key the key to be set + * @param value the value to set the key with + */ + void set(const std::string& key, const std::vector& value); + + /** + * set the key with the bool array value + * @param key the key to be set + * @param value the value to set the key with + */ + void set(const std::string& key, const std::vector& value); + + /** + * set the key with the json array value + * @param key the key to be set + * @param value the value to set the key with + */ + void set(const std::string& key, std::vector& value); + + /** + * set the key with the string array value + * takes as input an array of any model and a function converting each item into a string + * @param key the key to be set + * @param value the value to set the key with + * @param converter function called on each item of value to convert them to string + */ + template + void set(const std::string& key, const std::vector& value, + const std::function& converter) { + auto arr = rapidjson::Value{ rapidjson::kArrayType }; + auto key_val = rapidjson::Value{ key.data(), memory_pool_ }; + + for (const auto& val : value) { + arr.PushBack(rapidjson::Value(converter(val).data(), memory_pool_).Move(), memory_pool_); + } + + json_.AddMember(key_val.Move(), arr.Move(), memory_pool_); + } + +public: + /** + * get an integer value for the given key + * assumption is made that key exists (this function will **not** check for existence) + * @param key the key to retrieve + * @return the retrieved value + */ + int64_t getInt(const std::string& key) const; + + /** + * get a string value for the given key + * assumption is made that key exists (this function will **not** check for existence) + * @param key the key to retrieve + * @return the retrieved value + */ + std::string getString(const std::string& key) const; + + /** + * get a string vector value for the given key + * assumption is made that key exists (this function will **not** check for existence) + * @param key the key to retrieve + * @return the retrieved value + */ + std::vector getStringVector(const std::string& key) const; + + /** + * get a boolean vector value for the given key + * assumption is made that key exists (this function will **not** check for existence) + * @param key the key to retrieve + * @return the retrieved value + */ + std::vector getBoolVector(const std::string& key) const; + + /** + * get a json vector value for the given key + * assumption is made that key exists (this function will **not** check for existence) + * @param key the key to retrieve + * @return the retrieved value + */ + std::vector getJsonVector(const std::string& key) const; + +private: + /** + * json memory pool, shared among all json objects + */ + static rapidjson::MemoryPoolAllocator<> memory_pool_; + +private: + /** + * the json object itself + */ + rapidjson::Document json_; +}; + +} // namespace Utils + +} // namespace IOTA diff --git a/source/api/extended.cpp b/source/api/extended.cpp index 87070af..6861625 100644 --- a/source/api/extended.cpp +++ b/source/api/extended.cpp @@ -23,6 +23,7 @@ // // +#include #include #include diff --git a/source/api/requests/add_neighbors.cpp b/source/api/requests/add_neighbors.cpp index 4b080c2..4373c3b 100644 --- a/source/api/requests/add_neighbors.cpp +++ b/source/api/requests/add_neighbors.cpp @@ -36,9 +36,10 @@ AddNeighbors::AddNeighbors(const std::vector& uris) } void -AddNeighbors::serialize(json& data) const { +AddNeighbors::serialize(Utils::json& data) const { Base::serialize(data); - data["uris"] = uris_; + + data.set("uris", uris_); } const std::vector& diff --git a/source/api/requests/attach_to_tangle.cpp b/source/api/requests/attach_to_tangle.cpp index 7d7fcb2..aa1ecdb 100644 --- a/source/api/requests/attach_to_tangle.cpp +++ b/source/api/requests/attach_to_tangle.cpp @@ -43,12 +43,13 @@ AttachToTangle::AttachToTangle(const Types::Trytes& trunkTransactio } void -AttachToTangle::serialize(json& data) const { +AttachToTangle::serialize(Utils::json& data) const { Base::serialize(data); - data["trunkTransaction"] = trunkTransaction_; - data["branchTransaction"] = branchTransaction_; - data["minWeightMagnitude"] = minWeightMagnitude_; - data["trytes"] = trytes_; + + data.set("trunkTransaction", trunkTransaction_); + data.set("branchTransaction", branchTransaction_); + data.set("minWeightMagnitude", minWeightMagnitude_); + data.set("trytes", trytes_); } const Types::Trytes& diff --git a/source/api/requests/base.cpp b/source/api/requests/base.cpp index 5ad6b60..a060f47 100644 --- a/source/api/requests/base.cpp +++ b/source/api/requests/base.cpp @@ -35,8 +35,8 @@ Base::Base(const std::string& command) : command_(command) { } void -Base::serialize(json& data) const { - data = json{ { "command", command_ } }; +Base::serialize(Utils::json& data) const { + data.set("command", command_); } const std::string& diff --git a/source/api/requests/broadcast_transactions.cpp b/source/api/requests/broadcast_transactions.cpp index 3a566af..2f5470d 100644 --- a/source/api/requests/broadcast_transactions.cpp +++ b/source/api/requests/broadcast_transactions.cpp @@ -36,9 +36,10 @@ BroadcastTransactions::BroadcastTransactions(const std::vector& t } void -BroadcastTransactions::serialize(json& data) const { +BroadcastTransactions::serialize(Utils::json& data) const { Base::serialize(data); - data["trytes"] = trytes_; + + data.set("trytes", trytes_); } const std::vector& diff --git a/source/api/requests/find_transactions.cpp b/source/api/requests/find_transactions.cpp index 51ab77b..a9693e3 100644 --- a/source/api/requests/find_transactions.cpp +++ b/source/api/requests/find_transactions.cpp @@ -43,27 +43,25 @@ FindTransactions::FindTransactions(const std::vector& addresses } void -FindTransactions::serialize(json& data) const { +FindTransactions::serialize(Utils::json& data) const { Base::serialize(data); if (!addresses_.empty()) { - for (auto& address : addresses_) { - data["addresses"].emplace_back(address.toTrytes()); - } + data.set("addresses", addresses_, + [](const Models::Address& addr) { return addr.toTrytes(); }); } if (!tags_.empty()) { - for (const auto& tag : tags_) { - data["tags"].emplace_back(tag.toTrytesWithPadding()); - } + data.set("tags", tags_, + [](const Models::Tag& tag) { return tag.toTrytesWithPadding(); }); } if (!approvees_.empty()) { - data["approvees"] = approvees_; + data.set("approvees", approvees_); } if (!bundles_.empty()) { - data["bundles"] = bundles_; + data.set("bundles", bundles_); } } diff --git a/source/api/requests/get_balances.cpp b/source/api/requests/get_balances.cpp index cb38e3b..057d7e0 100644 --- a/source/api/requests/get_balances.cpp +++ b/source/api/requests/get_balances.cpp @@ -36,13 +36,12 @@ GetBalances::GetBalances(const std::vector& addresses, const in } void -GetBalances::serialize(json& data) const { +GetBalances::serialize(Utils::json& data) const { Base::serialize(data); - for (auto& address : addresses_) { - data["addresses"].emplace_back(address.toTrytes()); - } - data["threshold"] = threshold_; + data.set("addresses", addresses_, + [](const Models::Address& addr) { return addr.toTrytes(); }); + data.set("threshold", threshold_); } const std::vector& diff --git a/source/api/requests/get_inclusions_states.cpp b/source/api/requests/get_inclusions_states.cpp index 52b40a3..0d86a76 100644 --- a/source/api/requests/get_inclusions_states.cpp +++ b/source/api/requests/get_inclusions_states.cpp @@ -38,10 +38,11 @@ GetInclusionStates::GetInclusionStates(const std::vector& transac } void -GetInclusionStates::serialize(json& data) const { +GetInclusionStates::serialize(Utils::json& data) const { Base::serialize(data); - data["transactions"] = transactions_; - data["tips"] = tips_; + + data.set("transactions", transactions_); + data.set("tips", tips_); } const std::vector& diff --git a/source/api/requests/get_transactions_to_approve.cpp b/source/api/requests/get_transactions_to_approve.cpp index 5a37cad..4c31879 100644 --- a/source/api/requests/get_transactions_to_approve.cpp +++ b/source/api/requests/get_transactions_to_approve.cpp @@ -36,9 +36,10 @@ GetTransactionsToApprove::GetTransactionsToApprove(const int& depth) } void -GetTransactionsToApprove::serialize(json& data) const { +GetTransactionsToApprove::serialize(Utils::json& data) const { Base::serialize(data); - data["depth"] = depth_; + + data.set("depth", depth_); } int diff --git a/source/api/requests/get_trytes.cpp b/source/api/requests/get_trytes.cpp index 46cc8ec..7e1e6b6 100644 --- a/source/api/requests/get_trytes.cpp +++ b/source/api/requests/get_trytes.cpp @@ -36,9 +36,10 @@ GetTrytes::GetTrytes(const std::vector& hashes) } void -GetTrytes::serialize(json& data) const { +GetTrytes::serialize(Utils::json& data) const { Base::serialize(data); - data["hashes"] = hashes_; + + data.set("hashes", hashes_); } const std::vector& diff --git a/source/api/requests/remove_neighbors.cpp b/source/api/requests/remove_neighbors.cpp index cd91011..75c1a28 100644 --- a/source/api/requests/remove_neighbors.cpp +++ b/source/api/requests/remove_neighbors.cpp @@ -36,9 +36,10 @@ RemoveNeighbors::RemoveNeighbors(const std::vector& uris) } void -RemoveNeighbors::serialize(json& data) const { +RemoveNeighbors::serialize(Utils::json& data) const { Base::serialize(data); - data["uris"] = uris_; + + data.set("uris", uris_); } const std::vector& diff --git a/source/api/requests/store_transactions.cpp b/source/api/requests/store_transactions.cpp index f5102a6..2273072 100644 --- a/source/api/requests/store_transactions.cpp +++ b/source/api/requests/store_transactions.cpp @@ -36,9 +36,10 @@ StoreTransactions::StoreTransactions(const std::vector& trytes) } void -StoreTransactions::serialize(json& data) const { +StoreTransactions::serialize(Utils::json& data) const { Base::serialize(data); - data["trytes"] = trytes_; + + data.set("trytes", trytes_); } const std::vector& diff --git a/source/api/responses/add_neighbors.cpp b/source/api/responses/add_neighbors.cpp index f9bb8cc..4c02c9a 100644 --- a/source/api/responses/add_neighbors.cpp +++ b/source/api/responses/add_neighbors.cpp @@ -34,16 +34,16 @@ namespace Responses { AddNeighbors::AddNeighbors(const int64_t& addedNeighbors) : addedNeighbors_(addedNeighbors) { } -AddNeighbors::AddNeighbors(const json& res) { +AddNeighbors::AddNeighbors(const Utils::json& res) { deserialize(res); } void -AddNeighbors::deserialize(const json& res) { +AddNeighbors::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("addedNeighbors")) { - addedNeighbors_ = res.at("addedNeighbors").get(); + if (res.has("addedNeighbors")) { + addedNeighbors_ = res.getInt("addedNeighbors"); } } diff --git a/source/api/responses/attach_to_tangle.cpp b/source/api/responses/attach_to_tangle.cpp index ae838e9..5c5a006 100644 --- a/source/api/responses/attach_to_tangle.cpp +++ b/source/api/responses/attach_to_tangle.cpp @@ -34,16 +34,16 @@ namespace Responses { AttachToTangle::AttachToTangle(const std::vector& trytes) : trytes_(trytes) { } -AttachToTangle::AttachToTangle(const json& res) { +AttachToTangle::AttachToTangle(const Utils::json& res) { deserialize(res); } void -AttachToTangle::deserialize(const json& res) { +AttachToTangle::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("trytes")) { - trytes_ = res.at("trytes").get>(); + if (res.has("trytes")) { + trytes_ = res.getStringVector("trytes"); } } diff --git a/source/api/responses/base.cpp b/source/api/responses/base.cpp index 869ead9..f67e285 100644 --- a/source/api/responses/base.cpp +++ b/source/api/responses/base.cpp @@ -34,14 +34,14 @@ namespace Responses { Base::Base(const int64_t& duration) : duration_(duration) { } -Base::Base(const json& res) { +Base::Base(const Utils::json& res) { deserialize(res); } void -Base::deserialize(const json& res) { - if (res.count("duration")) { - duration_ = res.at("duration").get(); +Base::deserialize(const Utils::json& res) { + if (res.has("duration")) { + duration_ = res.getInt("duration"); } } diff --git a/source/api/responses/find_transactions.cpp b/source/api/responses/find_transactions.cpp index 992a658..ed06ec6 100644 --- a/source/api/responses/find_transactions.cpp +++ b/source/api/responses/find_transactions.cpp @@ -34,16 +34,16 @@ namespace Responses { FindTransactions::FindTransactions(const std::vector& hashes) : hashes_(hashes) { } -FindTransactions::FindTransactions(const json& res) { +FindTransactions::FindTransactions(const Utils::json& res) { deserialize(res); } void -FindTransactions::deserialize(const json& res) { +FindTransactions::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("hashes")) { - hashes_ = res.at("hashes").get>(); + if (res.has("hashes")) { + hashes_ = res.getStringVector("hashes"); } } diff --git a/source/api/responses/get_balances.cpp b/source/api/responses/get_balances.cpp index f629b12..7ffcd50 100644 --- a/source/api/responses/get_balances.cpp +++ b/source/api/responses/get_balances.cpp @@ -36,24 +36,24 @@ GetBalances::GetBalances(const std::vector& balances, const Types:: : balances_(balances), milestone_(milestone), milestoneIndex_(milestoneIndex) { } -GetBalances::GetBalances(const json& res) { +GetBalances::GetBalances(const Utils::json& res) { deserialize(res); } void -GetBalances::deserialize(const json& res) { +GetBalances::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("balances")) { - balances_ = res.at("balances").get>(); + if (res.has("balances")) { + balances_ = res.getStringVector("balances"); } - if (res.count("milestone")) { - milestone_ = res.at("milestone").get(); + if (res.has("milestone")) { + milestone_ = res.getString("milestone"); } - if (res.count("milestoneIndex")) { - milestoneIndex_ = res.at("milestoneIndex").get(); + if (res.has("milestoneIndex")) { + milestoneIndex_ = res.getInt("milestoneIndex"); } } diff --git a/source/api/responses/get_inclusion_states.cpp b/source/api/responses/get_inclusion_states.cpp index c50e2a0..f6e0d3f 100644 --- a/source/api/responses/get_inclusion_states.cpp +++ b/source/api/responses/get_inclusion_states.cpp @@ -34,16 +34,16 @@ namespace Responses { GetInclusionStates::GetInclusionStates(const std::vector& states) : states_(states) { } -GetInclusionStates::GetInclusionStates(const json& res) { +GetInclusionStates::GetInclusionStates(const Utils::json& res) { deserialize(res); } void -GetInclusionStates::deserialize(const json& res) { +GetInclusionStates::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("states")) { - states_ = res.at("states").get>(); + if (res.has("states")) { + states_ = res.getBoolVector("states"); } } diff --git a/source/api/responses/get_neighbors.cpp b/source/api/responses/get_neighbors.cpp index 805d0fc..26fee43 100644 --- a/source/api/responses/get_neighbors.cpp +++ b/source/api/responses/get_neighbors.cpp @@ -35,30 +35,31 @@ namespace Responses { GetNeighbors::GetNeighbors(const std::vector& neighbors) : neighbors_(neighbors) { } -GetNeighbors::GetNeighbors(const json& res) { +GetNeighbors::GetNeighbors(const Utils::json& res) { deserialize(res); } void -GetNeighbors::deserialize(const json& res) { +GetNeighbors::deserialize(const Utils::json& res) { Base::deserialize(res); - for (const auto& neighbor : res["neighbors"]) { + + for (const auto& neighbor : res.getJsonVector("neighbors")) { Models::Neighbor obj; - if (neighbor.count("address")) { - obj.setAddress(neighbor.at("address").get()); + if (neighbor.has("address")) { + obj.setAddress(neighbor.getString("address")); } - if (neighbor.count("numberOfAllTransactions")) { - obj.setNumberOfAllTransactions(neighbor.at("numberOfAllTransactions").get()); + if (neighbor.has("numberOfAllTransactions")) { + obj.setNumberOfAllTransactions(neighbor.getInt("numberOfAllTransactions")); } - if (neighbor.count("numberOfInvalidTransactions")) { - obj.setNumberOfInvalidTransactions(neighbor.at("numberOfInvalidTransactions").get()); + if (neighbor.has("numberOfInvalidTransactions")) { + obj.setNumberOfInvalidTransactions(neighbor.getInt("numberOfInvalidTransactions")); } - if (neighbor.count("numberOfNewTransactions")) { - obj.setNumberOfNewTransactions(neighbor.at("numberOfNewTransactions").get()); + if (neighbor.has("numberOfNewTransactions")) { + obj.setNumberOfNewTransactions(neighbor.getInt("numberOfNewTransactions")); } neighbors_.push_back(std::move(obj)); diff --git a/source/api/responses/get_node_info.cpp b/source/api/responses/get_node_info.cpp index 09fb853..a1079c1 100644 --- a/source/api/responses/get_node_info.cpp +++ b/source/api/responses/get_node_info.cpp @@ -56,73 +56,72 @@ GetNodeInfo::GetNodeInfo(const std::string& appName, const std::string& appVersi transactionsToRequest_(transactionsToRequest) { } -GetNodeInfo::GetNodeInfo(const json& res) { +GetNodeInfo::GetNodeInfo(const Utils::json& res) { deserialize(res); } void -GetNodeInfo::deserialize(const json& res) { +GetNodeInfo::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("appName")) { - appName_ = res.at("appName").get(); + if (res.has("appName")) { + appName_ = res.getString("appName"); } - if (res.count("appVersion")) { - appVersion_ = res.at("appVersion").get(); + if (res.has("appVersion")) { + appVersion_ = res.getString("appVersion"); } - if (res.count("jreAvailableProcessors")) { - jreAvailableProcessors_ = res.at("jreAvailableProcessors").get(); + if (res.has("jreAvailableProcessors")) { + jreAvailableProcessors_ = res.getInt("jreAvailableProcessors"); } - if (res.count("jreFreeMemory")) { - jreFreeMemory_ = res.at("jreFreeMemory").get(); + if (res.has("jreFreeMemory")) { + jreFreeMemory_ = res.getInt("jreFreeMemory"); } - if (res.count("jreMaxMemory")) { - jreMaxMemory_ = res.at("jreMaxMemory").get(); + if (res.has("jreMaxMemory")) { + jreMaxMemory_ = res.getInt("jreMaxMemory"); } - if (res.count("jreTotalMemory")) { - jreTotalMemory_ = res.at("jreTotalMemory").get(); + if (res.has("jreTotalMemory")) { + jreTotalMemory_ = res.getInt("jreTotalMemory"); } - if (res.count("latestMilestone")) { - latestMilestone_ = res.at("latestMilestone").get(); + if (res.has("latestMilestone")) { + latestMilestone_ = res.getString("latestMilestone"); } - if (res.count("latestMilestoneIndex")) { - latestMilestoneIndex_ = res.at("latestMilestoneIndex").get(); + if (res.has("latestMilestoneIndex")) { + latestMilestoneIndex_ = res.getInt("latestMilestoneIndex"); } - if (res.count("latestSolidSubtangleMilestone")) { - latestSolidSubtangleMilestone_ = res.at("latestSolidSubtangleMilestone").get(); + if (res.has("latestSolidSubtangleMilestone")) { + latestSolidSubtangleMilestone_ = res.getString("latestSolidSubtangleMilestone"); } - if (res.count("latestSolidSubtangleMilestoneIndex")) { - latestSolidSubtangleMilestoneIndex_ = - res.at("latestSolidSubtangleMilestoneIndex").get(); + if (res.has("latestSolidSubtangleMilestoneIndex")) { + latestSolidSubtangleMilestoneIndex_ = res.getInt("latestSolidSubtangleMilestoneIndex"); } - if (res.count("neighbors")) { - neighbors_ = res.at("neighbors").get(); + if (res.has("neighbors")) { + neighbors_ = res.getInt("neighbors"); } - if (res.count("packetsQueueSize")) { - packetsQueueSize_ = res.at("packetsQueueSize").get(); + if (res.has("packetsQueueSize")) { + packetsQueueSize_ = res.getInt("packetsQueueSize"); } - if (res.count("time")) { - time_ = res.at("time").get(); + if (res.has("time")) { + time_ = res.getInt("time"); } - if (res.count("tips")) { - tips_ = res.at("tips").get(); + if (res.has("tips")) { + tips_ = res.getInt("tips"); } - if (res.count("transactionsToRequest")) { - transactionsToRequest_ = res.at("transactionsToRequest").get(); + if (res.has("transactionsToRequest")) { + transactionsToRequest_ = res.getInt("transactionsToRequest"); } } diff --git a/source/api/responses/get_tips.cpp b/source/api/responses/get_tips.cpp index e8ecb42..bc0995a 100644 --- a/source/api/responses/get_tips.cpp +++ b/source/api/responses/get_tips.cpp @@ -34,16 +34,16 @@ namespace Responses { GetTips::GetTips(const std::vector& hashes) : hashes_(hashes) { } -GetTips::GetTips(const json& res) { +GetTips::GetTips(const Utils::json& res) { deserialize(res); } void -GetTips::deserialize(const json& res) { +GetTips::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("hashes")) { - hashes_ = res.at("hashes").get>(); + if (res.has("hashes")) { + hashes_ = res.getStringVector("hashes"); } } diff --git a/source/api/responses/get_transactions_to_approve.cpp b/source/api/responses/get_transactions_to_approve.cpp index 0259053..f4c1899 100644 --- a/source/api/responses/get_transactions_to_approve.cpp +++ b/source/api/responses/get_transactions_to_approve.cpp @@ -36,20 +36,20 @@ GetTransactionsToApprove::GetTransactionsToApprove(const Types::Trytes& trunkTra : trunkTransaction_(trunkTransaction), branchTransaction_(branchTransaction) { } -GetTransactionsToApprove::GetTransactionsToApprove(const json& res) { +GetTransactionsToApprove::GetTransactionsToApprove(const Utils::json& res) { deserialize(res); } void -GetTransactionsToApprove::deserialize(const json& res) { +GetTransactionsToApprove::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("trunkTransaction")) { - trunkTransaction_ = res.at("trunkTransaction").get(); + if (res.has("trunkTransaction")) { + trunkTransaction_ = res.getString("trunkTransaction"); } - if (res.count("branchTransaction")) { - branchTransaction_ = res.at("branchTransaction").get(); + if (res.has("branchTransaction")) { + branchTransaction_ = res.getString("branchTransaction"); } } diff --git a/source/api/responses/get_trytes.cpp b/source/api/responses/get_trytes.cpp index 2fdddfd..7051fc0 100644 --- a/source/api/responses/get_trytes.cpp +++ b/source/api/responses/get_trytes.cpp @@ -34,16 +34,16 @@ namespace Responses { GetTrytes::GetTrytes(const std::vector& trytes) : trytes_(trytes) { } -GetTrytes::GetTrytes(const json& res) { +GetTrytes::GetTrytes(const Utils::json& res) { deserialize(res); } void -GetTrytes::deserialize(const json& res) { +GetTrytes::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("trytes")) { - trytes_ = res.at("trytes").get>(); + if (res.has("trytes")) { + trytes_ = res.getStringVector("trytes"); } } diff --git a/source/api/responses/remove_neighbors.cpp b/source/api/responses/remove_neighbors.cpp index 9e15cbf..d697abc 100644 --- a/source/api/responses/remove_neighbors.cpp +++ b/source/api/responses/remove_neighbors.cpp @@ -35,16 +35,16 @@ RemoveNeighbors::RemoveNeighbors(const int64_t& removedNeighbors) : removedNeighbors_(removedNeighbors) { } -RemoveNeighbors::RemoveNeighbors(const json& res) { +RemoveNeighbors::RemoveNeighbors(const Utils::json& res) { deserialize(res); } void -RemoveNeighbors::deserialize(const json& res) { +RemoveNeighbors::deserialize(const Utils::json& res) { Base::deserialize(res); - if (res.count("removedNeighbors")) { - removedNeighbors_ = res.at("removedNeighbors").get(); + if (res.has("removedNeighbors")) { + removedNeighbors_ = res.getInt("removedNeighbors"); } } diff --git a/source/utils/json.cpp b/source/utils/json.cpp new file mode 100644 index 0000000..2c14daf --- /dev/null +++ b/source/utils/json.cpp @@ -0,0 +1,159 @@ +// +// MIT License +// +// Copyright (c) 2017-2018 Thibault Martinez and Simon Ninon +// +// 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. +// +// + +#include + +namespace IOTA { + +namespace Utils { + +rapidjson::MemoryPoolAllocator<> json::memory_pool_; + +json::json(void) : json_(rapidjson::kObjectType, &memory_pool_) { +} + +json::json(const rapidjson::Value& val) : json_(rapidjson::kObjectType, &memory_pool_) { + json_.CopyFrom(val, memory_pool_); +} + +void +json::loads(const std::string& json_str) { + json_.Parse(json_str.c_str()); +} + +std::string +json::dumps(void) const { + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + json_.Accept(writer); + + return buffer.GetString(); +} + +bool +json::has(const std::string& key) const { + return json_.HasMember(key.data()); +} + +void +json::set(const std::string& key, int64_t value) { + auto key_val = rapidjson::Value{ key.data(), memory_pool_ }; + + json_.AddMember(key_val.Move(), value, memory_pool_); +} + +void +json::set(const std::string& key, const std::string& value) { + auto val = rapidjson::Value(value.data(), memory_pool_); + auto key_val = rapidjson::Value{ key.data(), memory_pool_ }; + + json_.AddMember(key_val.Move(), val.Move(), memory_pool_); +} + +void +json::set(const std::string& key, const std::vector& value) { + auto arr = rapidjson::Value{ rapidjson::kArrayType }; + auto key_val = rapidjson::Value{ key.data(), memory_pool_ }; + + for (const auto& val : value) { + arr.PushBack(rapidjson::Value(val.data(), memory_pool_).Move(), memory_pool_); + } + + json_.AddMember(key_val.Move(), arr.Move(), memory_pool_); +} + +void +json::set(const std::string& key, const std::vector& value) { + auto arr = rapidjson::Value{ rapidjson::kArrayType }; + auto key_val = rapidjson::Value{ key.data(), memory_pool_ }; + + for (const auto& val : value) { + arr.PushBack(val, memory_pool_); + } + + json_.AddMember(key_val.Move(), arr.Move(), memory_pool_); +} + +void +json::set(const std::string& key, std::vector& value) { + auto arr = rapidjson::Value{ rapidjson::kArrayType }; + auto key_val = rapidjson::Value{ key.data(), memory_pool_ }; + + for (auto& val : value) { + arr.PushBack(val.json_, memory_pool_); + } + + json_.AddMember(key_val.Move(), arr.Move(), memory_pool_); +} + +int64_t +json::getInt(const std::string& key) const { + return json_[key.data()].GetInt64(); +} + +std::string +json::getString(const std::string& key) const { + return json_[key.data()].GetString(); +} + +std::vector +json::getStringVector(const std::string& key) const { + auto arr = json_[key.data()].GetArray(); + + std::vector res; + for (auto it = arr.Begin(); it != arr.End(); ++it) { + res.push_back(it->GetString()); + } + + return res; +} + +std::vector +json::getBoolVector(const std::string& key) const { + auto arr = json_[key.data()].GetArray(); + + std::vector res; + for (auto it = arr.Begin(); it != arr.End(); ++it) { + res.push_back(it->GetBool()); + } + + return res; +} + +std::vector +json::getJsonVector(const std::string& key) const { + auto arr = json_[key.data()].GetArray(); + + std::vector res; + for (auto it = arr.Begin(); it != arr.End(); ++it) { + res.push_back(json(*it)); + } + + return res; +} + +} // namespace Utils + +} // namespace IOTA diff --git a/test.cpp b/test.cpp new file mode 100644 index 0000000..0b45369 --- /dev/null +++ b/test.cpp @@ -0,0 +1,25 @@ +#include +#include + +static std::string proxy_host = "localhost"; +static uint16_t proxy_port = 14265; + +const std::string& +get_proxy_host(void) { + return proxy_host; +} + +const uint16_t& +get_proxy_port(void) { + return proxy_port; +} + +int +main() { + IOTA::API::Core api(get_proxy_host(), get_proxy_port()); + + for (int i = 0; i < 1000; ++i) { + api.getNodeInfo(); + api.addNeighbors({ "udp://8.8.8.8:14265", "udp://8.8.8.5:14265" }); + } +} diff --git a/test/source/api/requests/add_neighbors_test.cpp b/test/source/api/requests/add_neighbors_test.cpp index 15e5e2c..704a49c 100644 --- a/test/source/api/requests/add_neighbors_test.cpp +++ b/test/source/api/requests/add_neighbors_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(AddNeighborsRequest, CtorShouldInitFields) { const IOTA::API::Requests::AddNeighbors req{ { "uri1", "uri2" } }; @@ -51,10 +52,10 @@ TEST(AddNeighborsRequest, SetUris) { TEST(AddNeighborsRequest, SerializeShouldInitJson) { const IOTA::API::Requests::AddNeighbors req{ { "uri1", "uri2" } }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "addNeighbors"); - EXPECT_EQ(data["uris"], std::vector({ "uri1", "uri2" })); + EXPECT_EQ(data.getString("command"), "addNeighbors"); + EXPECT_EQ(data.getStringVector("uris"), std::vector({ "uri1", "uri2" })); } diff --git a/test/source/api/requests/attach_to_tangle_test.cpp b/test/source/api/requests/attach_to_tangle_test.cpp index 75f0ffb..d973832 100644 --- a/test/source/api/requests/attach_to_tangle_test.cpp +++ b/test/source/api/requests/attach_to_tangle_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(AttachToTangleRequest, CtorShouldInitFields) { const IOTA::API::Requests::AttachToTangle req{ "trunk", "branch", 42, { "trytes1", "trytes2" } }; @@ -93,13 +94,14 @@ TEST(AttachToTangleRequest, setTrytes) { TEST(AttachToTangleRequest, SerializeShouldInitJson) { const IOTA::API::Requests::AttachToTangle req{ "trunk", "branch", 42, { "trytes1", "trytes2" } }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "attachToTangle"); - EXPECT_EQ(data["trunkTransaction"], "trunk"); - EXPECT_EQ(data["branchTransaction"], "branch"); - EXPECT_EQ(data["minWeightMagnitude"], 42); - EXPECT_EQ(data["trytes"], std::vector({ "trytes1", "trytes2" })); + EXPECT_EQ(data.getString("command"), "attachToTangle"); + EXPECT_EQ(data.getString("trunkTransaction"), "trunk"); + EXPECT_EQ(data.getString("branchTransaction"), "branch"); + EXPECT_EQ(data.getInt("minWeightMagnitude"), 42); + EXPECT_EQ(data.getStringVector("trytes"), + std::vector({ "trytes1", "trytes2" })); } diff --git a/test/source/api/requests/base_test.cpp b/test/source/api/requests/base_test.cpp index e01a3d7..80d9745 100644 --- a/test/source/api/requests/base_test.cpp +++ b/test/source/api/requests/base_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(BaseRequest, CtorShouldInitFields) { const IOTA::API::Requests::Base req{ { "cmd" } }; @@ -35,9 +36,9 @@ TEST(BaseRequest, CtorShouldInitFields) { TEST(BaseRequest, SerializeShouldInitJson) { const IOTA::API::Requests::Base req{ "cmd" }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "cmd"); + EXPECT_EQ(data.getString("command"), "cmd"); } diff --git a/test/source/api/requests/broadcast_transactions_test.cpp b/test/source/api/requests/broadcast_transactions_test.cpp index abe7c06..865e3b4 100644 --- a/test/source/api/requests/broadcast_transactions_test.cpp +++ b/test/source/api/requests/broadcast_transactions_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(BroadcastTransactionsRequest, CtorShouldInitFields) { const IOTA::API::Requests::BroadcastTransactions res{ { "TESTA", "TESTB" } }; @@ -54,10 +55,9 @@ TEST(BroadcastTransactionsRequest, SetTrytes) { TEST(BroadcastTransactionsRequest, Serialize) { const IOTA::API::Requests::BroadcastTransactions res{ { "TESTA", "TESTB" } }; - json data; + IOTA::Utils::json data; res.serialize(data); - EXPECT_EQ(data["command"], "broadcastTransactions"); - EXPECT_EQ(data["trytes"].get>(), - std::vector({ "TESTA", "TESTB" })); + EXPECT_EQ(data.getString("command"), "broadcastTransactions"); + EXPECT_EQ(data.getStringVector("trytes"), std::vector({ "TESTA", "TESTB" })); } diff --git a/test/source/api/requests/find_transactions_test.cpp b/test/source/api/requests/find_transactions_test.cpp index aecdf28..1d84af5 100644 --- a/test/source/api/requests/find_transactions_test.cpp +++ b/test/source/api/requests/find_transactions_test.cpp @@ -26,6 +26,7 @@ #include #include +#include #include TEST(FindTransactionsRequest, CtorShouldInitFields) { @@ -173,16 +174,19 @@ TEST(FindTransactionsRequest, SerializeShouldInitJson) { { { "TAGONE" }, { "TAGTWO" } }, { "approvee1", "approvee2" }, { "bundle1", "bundle2" } }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "findTransactions"); - EXPECT_EQ(data["addresses"], + EXPECT_EQ(data.getString("command"), "findTransactions"); + EXPECT_EQ(data.getStringVector("addresses"), std::vector({ ACCOUNT_1_ADDRESS_1_HASH_WITHOUT_CHECKSUM, ACCOUNT_1_ADDRESS_2_HASH_WITHOUT_CHECKSUM })); - EXPECT_EQ(data["tags"], std::vector( - { "TAGONE999999999999999999999", "TAGTWO999999999999999999999" })); - EXPECT_EQ(data["approvees"], std::vector({ "approvee1", "approvee2" })); - EXPECT_EQ(data["bundles"], std::vector({ "bundle1", "bundle2" })); + EXPECT_EQ(data.getStringVector("tags"), + std::vector( + { "TAGONE999999999999999999999", "TAGTWO999999999999999999999" })); + EXPECT_EQ(data.getStringVector("approvees"), + std::vector({ "approvee1", "approvee2" })); + EXPECT_EQ(data.getStringVector("bundles"), + std::vector({ "bundle1", "bundle2" })); } diff --git a/test/source/api/requests/get_balances_test.cpp b/test/source/api/requests/get_balances_test.cpp index 004413d..ce904c1 100644 --- a/test/source/api/requests/get_balances_test.cpp +++ b/test/source/api/requests/get_balances_test.cpp @@ -26,6 +26,7 @@ #include #include +#include #include TEST(GetBalancesRequest, DefaultCtorShouldInitFields) { @@ -83,13 +84,13 @@ TEST(GetBalancesRequest, SerializeShouldInitJson) { const IOTA::API::Requests::GetBalances req{ { ACCOUNT_1_ADDRESS_1_HASH, ACCOUNT_1_ADDRESS_2_HASH }, 42 }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "getBalances"); - EXPECT_EQ(data["addresses"], + EXPECT_EQ(data.getString("command"), "getBalances"); + EXPECT_EQ(data.getStringVector("addresses"), std::vector({ ACCOUNT_1_ADDRESS_1_HASH_WITHOUT_CHECKSUM, ACCOUNT_1_ADDRESS_2_HASH_WITHOUT_CHECKSUM })); - EXPECT_EQ(data["threshold"], 42); + EXPECT_EQ(data.getInt("threshold"), 42); } diff --git a/test/source/api/requests/get_inclusion_states_test.cpp b/test/source/api/requests/get_inclusion_states_test.cpp index 47e53c3..43a5271 100644 --- a/test/source/api/requests/get_inclusion_states_test.cpp +++ b/test/source/api/requests/get_inclusion_states_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetInclusionStatesRequest, CtorShouldInitFields) { const IOTA::API::Requests::GetInclusionStates req( @@ -74,11 +75,12 @@ TEST(GetInclusionStatesRequest, SetTips) { TEST(GetInclusionStatesRequest, SerializeShouldInitJson) { const IOTA::API::Requests::GetInclusionStates req{ { "tx1", "tx2" }, { "tip1", "tip2" } }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "getInclusionStates"); - EXPECT_EQ(data["transactions"], std::vector({ "tx1", "tx2" })); - EXPECT_EQ(data["tips"], std::vector({ "tip1", "tip2" })); + EXPECT_EQ(data.getString("command"), "getInclusionStates"); + EXPECT_EQ(data.getStringVector("transactions"), + std::vector({ "tx1", "tx2" })); + EXPECT_EQ(data.getStringVector("tips"), std::vector({ "tip1", "tip2" })); } diff --git a/test/source/api/requests/get_neighbors_test.cpp b/test/source/api/requests/get_neighbors_test.cpp index e79ea71..86f76cb 100644 --- a/test/source/api/requests/get_neighbors_test.cpp +++ b/test/source/api/requests/get_neighbors_test.cpp @@ -26,12 +26,13 @@ #include #include +#include TEST(GetNeighborsRequest, SerializeShouldInitJson) { const IOTA::API::Requests::GetNeighbors req; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "getNeighbors"); + EXPECT_EQ(data.getString("command"), "getNeighbors"); } diff --git a/test/source/api/requests/get_node_info_test.cpp b/test/source/api/requests/get_node_info_test.cpp index d5aa487..5ea5ba8 100644 --- a/test/source/api/requests/get_node_info_test.cpp +++ b/test/source/api/requests/get_node_info_test.cpp @@ -26,12 +26,13 @@ #include #include +#include TEST(GetNodeInfoRequest, SerializeShouldInitJson) { const IOTA::API::Requests::GetNodeInfo req; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "getNodeInfo"); + EXPECT_EQ(data.getString("command"), "getNodeInfo"); } diff --git a/test/source/api/requests/get_tips_test.cpp b/test/source/api/requests/get_tips_test.cpp index 30e453e..5c769e8 100644 --- a/test/source/api/requests/get_tips_test.cpp +++ b/test/source/api/requests/get_tips_test.cpp @@ -26,12 +26,13 @@ #include #include +#include TEST(GetTipsRequest, SerializeShouldInitJson) { const IOTA::API::Requests::GetTips req; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "getTips"); + EXPECT_EQ(data.getString("command"), "getTips"); } diff --git a/test/source/api/requests/get_transactions_to_approve_test.cpp b/test/source/api/requests/get_transactions_to_approve_test.cpp index acd8804..d4c3dfa 100644 --- a/test/source/api/requests/get_transactions_to_approve_test.cpp +++ b/test/source/api/requests/get_transactions_to_approve_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetTransactionToApproveRequest, Ctor) { const IOTA::API::Requests::GetTransactionsToApprove req{}; @@ -49,10 +50,10 @@ TEST(GetTransactionToApproveRequest, SetDepth) { TEST(GetTransactionToApproveRequest, SerializeShouldInitJson) { const IOTA::API::Requests::GetTransactionsToApprove req{ 42 }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "getTransactionsToApprove"); - EXPECT_EQ(data["depth"], 42); + EXPECT_EQ(data.getString("command"), "getTransactionsToApprove"); + EXPECT_EQ(data.getInt("depth"), 42); } diff --git a/test/source/api/requests/get_trytes_test.cpp b/test/source/api/requests/get_trytes_test.cpp index 99d23eb..3802d57 100644 --- a/test/source/api/requests/get_trytes_test.cpp +++ b/test/source/api/requests/get_trytes_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetTrytesRequest, CtorShouldInitFields) { const IOTA::API::Requests::GetTrytes req{ { "TESTA", "TESTB" } }; @@ -53,10 +54,10 @@ TEST(GetTrytesRequest, SetHashes) { TEST(GetTrytesRequest, SerializeShouldInitJson) { const IOTA::API::Requests::GetTrytes req{ { "TESTA", "TESTB" } }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "getTrytes"); - EXPECT_EQ(data["hashes"], std::vector({ "TESTA", "TESTB" })); + EXPECT_EQ(data.getString("command"), "getTrytes"); + EXPECT_EQ(data.getStringVector("hashes"), std::vector({ "TESTA", "TESTB" })); } diff --git a/test/source/api/requests/interrupt_attaching_to_tangle_test.cpp b/test/source/api/requests/interrupt_attaching_to_tangle_test.cpp index 8a7f6c0..4715694 100644 --- a/test/source/api/requests/interrupt_attaching_to_tangle_test.cpp +++ b/test/source/api/requests/interrupt_attaching_to_tangle_test.cpp @@ -26,12 +26,13 @@ #include #include +#include TEST(InterruptAttachingToTangleRequest, SerializeShouldInitJson) { const IOTA::API::Requests::InterruptAttachingToTangle req; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "interruptAttachingToTangle"); + EXPECT_EQ(data.getString("command"), "interruptAttachingToTangle"); } diff --git a/test/source/api/requests/remove_neighbors_test.cpp b/test/source/api/requests/remove_neighbors_test.cpp index fd59390..797b14b 100644 --- a/test/source/api/requests/remove_neighbors_test.cpp +++ b/test/source/api/requests/remove_neighbors_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(RemoveNeighborsRequest, CtorShouldInitFields) { const IOTA::API::Requests::RemoveNeighbors req{ { "uri1", "uri2" } }; @@ -51,10 +52,10 @@ TEST(RemoveNeighborsRequest, SetUris) { TEST(RemoveNeighborsRequest, SerializeShouldInitJson) { const IOTA::API::Requests::RemoveNeighbors req{ { "uri1", "uri2" } }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"], "removeNeighbors"); - EXPECT_EQ(data["uris"], std::vector({ "uri1", "uri2" })); + EXPECT_EQ(data.getString("command"), "removeNeighbors"); + EXPECT_EQ(data.getStringVector("uris"), std::vector({ "uri1", "uri2" })); } diff --git a/test/source/api/requests/store_transactions_test.cpp b/test/source/api/requests/store_transactions_test.cpp index 55b6bf7..97742f7 100644 --- a/test/source/api/requests/store_transactions_test.cpp +++ b/test/source/api/requests/store_transactions_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(StoreTransactionsRequest, CtorShouldInitFields) { const IOTA::API::Requests::StoreTransactions res{ { "TESTA", "TESTB" } }; @@ -53,10 +54,10 @@ TEST(StoreTransactionsRequest, SetTrytes) { TEST(StoreTransactionsRequest, SerializeShouldInitJson) { const IOTA::API::Requests::StoreTransactions req{ { "TESTA", "TESTB" } }; - json data; + IOTA::Utils::json data; req.serialize(data); - EXPECT_EQ(data["command"].get(), "storeTransactions"); - EXPECT_EQ(data["trytes"], std::vector({ "TESTA", "TESTB" })); + EXPECT_EQ(data.getString("command"), "storeTransactions"); + EXPECT_EQ(data.getStringVector("trytes"), std::vector({ "TESTA", "TESTB" })); } diff --git a/test/source/api/responses/add_neighbors_test.cpp b/test/source/api/responses/add_neighbors_test.cpp index fc7a238..75eec19 100644 --- a/test/source/api/responses/add_neighbors_test.cpp +++ b/test/source/api/responses/add_neighbors_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(AddNeighborsResponse, CtorShouldInitFields) { const IOTA::API::Responses::AddNeighbors res{ 42 }; @@ -45,9 +46,9 @@ TEST(AddNeighborsResponse, SetAddedNeighbors) { TEST(AddNeighborsResponse, DeserializeShouldSetFields) { IOTA::API::Responses::AddNeighbors res; - json data; + IOTA::Utils::json data; - data["addedNeighbors"] = 42; + data.set("addedNeighbors", 42); res.deserialize(data); EXPECT_EQ(res.getAddedNeighbors(), 42); } diff --git a/test/source/api/responses/attach_to_tangle_test.cpp b/test/source/api/responses/attach_to_tangle_test.cpp index 2a78668..ec8e0a9 100644 --- a/test/source/api/responses/attach_to_tangle_test.cpp +++ b/test/source/api/responses/attach_to_tangle_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(AttachToTangleResponse, CtorShouldInitFields) { const IOTA::API::Responses::AttachToTangle res{ std::vector( @@ -57,11 +58,11 @@ TEST(AttachToTangleResponse, SetTrytes) { TEST(AttachToTangleResponse, DeserializeShouldSetFields) { IOTA::API::Responses::AttachToTangle res; - json data; + IOTA::Utils::json data; std::vector trytes; trytes.push_back("TEST"); - data["trytes"] = trytes; + data.set("trytes", trytes); res.deserialize(data); EXPECT_EQ(res.getTrytes(), trytes); } diff --git a/test/source/api/responses/base_test.cpp b/test/source/api/responses/base_test.cpp index 59fe627..1ae3a84 100644 --- a/test/source/api/responses/base_test.cpp +++ b/test/source/api/responses/base_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(BaseResponse, CtorShouldInitFields) { const IOTA::API::Responses::Base res{ 0 }; @@ -43,9 +44,9 @@ TEST(BaseResponse, SetDuration) { TEST(BaseResponse, DeserializeShouldSetFields) { IOTA::API::Responses::Base res; - json data; + IOTA::Utils::json data; - data["duration"] = 42; + data.set("duration", 42); res.deserialize(data); EXPECT_EQ(res.getDuration(), 42); } diff --git a/test/source/api/responses/find_transactions_test.cpp b/test/source/api/responses/find_transactions_test.cpp index 46ceac7..c18411a 100644 --- a/test/source/api/responses/find_transactions_test.cpp +++ b/test/source/api/responses/find_transactions_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(FindTransactionsResponse, DefaultCtorShouldInitFields) { const IOTA::API::Responses::FindTransactions res; @@ -74,11 +75,11 @@ TEST(FindTransactionsResponse, SetHashes) { TEST(FindTransactionsResponse, DeserializeShouldSetFields) { IOTA::API::Responses::FindTransactions res; - json data; + IOTA::Utils::json data; std::vector hashes; hashes.push_back("TEST"); - data["hashes"] = hashes; + data.set("hashes", hashes); res.deserialize(data); EXPECT_EQ(res.getHashes(), hashes); } diff --git a/test/source/api/responses/get_balances_test.cpp b/test/source/api/responses/get_balances_test.cpp index 83b34a3..d4a0ad9 100644 --- a/test/source/api/responses/get_balances_test.cpp +++ b/test/source/api/responses/get_balances_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetBalancesReponse, DefaultCtorShouldInitFields) { const IOTA::API::Responses::GetBalances res; @@ -102,11 +103,11 @@ TEST(GetBalancesReponse, SetMilestoneIndex) { TEST(GetBalancesReponse, DeserializeShouldSetFields) { IOTA::API::Responses::GetBalances res; - json data; + IOTA::Utils::json data; - data["balances"] = std::vector({ "bal1", "bal2", "bal3" }); - data["milestone"] = "milestone"; - data["milestoneIndex"] = 1; + data.set("balances", std::vector({ "bal1", "bal2", "bal3" })); + data.set("milestone", "milestone"); + data.set("milestoneIndex", 1); res.deserialize(data); diff --git a/test/source/api/responses/get_inclusion_states_test.cpp b/test/source/api/responses/get_inclusion_states_test.cpp index f6bef7b..165fa47 100644 --- a/test/source/api/responses/get_inclusion_states_test.cpp +++ b/test/source/api/responses/get_inclusion_states_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetInclusionStatesResponse, CtorShouldInitFields) { const IOTA::API::Responses::GetInclusionStates res{ std::vector({ true, false, true }) }; @@ -47,11 +48,11 @@ TEST(GetInclusionStatesResponse, SetStates) { TEST(GetInclusionStatesResponse, DeserializeShouldSetFields) { IOTA::API::Responses::GetInclusionStates res; - json data; + IOTA::Utils::json data; std::vector states; - states.push_back("TEST"); - data["states"] = states; + states.push_back(true); + data.set("states", states); res.deserialize(data); EXPECT_EQ(res.getStates(), states); } diff --git a/test/source/api/responses/get_neighbors_test.cpp b/test/source/api/responses/get_neighbors_test.cpp index 4d1028e..fedcf98 100644 --- a/test/source/api/responses/get_neighbors_test.cpp +++ b/test/source/api/responses/get_neighbors_test.cpp @@ -27,6 +27,7 @@ #include #include +#include TEST(GetNeighborsResponse, CtorShouldInitFields) { const IOTA::API::Responses::GetNeighbors res{ std::vector( @@ -79,14 +80,14 @@ TEST(GetNeighborsResponse, SetNeighbors) { TEST(GetNeighborsResponse, DeserializeShouldSetFields) { IOTA::API::Responses::GetNeighbors res; - json data; - json neighbor; - - neighbor["address"] = "addr1"; - neighbor["numberOfAllTransactions"] = 1; - neighbor["numberOfInvalidTransactions"] = 2; - neighbor["numberOfNewTransactions"] = 3; - data["neighbors"] = std::vector{ neighbor }; + IOTA::Utils::json data; + IOTA::Utils::json neighbor; + + neighbor.set("address", "addr1"); + neighbor.set("numberOfAllTransactions", 1); + neighbor.set("numberOfInvalidTransactions", 2); + neighbor.set("numberOfNewTransactions", 3); + data.set("neighbors", std::vector{ neighbor }); res.deserialize(data); diff --git a/test/source/api/responses/get_node_info_test.cpp b/test/source/api/responses/get_node_info_test.cpp index 1eeb993..dcecc14 100644 --- a/test/source/api/responses/get_node_info_test.cpp +++ b/test/source/api/responses/get_node_info_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetNodeInfoResponse, CtorShouldInitFields) { const IOTA::API::Responses::GetNodeInfo res{ @@ -443,23 +444,23 @@ TEST(GetNodeInfoResponse, SetTransactionsToRequest) { TEST(GetNodeInfoResponse, DeserializeShouldSetFields) { IOTA::API::Responses::GetNodeInfo res; - json data; - - data["appName"] = "appname"; - data["appVersion"] = "appversion"; - data["jreAvailableProcessors"] = 1; - data["jreFreeMemory"] = 2; - data["jreMaxMemory"] = 3; - data["jreTotalMemory"] = 4; - data["latestMilestone"] = "milestone"; - data["latestMilestoneIndex"] = 5; - data["latestSolidSubtangleMilestone"] = "submilestone"; - data["latestSolidSubtangleMilestoneIndex"] = 6; - data["neighbors"] = 7; - data["packetsQueueSize"] = 8; - data["time"] = 9; - data["tips"] = 10; - data["transactionsToRequest"] = 11; + IOTA::Utils::json data; + + data.set("appName", "appname"); + data.set("appVersion", "appversion"); + data.set("jreAvailableProcessors", 1); + data.set("jreFreeMemory", 2); + data.set("jreMaxMemory", 3); + data.set("jreTotalMemory", 4); + data.set("latestMilestone", "milestone"); + data.set("latestMilestoneIndex", 5); + data.set("latestSolidSubtangleMilestone", "submilestone"); + data.set("latestSolidSubtangleMilestoneIndex", 6); + data.set("neighbors", 7); + data.set("packetsQueueSize", 8); + data.set("time", 9); + data.set("tips", 10); + data.set("transactionsToRequest", 11); res.deserialize(data); diff --git a/test/source/api/responses/get_tips_test.cpp b/test/source/api/responses/get_tips_test.cpp index 2219fbc..40e6d39 100644 --- a/test/source/api/responses/get_tips_test.cpp +++ b/test/source/api/responses/get_tips_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetTipsResponse, CtorShouldInitFields) { const IOTA::API::Responses::GetTips res{ std::vector({ "TESTA", "TESTB" }) }; @@ -56,11 +57,11 @@ TEST(GetTipsResponse, SetHashes) { TEST(GetTipsResponse, DeserializeShouldSetFields) { IOTA::API::Responses::GetTips res; - json data; + IOTA::Utils::json data; std::vector hashes; hashes.push_back("TEST"); - data["hashes"] = hashes; + data.set("hashes", hashes); res.deserialize(data); EXPECT_EQ(res.getHashes(), hashes); } diff --git a/test/source/api/responses/get_transactions_to_approve_test.cpp b/test/source/api/responses/get_transactions_to_approve_test.cpp index fca9c76..f2fb5ae 100644 --- a/test/source/api/responses/get_transactions_to_approve_test.cpp +++ b/test/source/api/responses/get_transactions_to_approve_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetTransactionsToApproveResponse, CtorShouldInitFields) { const IOTA::API::Responses::GetTransactionsToApprove res{ "TESTA", "TESTB" }; @@ -47,10 +48,10 @@ TEST(GetTransactionsToApproveResponse, Setters) { TEST(GetTransactionsToApproveResponse, DeserializeShouldSetFields) { IOTA::API::Responses::GetTransactionsToApprove res; - json data; + IOTA::Utils::json data; - data["trunkTransaction"] = "TEST1"; - data["branchTransaction"] = "TEST2"; + data.set("trunkTransaction", "TEST1"); + data.set("branchTransaction", "TEST2"); res.deserialize(data); EXPECT_EQ(res.getTrunkTransaction(), "TEST1"); diff --git a/test/source/api/responses/get_trytes_test.cpp b/test/source/api/responses/get_trytes_test.cpp index 1676395..d5b19ed 100644 --- a/test/source/api/responses/get_trytes_test.cpp +++ b/test/source/api/responses/get_trytes_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(GetTrytesResponse, DefaultCtorShouldInitFields) { const IOTA::API::Responses::GetTrytes res; @@ -74,11 +75,11 @@ TEST(GetTrytesResponse, SetTrytes) { TEST(GetTrytesResponse, DeserializeShouldSetFields) { IOTA::API::Responses::GetTrytes res; - json data; + IOTA::Utils::json data; std::vector trytes; trytes.push_back("TEST"); - data["trytes"] = trytes; + data.set("trytes", trytes); res.deserialize(data); EXPECT_EQ(res.getTrytes(), trytes); } diff --git a/test/source/api/responses/remove_neighbors_test.cpp b/test/source/api/responses/remove_neighbors_test.cpp index 91f6467..c1d867b 100644 --- a/test/source/api/responses/remove_neighbors_test.cpp +++ b/test/source/api/responses/remove_neighbors_test.cpp @@ -26,6 +26,7 @@ #include #include +#include TEST(RemoveNeighborsResponse, DefaultCtorShouldInitFields) { const IOTA::API::Responses::RemoveNeighbors res{}; @@ -52,9 +53,9 @@ TEST(RemoveNeighborsResponse, SetRemovedNeighbors) { TEST(RemoveNeighborsResponse, DeserializeShouldSetFields) { IOTA::API::Responses::RemoveNeighbors res; - json data; + IOTA::Utils::json data; - data["removedNeighbors"] = 42; + data.set("removedNeighbors", 42); res.deserialize(data); EXPECT_EQ(res.getRemovedNeighbors(), 42); }