Cryptocurrency mining pool written in C++ for speed. Supports Stratum.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

184 lines
6.0 KiB

#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();
if (!qi::phrase_parse(begin, end, g, ascii::space))
throw JSONException("Failed to parse JSON");
}
}
#endif