diff options
| -rw-r--r-- | libjsonpp/Jamfile.jam | 3 | ||||
| -rw-r--r-- | libjsonpp/json.ll | 3 | ||||
| -rw-r--r-- | libjsonpp/jsonFlexLexer.cpp | 71 | ||||
| -rw-r--r-- | libjsonpp/jsonFlexLexer.h | 40 | ||||
| -rw-r--r-- | libjsonpp/jsonValueFlexLexer.cpp | 72 | ||||
| -rw-r--r-- | libjsonpp/jsonValueFlexLexer.h | 34 | ||||
| -rw-r--r-- | libjsonpp/jsonpp.cpp | 14 | ||||
| -rw-r--r-- | libjsonpp/jsonpp.h | 23 | ||||
| -rw-r--r-- | libjsonpp/parse.cpp | 9 | ||||
| -rw-r--r-- | libjsonpp/serialize.cpp | 3 | 
10 files changed, 162 insertions, 110 deletions
| diff --git a/libjsonpp/Jamfile.jam b/libjsonpp/Jamfile.jam index c956b7b..7f607bd 100644 --- a/libjsonpp/Jamfile.jam +++ b/libjsonpp/Jamfile.jam @@ -17,7 +17,6 @@ lib jsonpp :  	:  	<include>.  	<library>..//glibmm -	<define>yyFlexLexer=jsonBaseFlexLexer  	: :  	<include>.  	; @@ -58,5 +57,5 @@ run  	testEncoding  	; -package.install install : <install-source-root>. : : jsonpp : [ glob *.h : jsonFlexLexer.h ] ; +package.install install : <install-source-root>. : : jsonpp : [ glob *.h : jsonValueFlexLexer.h ] ; diff --git a/libjsonpp/json.ll b/libjsonpp/json.ll index 391556d..12e46a9 100644 --- a/libjsonpp/json.ll +++ b/libjsonpp/json.ll @@ -8,6 +8,7 @@  %option prefix="jsonBase"  %{ +#include <glibmm/ustring.h>  #include "jsonFlexLexer.h"  #pragma GCC diagnostic ignored "-Wsign-compare"  #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" @@ -86,7 +87,7 @@ text [^\\\"]*  			yy_pop_state();  			break;  		case OBJECT_ITEM: -			name = encodeBuf(); +			PushKey(encodeBuf());  			BEGIN(COLON);  			break;  	} diff --git a/libjsonpp/jsonFlexLexer.cpp b/libjsonpp/jsonFlexLexer.cpp index 0964c1c..df29d8f 100644 --- a/libjsonpp/jsonFlexLexer.cpp +++ b/libjsonpp/jsonFlexLexer.cpp @@ -1,87 +1,32 @@ -#include "jsonFlexLexer.h" +#include "jsonValueFlexLexer.h"  #include <glibmm/convert.h>  namespace json { -	const std::string UTF8 { "utf-8" }; - -	jsonFlexLexer::jsonFlexLexer(std::istream & in, std::string enc, Value & v) : +	jsonFlexLexer::jsonFlexLexer(std::istream & in, std::string enc) :  		yyFlexLexer(&in, nullptr), -		encoding(enc != UTF8 ? std::move(enc) : std::string()) +		encoding(enc != utf8 ? std::move(enc) : std::string())  	{  		yy_push_state(0); -		acceptValues.push([&v](auto && value) { -			v = std::forward<Value>(value); -			return &v; -		});  	}  	std::string  	jsonFlexLexer::encodeBuf() const  	{  		if (!encoding.empty()) { -			return Glib::convert(buf, UTF8, encoding); +			return Glib::convert(buf, utf8, encoding);  		}  		return buf;  	}  	void -	jsonFlexLexer::BeginObject() -	{ -		auto object = std::get_if<Object>(acceptValues.top()(Object())); -		acceptValues.push([object,this](auto && value) { -			return &object->emplace(std::move(name), std::forward<Value>(value)).first->second; -		}); -	} - -	void -	jsonFlexLexer::BeginArray() -	{ -		auto array = std::get_if<Array>(acceptValues.top()(Array())); -		acceptValues.push([array](auto && value) { -			return &array->emplace_back(std::forward<Value>(value)); -		}); -	} - -	void -	jsonFlexLexer::PushNull() -	{ -		acceptValues.top()(Null()); -	} - -	void -	jsonFlexLexer::PushBoolean(bool value) -	{ -		acceptValues.top()(value); -	} - -	void -	jsonFlexLexer::PushNumber(double value) -	{ -		acceptValues.top()(value); -	} - -	void -	jsonFlexLexer::PushText(std::string && value) -	{ -		acceptValues.top()(std::move(value)); -	} - -	void -	jsonFlexLexer::EndArray() -	{ -		acceptValues.pop(); -	} - -	void -	jsonFlexLexer::EndObject() +	jsonFlexLexer::LexerError(const char * msg)  	{ -		acceptValues.pop(); +		throw ParseError(msg, 0, 0);  	} -	void -	jsonFlexLexer::LexerError(const char * msg) +	ParseError::ParseError(const char * at, int l, int s) : +		std::invalid_argument(Glib::ustring::compose("Parse error at or near %1 (line %2, state %3)", at, l, s))  	{ -		throw ParseError(msg, 0, 0);  	}  } diff --git a/libjsonpp/jsonFlexLexer.h b/libjsonpp/jsonFlexLexer.h index 43770d5..bbd6b95 100644 --- a/libjsonpp/jsonFlexLexer.h +++ b/libjsonpp/jsonFlexLexer.h @@ -2,41 +2,45 @@  #define JSONFLEXLEXER_H  #include <string> -#include "jsonpp.h" -#include <stack> -#include <functional> +#include <stdexcept>  #ifndef FLEX_SCANNER +#define yyFlexLexer jsonBaseFlexLexer  #include <FlexLexer.h>  #endif  namespace json { +#pragma GCC visibility push(default) +	class ParseError : public std::invalid_argument { +		public: +			ParseError(const char *, int, int); +	}; +  	class jsonFlexLexer : public yyFlexLexer {  		public: -			jsonFlexLexer(std::istream &, std::string enc, Value & v); +			jsonFlexLexer(std::istream &, std::string enc);  			int yylex() override; -			void LexerError(const char * msg) override; -			void BeginObject(); -			void BeginArray(); +		private: +			virtual void BeginObject() = 0; +			virtual void BeginArray() = 0; -			void PushBoolean(bool); -			void PushNumber(double); -			void PushNull(); -			void PushText(std::string &&); +			virtual void PushBoolean(bool) = 0; +			virtual void PushNumber(double) = 0; +			virtual void PushNull() = 0; +			virtual void PushText(std::string &&) = 0; +			virtual void PushKey(std::string &&) = 0; -			void EndArray(); -			void EndObject(); +			virtual void EndArray() = 0; +			virtual void EndObject() = 0; -		private: +			void LexerError(const char * msg) override;  			std::string encodeBuf() const; -			std::string buf, name; +			std::string buf;  			const std::string encoding; - -			using AcceptValue = std::function<Value *(Value &&)>; -			std::stack<AcceptValue> acceptValues;  	}; +#pragma GCC visibility pop  }  #endif diff --git a/libjsonpp/jsonValueFlexLexer.cpp b/libjsonpp/jsonValueFlexLexer.cpp new file mode 100644 index 0000000..5225c95 --- /dev/null +++ b/libjsonpp/jsonValueFlexLexer.cpp @@ -0,0 +1,72 @@ +#include "jsonValueFlexLexer.h" + +namespace json { +	jsonValueFlexLexer::jsonValueFlexLexer(std::istream & in, std::string enc, Value & v) : +		jsonFlexLexer(in, std::move(enc)) +	{ +		acceptValues.push([&v](auto && value) { +			return &(v = std::forward<Value>(value)); +		}); +	} + +	void +	jsonValueFlexLexer::BeginObject() +	{ +		auto object = std::get_if<Object>(acceptValues.top()(Object())); +		acceptValues.push([object,this](auto && value) { +			return &object->emplace(std::move(name), std::forward<Value>(value)).first->second; +		}); +	} + +	void +	jsonValueFlexLexer::BeginArray() +	{ +		auto array = std::get_if<Array>(acceptValues.top()(Array())); +		acceptValues.push([array](auto && value) { +			return &array->emplace_back(std::forward<Value>(value)); +		}); +	} + +	void +	jsonValueFlexLexer::PushNull() +	{ +		acceptValues.top()(Null()); +	} + +	void +	jsonValueFlexLexer::PushBoolean(bool value) +	{ +		acceptValues.top()(value); +	} + +	void +	jsonValueFlexLexer::PushNumber(double value) +	{ +		acceptValues.top()(value); +	} + +	void +	jsonValueFlexLexer::PushText(std::string && value) +	{ +		acceptValues.top()(std::forward<std::string>(value)); +	} + +	void +	jsonValueFlexLexer::PushKey(std::string && value) +	{ +		name = std::forward<std::string>(value); +	} + +	void +	jsonValueFlexLexer::EndArray() +	{ +		acceptValues.pop(); +	} + +	void +	jsonValueFlexLexer::EndObject() +	{ +		acceptValues.pop(); +	} +} + diff --git a/libjsonpp/jsonValueFlexLexer.h b/libjsonpp/jsonValueFlexLexer.h new file mode 100644 index 0000000..82f3d62 --- /dev/null +++ b/libjsonpp/jsonValueFlexLexer.h @@ -0,0 +1,34 @@ +#ifndef JSONVALUEFLEXLEXER_H +#define JSONVALUEFLEXLEXER_H + +#include "jsonFlexLexer.h" +#include "jsonpp.h" +#include <stack> +#include <functional> + +namespace json { +	class jsonValueFlexLexer : public jsonFlexLexer { +		public: +			jsonValueFlexLexer(std::istream &, std::string enc, Value & v); + +			void BeginObject() override; +			void BeginArray() override; + +			void PushBoolean(bool) override; +			void PushNumber(double) override; +			void PushNull() override; +			void PushText(std::string &&) override; +			void PushKey(std::string &&) override; + +			void EndArray() override; +			void EndObject() override; + +		private: +			using AcceptValue = std::function<Value *(Value &&)>; +			std::stack<AcceptValue> acceptValues; +			std::string name; +	}; +} + +#endif + diff --git a/libjsonpp/jsonpp.cpp b/libjsonpp/jsonpp.cpp new file mode 100644 index 0000000..db2ac63 --- /dev/null +++ b/libjsonpp/jsonpp.cpp @@ -0,0 +1,14 @@ +#include "jsonpp.h" + +namespace json { +	const std::string null("null"); +	const std::string utf8("utf-8"); + +	static_assert(std::is_move_constructible<Value>::value); +	static_assert(std::is_nothrow_move_constructible<Object>::value); +	static_assert(std::is_nothrow_move_constructible<Array>::value); +	static_assert(std::is_move_assignable<Value>::value); +	static_assert(std::is_nothrow_move_assignable<Object>::value); +	static_assert(std::is_nothrow_move_assignable<Array>::value); +} + diff --git a/libjsonpp/jsonpp.h b/libjsonpp/jsonpp.h index 67afb36..ac45acd 100644 --- a/libjsonpp/jsonpp.h +++ b/libjsonpp/jsonpp.h @@ -1,22 +1,20 @@ -#ifndef JSON_H -#define JSON_H +#ifndef JSONPP_H +#define JSONPP_H  #include <glibmm/ustring.h>  #include <variant>  #include <map>  #include <vector> -#include <stdexcept> +#include "jsonFlexLexer.h" -#pragma GCC visibility push(default)  namespace json { -	class ParseError : public std::invalid_argument { -		public: -			ParseError(const char *, int, int); -	}; +	extern const std::string utf8; +	extern const std::string null;  	typedef Glib::ustring String;  	typedef double Number;  	typedef bool Boolean; +#pragma GCC visibility push(default)  	class Null { };  	class Object;  	class Array; @@ -32,21 +30,14 @@ namespace json {  			using A::A;  	}; -	static_assert(std::is_move_constructible<Value>::value); -	static_assert(std::is_nothrow_move_constructible<Object>::value); -	static_assert(std::is_nothrow_move_constructible<Array>::value); -	static_assert(std::is_move_assignable<Value>::value); -	static_assert(std::is_nothrow_move_assignable<Object>::value); -	static_assert(std::is_nothrow_move_assignable<Array>::value); -  	Value parseValue(std::istream &);  	Value parseValue(std::istream &, const std::string & encoding);  	Value parseValue(const Glib::ustring & s);  	Value parseValue(Glib::ustring::const_iterator & s);  	void serializeValue(const Value &, std::ostream & s, const std::string & encoding); -}  #pragma GCC visibility pop +}  #endif diff --git a/libjsonpp/parse.cpp b/libjsonpp/parse.cpp index 9c9a013..ec6448b 100644 --- a/libjsonpp/parse.cpp +++ b/libjsonpp/parse.cpp @@ -1,19 +1,14 @@  #include "jsonpp.h" -#include "jsonFlexLexer.h" +#include "jsonValueFlexLexer.h"  namespace json { -	ParseError::ParseError(const char * at, int l, int s) : -		std::invalid_argument(Glib::ustring::compose("Parse error at or near %1 (line %2, state %3)", at, l, s)) -	{ -	} -  	Value parseValue(std::istream & s) {  		return parseValue(s, std::string());  	}  	Value parseValue(std::istream & s, const std::string & enc) {  		Value v; -		jsonFlexLexer jfl(s, enc, v); +		jsonValueFlexLexer jfl(s, enc, v);  		while (jfl.yylex()) {}  		return v;  	} diff --git a/libjsonpp/serialize.cpp b/libjsonpp/serialize.cpp index 055d36f..cb3d203 100644 --- a/libjsonpp/serialize.cpp +++ b/libjsonpp/serialize.cpp @@ -4,9 +4,6 @@  #include <iomanip>  namespace json { -	const std::string null("null"); -	const std::string utf8("utf-8"); -  	class JsonSerialize {  		public:  			JsonSerialize(std::ostream & out, const std::string & encoding) : | 
