Browse Source

JSON Parser n smth more

peercoin
Intel 11 years ago
parent
commit
8dca8f0932
  1. 1
      src/server/poolserver/Main.cpp
  2. 3
      src/server/poolserver/Server/Server.cpp
  3. 84
      src/server/poolserver/Stratum/Client.cpp
  4. 20
      src/server/poolserver/Stratum/Client.h
  5. 2
      src/server/poolserver/Stratum/Job.h
  6. 19
      src/server/poolserver/Stratum/Server.h
  7. 4
      src/server/shared/Bitcoin/Block.h
  8. 7
      src/server/shared/ByteBuffer.h
  9. 103
      src/server/shared/JSON/JSON.cpp
  10. 230
      src/server/shared/JSON/JSON.h
  11. 183
      src/server/shared/JSON/JSONReader.h
  12. 16
      src/server/shared/JSONRPC/JSONRPC.cpp

1
src/server/poolserver/Main.cpp

@ -34,6 +34,7 @@ bool InitConfig(int argc, char *argv[])
// Server // Server
descServer.add_options() descServer.add_options()
("MinDiffTime", boost::program_options::value<uint32_t>()->default_value(100), "Minimum server diff time") ("MinDiffTime", boost::program_options::value<uint32_t>()->default_value(100), "Minimum server diff time")
("MiningAddress", boost::program_options::value<std::string>()->default_value("n1w8gkPXdNGb6edm4vujBn71A72eQFCNCw"), "Address to send coins to")
; ;
// Stratum // Stratum

3
src/server/poolserver/Server/Server.cpp

@ -35,6 +35,9 @@ int Server::Run()
//InitDatabase(); //InitDatabase();
JSON node = JSON::FromString("{\"test\":{\"omg\":\"smth\"},\"other\":\"smth2\"}");
sLog.Info(LOG_SERVER, "Something: %s", node.ToString().c_str());
/*std::vector<byte> test = Util::ASCIIToBin("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"); /*std::vector<byte> test = Util::ASCIIToBin("4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b");
sLog.Info(LOG_SERVER, "Hash: %s", Util::BinToASCII(Crypto::SHA256D(test)).c_str()); sLog.Info(LOG_SERVER, "Hash: %s", Util::BinToASCII(Crypto::SHA256D(test)).c_str());
sLog.Info(LOG_SERVER, "RevHash: %s", Util::BinToASCII(Crypto::SHA256D(Util::Reverse(test))).c_str()); sLog.Info(LOG_SERVER, "RevHash: %s", Util::BinToASCII(Crypto::SHA256D(Util::Reverse(test))).c_str());

84
src/server/poolserver/Stratum/Client.cpp

@ -3,52 +3,84 @@
namespace Stratum namespace Stratum
{ {
void Client::OnMiningSubscribe(JSON msg) void Client::SendJob(bool clean)
{ {
_subscribed = true; if (clean)
_extranonce = _server->GetExtranonce(); _jobs.clear();
Job job = GetJob(); Job job = GetJob();
_jobs.push_back(job); uint64 jobid = _jobid++;
JSON response; _jobs[jobid] = job;
response.Set("id", msg["id"].Get<uint32>());
response.Set("error", NULL); // Coinbase parts
ByteBuffer coinbasebuf;
coinbasebuf << job.block->tx[0];
BinaryData coinbase = coinbasebuf.Binary();
// tx.version + tx.in[0].outpoint.hash + tx.in[0].outpoint.n + tx.script (block height)
uint32 cbsplit = 4 + 32 + 4 + 4;
BinaryData coinbase1 = BinaryData(coinbase.begin(), coinbase.begin() + cbsplit);
BinaryData coinbase2 = BinaryData(coinbase.begin() + cbsplit + 8, coinbase.end()); // plus extranonce size
JSON miningdiff; // Build merkle branch array
miningdiff.Add("mining.set_difficulty"); JSON merkle_branch(JSON_ARRAY);
JSON lala; uint64 branches = job.block->merkleBranches;
lala.Set("", 1); uint64 index = 0;
miningdiff.Add(lala); while (branches > 1) {
merkle_branch.Add(Util::BinToASCII(job.block->merkleTree[index+1]));
index += branches;
branches /= 2;
}
JSON params;
params.Add("bf");
params.Add(Util::BinToASCII(Util::Reverse(job.block->prevBlockHash)));
params.Add(Util::BinToASCII(coinbase1));
params.Add(Util::BinToASCII(coinbase2));
params.Add(merkle_branch);
params.Add(Util::BinToASCII(Util::Reverse(ByteBuffer(job.block->version).Binary())));
params.Add(Util::BinToASCII(Util::Reverse(ByteBuffer(job.block->bits).Binary())));
params.Add(Util::BinToASCII(Util::Reverse(ByteBuffer(job.block->time).Binary())));
params.Add(clean);
JSON msg;
msg["params"] = params;
msg["id"];
msg["method"] = "mining.notify";
SendMessage(msg);
}
void Client::OnMiningSubscribe(JSON msg)
{
_subscribed = true;
_extranonce = _server->GetExtranonce();
JSON notify; JSON notify;
notify.Add("mining.notify"); notify.Add("mining.notify");
notify.Add("abc"); notify.Add("ae6812eb4cd7735a302a8a9dd95cf71f");
JSON something;
something.Add(miningdiff);
something.Add(notify);
JSON result; JSON result;
result.Add(something); result.Add(notify);
ByteBuffer noncebuf; ByteBuffer noncebuf;
noncebuf << _extranonce; noncebuf << _extranonce;
JSON omg; result.Add(Util::BinToASCII(noncebuf.Binary()));
omg.Set("", Util::BinToASCII(noncebuf.Binary())); result.Add(int64(4));
result.Add(omg);
JSON shit;
shit.Set("", 4);
result.Add(shit);
response.Set("result", result); JSON response;
response["id"] = msg["id"].GetInt();
response["result"] = result;
response["error"];
SendMessage(response); SendMessage(response);
SendJob(false);
} }
Job Client::GetJob() Job Client::GetJob()
{ {
Job job; Job job;
job.work = _server->GetWork(); job.block = _server->GetWork();
return job; return job;
} }
} }

20
src/server/poolserver/Stratum/Client.h

@ -22,7 +22,7 @@ namespace Stratum
class Client class Client
{ {
public: public:
Client(Server* server, asio::io_service& io_service) : _server(server), _socket(io_service), _subscribed(false) Client(Server* server, asio::io_service& io_service) : _server(server), _socket(io_service), _subscribed(false), _jobid(0)
{ {
} }
@ -40,13 +40,12 @@ namespace Stratum
boost::bind(&Client::_OnReceive, this, asio::placeholders::error, asio::placeholders::bytes_transferred)); boost::bind(&Client::_OnReceive, this, asio::placeholders::error, asio::placeholders::bytes_transferred));
} }
void SendJob() void SendJob(bool clean);
{
}
void SendMessage(JSON msg) void SendMessage(JSON msg)
{ {
std::string data = msg.ToString(); std::string data = msg.ToString();
data += '\n';
sLog.Debug(LOG_SERVER, "Sending: %s", data.c_str()); sLog.Debug(LOG_SERVER, "Sending: %s", data.c_str());
_socket.send(boost::asio::buffer(data.c_str(), data.length())); _socket.send(boost::asio::buffer(data.c_str(), data.length()));
} }
@ -55,17 +54,17 @@ namespace Stratum
void OnMiningAuthorize(JSON msg) void OnMiningAuthorize(JSON msg)
{ {
std::string username = msg["result"][0].Get<std::string>(); std::string username = msg["result"][0].GetString();
JSON response; JSON response;
response.Set("id", msg["id"].Get<uint32>()); response["id"] = msg["id"].GetInt();
response.Set("error", NULL); response["error"];
response.Set("result", true); response["result"] = true;
SendMessage(response); SendMessage(response);
} }
void OnMessage(JSON msg) void OnMessage(JSON msg)
{ {
std::string method = msg["method"].Get<std::string>(); std::string method = msg["method"].GetString();
sLog.Debug(LOG_SERVER, "Method: %s", method.c_str()); sLog.Debug(LOG_SERVER, "Method: %s", method.c_str());
if (method.compare("mining.subscribe") == 0) if (method.compare("mining.subscribe") == 0)
@ -100,7 +99,8 @@ namespace Stratum
// Jobs // Jobs
bool _subscribed; bool _subscribed;
uint32 _extranonce; uint32 _extranonce;
std::vector<Job> _jobs; std::map<uint64, Job> _jobs;
uint64 _jobid;
}; };
} }

2
src/server/poolserver/Stratum/Job.h

@ -8,7 +8,7 @@ namespace Stratum
class Job class Job
{ {
public: public:
Bitcoin::BlockPtr work; Bitcoin::BlockPtr block;
}; };
} }

19
src/server/poolserver/Stratum/Server.h

@ -31,6 +31,7 @@ namespace Stratum
public: public:
Server(asio::io_service& io_service) : _io_service(io_service), _acceptor(io_service), _blockCheckTimer(io_service), _blockHeight(0), _extranonce(0) Server(asio::io_service& io_service) : _io_service(io_service), _acceptor(io_service), _blockCheckTimer(io_service), _blockHeight(0), _extranonce(0)
{ {
_pubkey = Util::ASCIIToBin(sConfig.Get<std::string>("MiningAddress"));
} }
~Server() ~Server()
@ -104,20 +105,20 @@ namespace Stratum
Bitcoin::BlockPtr block = Bitcoin::BlockPtr(new Bitcoin::Block()); Bitcoin::BlockPtr block = Bitcoin::BlockPtr(new Bitcoin::Block());
block->version = response["version"].Get<uint32>();; block->version = response["version"].GetInt();
block->prevBlockHash = Util::ASCIIToBin(response["previousblockhash"].Get<std::string>()); block->prevBlockHash = Util::ASCIIToBin(response["previousblockhash"].GetString());
block->time = response["curtime"].GetInt();
// Set bits // Set bits
ByteBuffer bitbuf(Util::ASCIIToBin(response["bits"].Get<std::string>())); ByteBuffer bitbuf(Util::ASCIIToBin(response["bits"].GetString()));
bitbuf >> block->bits; bitbuf >> block->bits;
// Add coinbase tx // Add coinbase tx
block->tx.push_back(CreateCoinbaseTX(_blockHeight, _pubkey, response["coinbasevalue"].Get<int64>())); block->tx.push_back(CreateCoinbaseTX(_blockHeight, _pubkey, response["coinbasevalue"].GetInt()));
// Add other transactions // Add other transactions
JSON trans = response["transactions"]; JSON trans = response["transactions"];
for (uint64 i = 0; i < trans.Size(); ++i) { for (uint64 i = 0; i < trans.Size(); ++i) {
ByteBuffer txbuf(Util::ASCIIToBin(trans[i]["data"].Get<std::string>())); ByteBuffer txbuf(Util::ASCIIToBin(trans[i]["data"].GetString()));
Bitcoin::Transaction tx; Bitcoin::Transaction tx;
txbuf >> tx; txbuf >> tx;
block->tx.push_back(tx); block->tx.push_back(tx);
@ -135,7 +136,7 @@ namespace Stratum
sLog.Debug(LOG_STRATUM, "Checking for new blocks..."); sLog.Debug(LOG_STRATUM, "Checking for new blocks...");
JSON response = _bitcoinrpc->Query("getinfo"); JSON response = _bitcoinrpc->Query("getinfo");
uint32 curBlock = response["blocks"].Get<uint32>(); uint32 curBlock = response["blocks"].GetInt();
if (curBlock > _blockHeight) { if (curBlock > _blockHeight) {
sLog.Debug(LOG_STRATUM, "New block on network! Height: %u", curBlock); sLog.Debug(LOG_STRATUM, "New block on network! Height: %u", curBlock);
@ -149,8 +150,10 @@ namespace Stratum
Bitcoin::Transaction CreateCoinbaseTX(uint32 blockHeight, BinaryData pubkey, int64 value) Bitcoin::Transaction CreateCoinbaseTX(uint32 blockHeight, BinaryData pubkey, int64 value)
{ {
// Extranonce placeholder
BinaryData extranonce_ph(8, 0);
ByteBuffer scriptsig; ByteBuffer scriptsig;
scriptsig << _blockHeight; scriptsig << _blockHeight << extranonce_ph;
Bitcoin::OutPoint outpoint; Bitcoin::OutPoint outpoint;
outpoint.hash.resize(32, 0); outpoint.hash.resize(32, 0);

4
src/server/shared/Bitcoin/Block.h

@ -28,6 +28,7 @@ namespace Bitcoin
// Other data // Other data
std::vector<BinaryData> merkleTree; std::vector<BinaryData> merkleTree;
uint64 merkleBranches;
void BuildMerkleTree() void BuildMerkleTree()
{ {
@ -40,6 +41,9 @@ namespace Bitcoin
++levels; ++levels;
} }
// Used when sending merkle branches
merkleBranches = branches;
// Add transactions // Add transactions
for (uint64 i = 0; i < branches; ++i) for (uint64 i = 0; i < branches; ++i)
merkleTree.push_back(tx[std::min(i, tx.size()-1)].GetHash()); merkleTree.push_back(tx[std::min(i, tx.size()-1)].GetHash());

7
src/server/shared/ByteBuffer.h

@ -8,6 +8,13 @@ class ByteBuffer
{ {
public: public:
ByteBuffer(): pointer(0) {} ByteBuffer(): pointer(0) {}
template<typename T>
ByteBuffer(T data): pointer(0)
{
Append<T>(data);
}
ByteBuffer(BinaryData data): pointer(0), vec(data) {} ByteBuffer(BinaryData data): pointer(0), vec(data) {}
ByteBuffer& operator<<(ByteBuffer& b) ByteBuffer& operator<<(ByteBuffer& b)

103
src/server/shared/JSON/JSON.cpp

@ -1,22 +1,109 @@
#include "JSON.h" #include "JSON.h"
#include "JSONReader.h"
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/assign.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include "Log.h"
JSON JSON::FromString(std::string jsonstring) JSON JSON::FromString(std::string jsonstring)
{ {
JSON json; JSON node;
json.pt = new boost::property_tree::ptree(); JSONReader::Parse(jsonstring, node);
std::stringstream ss; return node;
ss.str(jsonstring);
boost::property_tree::json_parser::read_json(ss, *json.pt);
return json;
} }
std::string JSON::ToString() std::string JSON::ToString()
{ {
std::stringstream ss; std::stringstream ss;
boost::property_tree::json_parser::write_json(ss, *pt); Write(ss);
return ss.str(); std::string json = ss.str();
// If it's array we have to wrap json into {}
if (json[0] == '[')
return "{" + json + "}";
else
return json;
}
void JSON::Write(std::stringstream& ss)
{
switch (_type)
{
case JSON_NULL:
ss << "null";
break;
case JSON_BOOL:
if (GetBool())
ss << "true";
else
ss << "false";
break;
case JSON_INTEGER:
ss << GetInt();
break;
case JSON_DOUBLE:
ss << GetDouble();
break;
case JSON_STRING:
ss << '"' << EscapeString(GetString()) << '"';
break;
case JSON_ARRAY:
{
ss << '[';
for (uint32 i = 0; i < _vec.size(); ++i)
{
if (i)
ss << ", ";
_vec[i].Write(ss);
}
ss << ']';
break;
}
case JSON_OBJECT:
{
ss << '{';
for (uint64 i = 0; i < _mapOrder.size(); ++i)
{
if (i)
ss << ',';
std::string key = _mapOrder[i];
ss << '"' << key << "\":";
_map[key].Write(ss);
}
ss << '}';
break;
}
default:
throw "Unknown type";
}
}
std::string JSON::EscapeString(std::string str)
{
static std::map<char, std::string> escapes = boost::assign::map_list_of
('"', "\\\"")
('\'', "\\'");
/*('\\', "\\\\")
('/', "\\/")
('b', "\\b")
('f', "\\f")
('n', "\\n")
('r', "\\r")
('t', "\\t")
('u', "\\u");*/
for (uint32 i = 0; i < str.length(); ++i)
{
if (escapes.count(str[i])) {
std::string esc = escapes[str[i]];
str.replace(i, 1, esc.c_str(), esc.length());
i += esc.length()-1;
}
}
return str;
} }

230
src/server/shared/JSON/JSON.h

@ -4,85 +4,235 @@
#include "Common.h" #include "Common.h"
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp> #include <boost/property_tree/json_parser.hpp>
#include <boost/cstdint.hpp> #include <boost/variant.hpp>
#include <string> #include <string>
#include <utility> #include <utility>
#include <sstream>
#include <vector>
#include <map>
#include <Log.h>
enum JSONValueType
{
JSON_NULL = 0,
JSON_ARRAY = 1,
JSON_OBJECT = 2,
JSON_BOOL = 3,
JSON_INTEGER = 4,
JSON_DOUBLE = 5,
JSON_STRING = 6
};
typedef boost::variant<bool, int64, double, std::string> JSONValue;
class JSON class JSON
{ {
public: public:
static JSON FromString(std::string jsonstring); static JSON FromString(std::string jsonstring);
JSON(bool base = true) : _base(base), pt(NULL) JSON(JSONValueType type = JSON_NULL) : _type(type)
{ {
if (base)
pt = new boost::property_tree::ptree();
} }
~JSON() ~JSON()
{ {
//if (_base && pt)
// delete pt;
} }
template<class T> // Arrays
T Get() JSON& operator[] (uint32 index)
{
return _vec[index];
}
template<typename T>
void Add(T val)
{
if (_type != JSON_ARRAY) {
if (_type != JSON_NULL)
throw "Bad type";
else
_type = JSON_ARRAY;
}
JSON node;
node = val;
_vec.push_back(node);
}
void AddNull()
{
if (_type != JSON_ARRAY) {
if (_type != JSON_NULL)
throw "Bad type";
else
_type = JSON_ARRAY;
}
JSON node;
_vec.push_back(node);
}
// Objects
JSON& operator[] (std::string key)
{
if (_type != JSON_OBJECT) {
if (_type != JSON_NULL)
throw "Bad type";
else
_type = JSON_OBJECT;
}
// Keep insertion order
if (!_map.count(key))
_mapOrder.push_back(key);
// std::map[] automatically creates key if it does not exist
return _map[key];
}
template<typename T>
void Set(std::string key, T val)
{
if (_type != JSON_OBJECT) {
if (_type != JSON_NULL)
throw "Bad type";
else
_type = JSON_OBJECT;
}
// Keep insertion order
if (!_map.count(key))
_mapOrder.push_back(key);
// std::map[] automatically creates key if it does not exist
_map[key] = val;
}
// Primitive types
bool GetBool()
{
if (_type != JSON_BOOL)
throw "Bad type";
return boost::get<bool>(_val);
}
void operator= (bool val)
{
_type = JSON_BOOL;
_val = val;
}
int64 GetInt()
{
if (_type != JSON_INTEGER)
throw "Bad type";
return boost::get<int64>(_val);
}
void operator= (int64 val)
{
_type = JSON_INTEGER;
_val = val;
}
double GetDouble()
{
if (_type != JSON_DOUBLE)
throw "Bad type";
return boost::get<double>(_val);
}
void operator= (double val)
{
_type = JSON_DOUBLE;
_val = val;
}
std::string GetString()
{
if (_type != JSON_STRING)
throw "Bad type";
return boost::get<std::string>(_val);
}
void operator= (std::string val)
{ {
return pt->get_value<T>(); _type = JSON_STRING;
_val = val;
} }
JSON operator[] (std::string key) // Fix for static strings
void operator= (const char* val)
{ {
JSON json(false); _type = JSON_STRING;
json.pt = &pt->get_child(key); _val = std::string(val);
return json;
} }
JSON operator[] (uint32 index) // Generic function
bool Empty()
{ {
JSON json(false); if (_type == JSON_NULL)
boost::property_tree::ptree::iterator it = pt->begin(); return true;
for (int i = 0; i < index; ++i) else
++it; return false;
boost::property_tree::ptree::value_type& kv = *it;
json.pt = &kv.second;
return json;
} }
template<class T> uint32 Size()
inline void Set(std::string key, T value)
{ {
pt->put<T>(key, value); if (_type == JSON_ARRAY)
return _vec.size();
else if (_type == JSON_OBJECT)
return _map.size();
else
throw "Type has no size";
} }
template<class T> JSONValueType GetType()
inline void Add(T value)
{ {
pt->push_back(std::make_pair("", value)); return _type;
} }
uint64_t Size() void SetType(JSONValueType type)
{ {
return pt->size(); _type = type;
} }
// Used for writting
std::string EscapeString(std::string);
std::string ToString(); std::string ToString();
void Write(std::stringstream& ss);
void SetRaw(std::string val);
void AddRaw(std::string val);
std::string hackfix;
private:
// Vector is used to store arrays
std::vector<JSON> _vec;
// Map is used to store objects
std::map<std::string, JSON> _map;
// Map insertion order
std::vector<std::string> _mapOrder;
// Boost variant stores primitive types
JSONValue _val;
boost::property_tree::ptree* pt; JSONValueType _type;
bool _base;
}; };
template<> template<>
inline void JSON::Set<JSON>(std::string key, JSON value) inline void JSON::Add(JSON& node)
{ {
pt->put_child(key, *value.pt); if (_type != JSON_ARRAY) {
} if (_type != JSON_NULL)
throw "Bad type";
template<> else
inline void JSON::Add<JSON>(JSON value) _type = JSON_ARRAY;
{ }
pt->push_back(std::make_pair("", *value.pt));
_vec.push_back(node);
} }
#endif #endif

183
src/server/shared/JSON/JSONReader.h

@ -0,0 +1,183 @@
#ifndef JSON_READER_H_
#define JSON_READER_H_
#include "Common.h"
#include "JSON.h"
#include <boost/spirit/include/qi.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <string>
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace JSONReader
{
class SemanticFunctions
{
public:
SemanticFunctions(JSON& node)
{
_stack.push_back(&node);
}
void BeginObject(char ch)
{
if (_stack.back()->GetType() == JSON_NULL)
_stack.back()->SetType(JSON_OBJECT);
else {
JSON* node = new JSON(JSON_OBJECT);
_stack.push_back(node);
}
}
void EndObject(char ch)
{
JSON* node = _stack.back();
_stack.pop_back();
if (_stack.size()) {
SetData(*node);
delete node;
}
}
void BeginArray(char ch)
{
if (_stack.back()->GetType() == JSON_NULL)
_stack.back()->SetType(JSON_ARRAY);
else {
JSON* node = new JSON(JSON_ARRAY);
_stack.push_back(node);
}
}
void EndArray(char ch)
{
JSON* node = _stack.back();
_stack.pop_back();
if (_stack.size()) {
SetData(*node);
delete node;
}
}
void ObjectKey(std::string str)
{
_nameStack.push_back(str);
}
void String(std::string str)
{
SetData(str);
}
void BoolTrue(std::string str)
{
SetData(true);
}
void BoolFalse(std::string str)
{
SetData(false);
}
void Null(std::string str)
{
SetData(JSON(JSON_NULL));
}
void Integer(int64 val)
{
SetData(val);
}
void Double(double val)
{
SetData(val);
}
template<typename T>
void SetData(T data)
{
if (_stack.back()->GetType() == JSON_OBJECT) {
_stack.back()->Set<T>(_nameStack.back(), data);
_nameStack.pop_back();
} else if (_stack.back()->GetType() == JSON_ARRAY)
_stack.back()->Add<T>(data);
else
throw "fail";
}
private:
// Push all nested nodes here
std::vector<JSON*> _stack;
// Node is added to the main tree when is closed so we need a name stack
std::vector<std::string> _nameStack;
};
template<typename T>
struct strict_real_policies : qi::real_policies<T>
{
static bool const expect_dot = true;
};
qi::real_parser<double, strict_real_policies<double> > strict_double;
template<typename Iterator>
struct Grammar : qi::grammar<Iterator, ascii::space_type>
{
Grammar(SemanticFunctions& smfunc) : _smfunc(smfunc), Grammar::base_type(json)
{
typedef boost::function<void(char, qi::unused_type, qi::unused_type)> CharFunc;
typedef boost::function<void(std::string, qi::unused_type, qi::unused_type)> StrFunc;
typedef boost::function<void(double, qi::unused_type, qi::unused_type)> DoubleFunc;
typedef boost::function<void(int64, qi::unused_type, qi::unused_type)> IntFunc;
CharFunc BeginObj(boost::bind(&SemanticFunctions::BeginObject, &_smfunc, _1));
CharFunc EndObj(boost::bind(&SemanticFunctions::EndObject, &_smfunc, _1));
CharFunc BeginArray(boost::bind(&SemanticFunctions::BeginArray, &_smfunc, _1));
CharFunc EndArray(boost::bind(&SemanticFunctions::EndArray, &_smfunc, _1));
StrFunc NewKey(boost::bind(&SemanticFunctions::ObjectKey, &_smfunc, _1));
StrFunc NewStr(boost::bind(&SemanticFunctions::String, &_smfunc, _1));
StrFunc NewTrue(boost::bind(&SemanticFunctions::BoolTrue, &_smfunc, _1));
StrFunc NewFalse(boost::bind(&SemanticFunctions::BoolFalse, &_smfunc, _1));
StrFunc NewNull(boost::bind(&SemanticFunctions::Null, &_smfunc, _1));
DoubleFunc NewDouble(boost::bind(&SemanticFunctions::Double, &_smfunc, _1));
IntFunc NewInt(boost::bind(&SemanticFunctions::Integer, &_smfunc, _1));
json = object | array;
object = qi::char_('{')[BeginObj] >> -members >> qi::char_('}')[EndObj];
members = pair % ',';
pair = string[NewKey] >> ':' >> value;
array = qi::char_('[')[BeginArray] >> -elements >> qi::char_(']')[EndArray];
elements = value % ',';
value = object | array | string[NewStr] | number | qi::string("true")[NewTrue] | qi::string("false")[NewFalse] | qi::string("null")[NewNull];
string = qi::lexeme['"' >> *(qi::char_ - '"') >> '"'];
number = strict_double[NewDouble] | qi::long_long[NewInt];
}
qi::rule<Iterator, ascii::space_type> json;
qi::rule<Iterator, ascii::space_type> object;
qi::rule<Iterator, ascii::space_type> members;
qi::rule<Iterator, ascii::space_type> pair;
qi::rule<Iterator, ascii::space_type> array;
qi::rule<Iterator, ascii::space_type> elements;
qi::rule<Iterator, ascii::space_type> value;
qi::rule<Iterator, std::string(), ascii::space_type> string;
qi::rule<Iterator, ascii::space_type> number;
// Functions
SemanticFunctions& _smfunc;
};
inline void Parse(std::string str, JSON& node)
{
SemanticFunctions smfunc(node);
Grammar<std::string::const_iterator> g(smfunc);
std::string::const_iterator begin = str.begin();
std::string::const_iterator end = str.end();
qi::phrase_parse(begin, end, g, ascii::space);
}
}
#endif

16
src/server/shared/JSONRPC/JSONRPC.cpp

@ -43,12 +43,12 @@ bool JSONRPC::Connect(JSONRPCConnectionInfo connInfo)
JSON JSONRPC::Query(std::string method, JSON params) JSON JSONRPC::Query(std::string method, JSON params)
{ {
JSON request(true); JSON request;
request.Set("jsonrpc", "1.0"); request["jsonrpc"] = "1.0";
request.Set("id", 1); request["id"] = int64(1);
request.Set("method", method); request["method"] = method;
if (params.Size() > 0) if (params.Size() > 0)
request.Set("params", params); request["params"] = params;
std::string jsonstring = request.ToString(); std::string jsonstring = request.ToString();
sLog.Debug(LOG_JSONRPC, "JSONRPC::Query(): JSONString: %s", jsonstring.c_str()); sLog.Debug(LOG_JSONRPC, "JSONRPC::Query(): JSONString: %s", jsonstring.c_str());
@ -61,7 +61,7 @@ JSON JSONRPC::Query(std::string method, JSON params)
if (error) if (error)
{ {
sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Error connecting to '%s': %s", _connInfo.Host.c_str(), boost::system::system_error(error).what()); sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Error connecting to '%s': %s", _connInfo.Host.c_str(), boost::system::system_error(error).what());
return NULL; throw "fail";
} }
boost::asio::streambuf request_buf; boost::asio::streambuf request_buf;
@ -91,13 +91,13 @@ JSON JSONRPC::Query(std::string method, JSON params)
if (!response_stream || http_version.substr(0, 5) != "HTTP/") if (!response_stream || http_version.substr(0, 5) != "HTTP/")
{ {
sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Malformed HTTP Response"); sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Malformed HTTP Response");
return NULL; throw "fail";
} }
if (status_code != 200) if (status_code != 200)
{ {
sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Returned status code: %u", status_code); sLog.Error(LOG_JSONRPC, "JSONRPC::Query(): Returned status code: %u", status_code);
return NULL; throw "fail";
} }
std::vector<std::string> headers; std::vector<std::string> headers;

Loading…
Cancel
Save