mirror of
https://github.com/EvernodeXRPL/sashimono.git
synced 2026-04-29 15:38:00 +00:00
Introduce message threads and message handling (#4)
This commit is contained in:
252
src/msg/json/msg_json.cpp
Normal file
252
src/msg/json/msg_json.cpp
Normal file
@@ -0,0 +1,252 @@
|
||||
#include "msg_json.hpp"
|
||||
|
||||
namespace msg::json
|
||||
{
|
||||
// JSON separators
|
||||
constexpr const char *SEP_COMMA = "\",\"";
|
||||
constexpr const char *SEP_COLON = "\":\"";
|
||||
constexpr const char *SEP_COMMA_NOQUOTE = ",\"";
|
||||
constexpr const char *SEP_COLON_NOQUOTE = "\":";
|
||||
constexpr const char *DOUBLE_QUOTE = "\"";
|
||||
|
||||
/**
|
||||
* Parses a json message sent by the message board.
|
||||
* @param d Jsoncons document to which the parsed json should be loaded.
|
||||
* @param message The message to parse.
|
||||
* Accepted message format:
|
||||
* {
|
||||
* 'type': '<message type>'
|
||||
* ...
|
||||
* }
|
||||
* @return 0 on successful parsing. -1 for failure.
|
||||
*/
|
||||
int parse_message(jsoncons::json &d, std::string_view message)
|
||||
{
|
||||
try
|
||||
{
|
||||
d = jsoncons::json::parse(message, jsoncons::strict_json_parsing());
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR << "JSON message parsing failed. " << e.what();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Check existence of msg type field.
|
||||
if (!d.contains(msg::FLD_TYPE) || !d[msg::FLD_TYPE].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "JSON message 'type' missing or invalid.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the message 'type' value from the json document.
|
||||
*/
|
||||
int extract_type(std::string &extracted_type, const jsoncons::json &d)
|
||||
{
|
||||
extracted_type = d[msg::FLD_TYPE].as<std::string>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts type, id and pubkey in the msg.
|
||||
* @param type Type in the message.
|
||||
* @param id id in the message.
|
||||
* @param pubkey Pubkey in the message.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* ...
|
||||
* "type": "<message type>",
|
||||
* "id": "<message id>",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* ...
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_commons(std::string &type, std::string &id, std::string &pubkey, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_type(type, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_ID))
|
||||
{
|
||||
LOG_ERROR << "Field id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d.contains(msg::FLD_PUBKEY))
|
||||
{
|
||||
LOG_ERROR << "Field owner_pubkey is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_PUBKEY].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid owner_pubkey value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
id = d[msg::FLD_ID].as<std::string>();
|
||||
pubkey = d[msg::FLD_PUBKEY].as<std::string>();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts create message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "create",
|
||||
* "owner_pubkey": "<pubkey of the owner>"
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_create_message(create_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts destroy message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "destroy",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* "contract_id": "<contract id>",
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_destroy_message(destroy_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_CONTRACT_ID))
|
||||
{
|
||||
LOG_ERROR << "Field contract_id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_CONTRACT_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid contract_id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.contract_id = d[msg::FLD_CONTRACT_ID].as<std::string>();
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts start message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "start",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* "contract_id": "<contract id>",
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_start_message(start_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_CONTRACT_ID))
|
||||
{
|
||||
LOG_ERROR << "Field contract_id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_CONTRACT_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid contract_id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.contract_id = d[msg::FLD_CONTRACT_ID].as<std::string>();
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts stop message from msg.
|
||||
* @param msg Populated msg object.
|
||||
* @param d The json document holding the read request message.
|
||||
* Accepted signed input container format:
|
||||
* {
|
||||
* "type": "stop",
|
||||
* "owner_pubkey": "<pubkey of the owner>",
|
||||
* "contract_id": "<contract id>",
|
||||
* }
|
||||
* @return 0 on successful extraction. -1 for failure.
|
||||
*/
|
||||
int extract_stop_message(stop_msg &msg, const jsoncons::json &d)
|
||||
{
|
||||
if (extract_commons(msg.type, msg.id, msg.pubkey, d) == -1)
|
||||
return -1;
|
||||
|
||||
if (!d.contains(msg::FLD_CONTRACT_ID))
|
||||
{
|
||||
LOG_ERROR << "Field contract_id is missing.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!d[msg::FLD_CONTRACT_ID].is<std::string>())
|
||||
{
|
||||
LOG_ERROR << "Invalid contract_id value.";
|
||||
return -1;
|
||||
}
|
||||
|
||||
msg.contract_id = d[msg::FLD_CONTRACT_ID].as<std::string>();
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a response json.
|
||||
* @param msg Buffer to construct the generated json message string into.
|
||||
* Message format:
|
||||
* {
|
||||
* 'type': '<message type>',
|
||||
* "content": "<any string>"
|
||||
* }
|
||||
* @param response_type Type of the response.
|
||||
* @param content Content inside the response.
|
||||
*/
|
||||
void create_response(std::string &msg, std::string_view response_type, std::string_view content)
|
||||
{
|
||||
msg.reserve(1024);
|
||||
msg += "{\"";
|
||||
msg += msg::FLD_TYPE;
|
||||
msg += SEP_COLON;
|
||||
msg += response_type;
|
||||
msg += SEP_COMMA;
|
||||
msg += msg::FLD_CONTENT;
|
||||
msg += SEP_COLON;
|
||||
msg += content;
|
||||
msg += "\"}";
|
||||
}
|
||||
|
||||
} // namespace msg::json
|
||||
Reference in New Issue
Block a user