Blame samples/Jzon.h

Packit 01d647
/*
Packit 01d647
Copyright (c) 2013 Johannes Häggqvist
Packit 01d647
Packit 01d647
Permission is hereby granted, free of charge, to any person obtaining a copy
Packit 01d647
of this software and associated documentation files (the "Software"), to deal
Packit 01d647
in the Software without restriction, including without limitation the rights
Packit 01d647
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
Packit 01d647
copies of the Software, and to permit persons to whom the Software is
Packit 01d647
furnished to do so, subject to the following conditions:
Packit 01d647
Packit 01d647
The above copyright notice and this permission notice shall be included in
Packit 01d647
all copies or substantial portions of the Software.
Packit 01d647
Packit 01d647
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit 01d647
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit 01d647
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Packit 01d647
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Packit 01d647
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
Packit 01d647
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
Packit 01d647
THE SOFTWARE.
Packit 01d647
*/
Packit 01d647
#ifndef Jzon_h__
Packit 01d647
#define Jzon_h__
Packit 01d647
Packit 01d647
#ifndef   JzonAPI
Packit 01d647
# ifdef   _WINDLL
Packit 01d647
#  define JzonAPI __declspec(dllimport)
Packit 01d647
# elif defined(__GNUC__) && (__GNUC__ >= 4)
Packit 01d647
#  define JzonAPI __attribute__ ((visibility("default")))
Packit 01d647
# else
Packit 01d647
#  define JzonAPI
Packit 01d647
# endif
Packit 01d647
#endif
Packit 01d647
Packit 01d647
#include <string>
Packit 01d647
#include <vector>
Packit 01d647
#include <queue>
Packit 01d647
#include <iterator>
Packit 01d647
#include <stdexcept>
Packit 01d647
Packit 01d647
namespace Jzon
Packit 01d647
{
Packit 01d647
    #ifdef _MSC_VER
Packit 01d647
	# pragma warning(disable : 4251)
Packit 01d647
	#endif
Packit 01d647
	
Packit 01d647
	template<typename T1, typename T2>
Packit 01d647
	struct Pair
Packit 01d647
	{
Packit 01d647
		Pair(T1 first, T2 second) : first(first), second(second)
Packit 01d647
		{}
Packit 01d647
Packit 01d647
		Pair &operator=(const Pair &rhs)
Packit 01d647
		{
Packit 01d647
			if (this != &rhs)
Packit 01d647
			{
Packit 01d647
				this->first  = rhs.first;
Packit 01d647
				this->second = rhs.second;
Packit 01d647
			}
Packit 01d647
			return *this;
Packit 01d647
		}
Packit 01d647
Packit 01d647
		T1 first;
Packit 01d647
		T2 second;
Packit 01d647
	};
Packit 01d647
	template<typename T1, typename T2>
Packit 01d647
	static Pair<T1, T2> MakePair(T1 first, T2 second)
Packit 01d647
	{
Packit 01d647
		return Pair<T1, T2>(first, second);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	class Node;
Packit 01d647
	class Value;
Packit 01d647
	class Object;
Packit 01d647
	class Array;
Packit 01d647
	typedef Pair<std::string, Node&> NamedNode;
Packit 01d647
	typedef Pair<std::string, Node*> NamedNodePtr;
Packit 01d647
Packit 01d647
	class TypeException : public std::logic_error
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		TypeException() : std::logic_error("A Node was used as the wrong type")
Packit 01d647
		{}
Packit 01d647
	};
Packit 01d647
	class NotFoundException : public std::out_of_range
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		NotFoundException() : std::out_of_range("The node could not be found")
Packit 01d647
		{}
Packit 01d647
	};
Packit 01d647
Packit 01d647
	struct Format
Packit 01d647
	{
Packit 01d647
		bool newline;
Packit 01d647
		bool spacing;
Packit 01d647
		bool useTabs;
Packit 01d647
		unsigned int indentSize;
Packit 01d647
	};
Packit 01d647
	static const Format StandardFormat = { true, true, true, 1 };
Packit 01d647
	static const Format NoFormat = { false, false, false, 0 };
Packit 01d647
Packit 01d647
	class JzonAPI Node
Packit 01d647
	{
Packit 01d647
		friend class Object;
Packit 01d647
		friend class Array;
Packit 01d647
Packit 01d647
	public:
Packit 01d647
		enum Type
Packit 01d647
		{
Packit 01d647
			T_OBJECT,
Packit 01d647
			T_ARRAY,
Packit 01d647
			T_VALUE
Packit 01d647
		};
Packit 01d647
Packit 01d647
		Node();
Packit 01d647
		virtual ~Node();
Packit 01d647
Packit 01d647
		virtual Type GetType() const = 0;
Packit 01d647
Packit 01d647
		inline bool IsObject() const { return (GetType() == T_OBJECT); }
Packit 01d647
		inline bool IsArray() const { return (GetType() == T_ARRAY); }
Packit 01d647
		inline bool IsValue() const { return (GetType() == T_VALUE); }
Packit 01d647
Packit 01d647
		Object &AsObject();
Packit 01d647
		const Object &AsObject() const;
Packit 01d647
		Array &AsArray();
Packit 01d647
		const Array &AsArray() const;
Packit 01d647
		Value &AsValue();
Packit 01d647
		const Value &AsValue() const;
Packit 01d647
Packit 01d647
		virtual inline bool IsNull() const { return false; }
Packit 01d647
		virtual inline bool IsString() const { return false; }
Packit 01d647
		virtual inline bool IsNumber() const { return false; }
Packit 01d647
		virtual inline bool IsBool() const { return false; }
Packit 01d647
Packit 01d647
		virtual std::string ToString() const { throw TypeException(); }
Packit 01d647
		virtual int ToInt() const { throw TypeException(); }
Packit 01d647
		virtual float ToFloat() const { throw TypeException(); }
Packit 01d647
		virtual double ToDouble() const { throw TypeException(); }
Packit 01d647
		virtual bool ToBool() const { throw TypeException(); }
Packit 01d647
Packit 01d647
		virtual bool Has(const std::string &/*name*/) const { throw TypeException(); }
Packit 01d647
		virtual size_t GetCount() const { return 0; }
Packit 01d647
		virtual Node &Get(const std::string &/*name*/) const { throw TypeException(); }
Packit 01d647
		virtual Node &Get(size_t /*index*/) const { throw TypeException(); }
Packit 01d647
Packit 01d647
		static Type DetermineType(const std::string &json);
Packit 01d647
Packit 01d647
	protected:
Packit 01d647
		virtual Node *GetCopy() const = 0;
Packit 01d647
	};
Packit 01d647
Packit 01d647
	class JzonAPI Value : public Node
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		enum ValueType
Packit 01d647
		{
Packit 01d647
			VT_NULL,
Packit 01d647
			VT_STRING,
Packit 01d647
			VT_NUMBER,
Packit 01d647
			VT_BOOL
Packit 01d647
		};
Packit 01d647
Packit 01d647
		Value();
Packit 01d647
		Value(const Value &rhs;;
Packit 01d647
		Value(const Node &rhs;;
Packit 01d647
		Value(ValueType type, const std::string &value);
Packit 01d647
		Value(const std::string &value);
Packit 01d647
		Value(const char *value);
Packit 01d647
		Value(const int value);
Packit 01d647
		Value(const float value);
Packit 01d647
		Value(const double value);
Packit 01d647
		Value(const bool value);
Packit 01d647
		virtual ~Value();
Packit 01d647
Packit 01d647
		virtual Type GetType() const;
Packit 01d647
		ValueType GetValueType() const;
Packit 01d647
Packit 01d647
		virtual inline bool IsNull() const { return (type == VT_NULL); }
Packit 01d647
		virtual inline bool IsString() const { return (type == VT_STRING); }
Packit 01d647
		virtual inline bool IsNumber() const { return (type == VT_NUMBER); }
Packit 01d647
		virtual inline bool IsBool() const { return (type == VT_BOOL); }
Packit 01d647
Packit 01d647
		virtual std::string ToString() const;
Packit 01d647
		virtual int ToInt() const;
Packit 01d647
		virtual float ToFloat() const;
Packit 01d647
		virtual double ToDouble() const;
Packit 01d647
		virtual bool ToBool() const;
Packit 01d647
Packit 01d647
		void SetNull();
Packit 01d647
		void Set(const Value &value);
Packit 01d647
		void Set(ValueType type, const std::string &value);
Packit 01d647
		void Set(const std::string &value);
Packit 01d647
		void Set(const char *value);
Packit 01d647
		void Set(const int value);
Packit 01d647
		void Set(const float value);
Packit 01d647
		void Set(const double value);
Packit 01d647
		void Set(const bool value);
Packit 01d647
Packit 01d647
		Value &operator=(const Value &rhs;;
Packit 01d647
		Value &operator=(const Node &rhs;;
Packit 01d647
		Value &operator=(const std::string &rhs;;
Packit 01d647
		Value &operator=(const char *rhs);
Packit 01d647
		Value &operator=(const int rhs);
Packit 01d647
		Value &operator=(const float rhs);
Packit 01d647
		Value &operator=(const double rhs);
Packit 01d647
		Value &operator=(const bool rhs);
Packit 01d647
Packit 01d647
		bool operator==(const Value &other) const;
Packit 01d647
		bool operator!=(const Value &other) const;
Packit 01d647
Packit 01d647
		static std::string EscapeString(const std::string &value);
Packit 01d647
		static std::string UnescapeString(const std::string &value);
Packit 01d647
Packit 01d647
	protected:
Packit 01d647
		virtual Node *GetCopy() const;
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		std::string valueStr;
Packit 01d647
		ValueType type;
Packit 01d647
	};
Packit 01d647
Packit 01d647
	static const Value null;
Packit 01d647
Packit 01d647
	class JzonAPI Object : public Node
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		class iterator : public std::iterator<std::input_iterator_tag, NamedNode>
Packit 01d647
		{
Packit 01d647
		public:
Packit 01d647
			iterator(NamedNodePtr *o) : p(o) {}
Packit 01d647
			iterator(const iterator &it) : p(it.p) {}
Packit 01d647
Packit 01d647
			iterator &operator++() { ++p; return *this; }
Packit 01d647
			iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
Packit 01d647
Packit 01d647
			bool operator==(const iterator &rhs) { return p == rhs.p; }
Packit 01d647
			bool operator!=(const iterator &rhs) { return p != rhs.p; }
Packit 01d647
Packit 01d647
			NamedNode operator*() { return NamedNode(p->first, *p->second); }
Packit 01d647
Packit 01d647
		private:
Packit 01d647
			NamedNodePtr *p;
Packit 01d647
		};
Packit 01d647
		class const_iterator : public std::iterator<std::input_iterator_tag, const NamedNode>
Packit 01d647
		{
Packit 01d647
		public:
Packit 01d647
			const_iterator(const NamedNodePtr *o) : p(o) {}
Packit 01d647
			const_iterator(const const_iterator &it) : p(it.p) {}
Packit 01d647
Packit 01d647
			const_iterator &operator++() { ++p; return *this; }
Packit 01d647
			const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
Packit 01d647
Packit 01d647
			bool operator==(const const_iterator &rhs) { return p == rhs.p; }
Packit 01d647
			bool operator!=(const const_iterator &rhs) { return p != rhs.p; }
Packit 01d647
Packit 01d647
			const NamedNode operator*() { return NamedNode(p->first, *p->second); }
Packit 01d647
Packit 01d647
		private:
Packit 01d647
			const NamedNodePtr *p;
Packit 01d647
		};
Packit 01d647
Packit 01d647
		Object();
Packit 01d647
		Object(const Object &other);
Packit 01d647
		Object(const Node &other);
Packit 01d647
		virtual ~Object();
Packit 01d647
Packit 01d647
		virtual Type GetType() const;
Packit 01d647
Packit 01d647
		void Add(const std::string &name, Node &node);
Packit 01d647
		void Add(const std::string &name, Value node);
Packit 01d647
		void Remove(const std::string &name);
Packit 01d647
		void Clear();
Packit 01d647
Packit 01d647
		iterator begin();
Packit 01d647
		const_iterator begin() const;
Packit 01d647
		iterator end();
Packit 01d647
		const_iterator end() const;
Packit 01d647
Packit 01d647
		virtual bool Has(const std::string &name) const;
Packit 01d647
		virtual size_t GetCount() const;
Packit 01d647
		virtual Node &Get(const std::string &name) const;
Packit 01d647
		using Node::Get;
Packit 01d647
Packit 01d647
	protected:
Packit 01d647
		virtual Node *GetCopy() const;
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		typedef std::vector<NamedNodePtr> ChildList;
Packit 01d647
		ChildList children;
Packit 01d647
	};
Packit 01d647
Packit 01d647
	class JzonAPI Array : public Node
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		class iterator : public std::iterator<std::input_iterator_tag, Node>
Packit 01d647
		{
Packit 01d647
		public:
Packit 01d647
			iterator(Node **o) : p(o) {}
Packit 01d647
			iterator(const iterator &it) : p(it.p) {}
Packit 01d647
Packit 01d647
			iterator &operator++() { ++p; return *this; }
Packit 01d647
			iterator operator++(int) { iterator tmp(*this); operator++(); return tmp; }
Packit 01d647
Packit 01d647
			bool operator==(const iterator &rhs) { return p == rhs.p; }
Packit 01d647
			bool operator!=(const iterator &rhs) { return p != rhs.p; }
Packit 01d647
Packit 01d647
			Node &operator*() { return **p; }
Packit 01d647
Packit 01d647
		private:
Packit 01d647
			Node **p;
Packit 01d647
		};
Packit 01d647
		class const_iterator : public std::iterator<std::input_iterator_tag, const Node>
Packit 01d647
		{
Packit 01d647
		public:
Packit 01d647
			const_iterator(const Node *const *o) : p(o) {}
Packit 01d647
			const_iterator(const const_iterator &it) : p(it.p) {}
Packit 01d647
Packit 01d647
			const_iterator &operator++() { ++p; return *this; }
Packit 01d647
			const_iterator operator++(int) { const_iterator tmp(*this); operator++(); return tmp; }
Packit 01d647
Packit 01d647
			bool operator==(const const_iterator &rhs) { return p == rhs.p; }
Packit 01d647
			bool operator!=(const const_iterator &rhs) { return p != rhs.p; }
Packit 01d647
Packit 01d647
			const Node &operator*() { return **p; }
Packit 01d647
Packit 01d647
		private:
Packit 01d647
			const Node *const *p;
Packit 01d647
		};
Packit 01d647
Packit 01d647
		Array();
Packit 01d647
		Array(const Array &other);
Packit 01d647
		Array(const Node &other);
Packit 01d647
		virtual ~Array();
Packit 01d647
Packit 01d647
		virtual Type GetType() const;
Packit 01d647
Packit 01d647
		void Add(Node &node);
Packit 01d647
		void Add(Value node);
Packit 01d647
		void Remove(size_t index);
Packit 01d647
		void Clear();
Packit 01d647
Packit 01d647
		iterator begin();
Packit 01d647
		const_iterator begin() const;
Packit 01d647
		iterator end();
Packit 01d647
		const_iterator end() const;
Packit 01d647
Packit 01d647
		virtual size_t GetCount() const;
Packit 01d647
		virtual Node &Get(size_t index) const;
Packit 01d647
		using Node::Get;
Packit 01d647
Packit 01d647
	protected:
Packit 01d647
		virtual Node *GetCopy() const;
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		typedef std::vector<Node*> ChildList;
Packit 01d647
		ChildList children;
Packit 01d647
	};
Packit 01d647
Packit 01d647
	class JzonAPI FileWriter
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		FileWriter(const std::string &filename);
Packit 01d647
		~FileWriter();
Packit 01d647
Packit 01d647
		static void WriteFile(const std::string &filename, const Node &root, const Format &format = NoFormat);
Packit 01d647
Packit 01d647
		void Write(const Node &root, const Format &format = NoFormat);
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		std::string filename;
Packit 01d647
	};
Packit 01d647
Packit 01d647
	class JzonAPI FileReader
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		FileReader(const std::string &filename);
Packit 01d647
		~FileReader();
Packit 01d647
Packit 01d647
		static bool ReadFile(const std::string &filename, Node &node);
Packit 01d647
Packit 01d647
		bool Read(Node &node);
Packit 01d647
Packit 01d647
		Node::Type DetermineType();
Packit 01d647
Packit 01d647
		const std::string &GetError() const;
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		bool loadFile(const std::string &filename, std::string &json);
Packit 01d647
		std::string json;
Packit 01d647
		std::string error;
Packit 01d647
	};
Packit 01d647
Packit 01d647
	class JzonAPI Writer
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		Writer(const Node &root, const Format &format = NoFormat);
Packit 01d647
		~Writer();
Packit 01d647
Packit 01d647
		void SetFormat(const Format &format);
Packit 01d647
		const std::string &Write();
Packit 01d647
Packit 01d647
		// Return result from last call to Write()
Packit 01d647
		const std::string &GetResult() const;
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		void writeNode(const Node &node, unsigned int level);
Packit 01d647
		void writeObject(const Object &node, unsigned int level);
Packit 01d647
		void writeArray(const Array &node, unsigned int level);
Packit 01d647
		void writeValue(const Value &node);
Packit 01d647
Packit 01d647
		std::string result;
Packit 01d647
Packit 01d647
		class FormatInterpreter *fi;
Packit 01d647
Packit 01d647
		const Node &roo;;
Packit 01d647
Packit 01d647
		// Disable assignment operator
Packit 01d647
		Writer &operator=(const Writer&);
Packit 01d647
	};
Packit 01d647
Packit 01d647
	class JzonAPI Parser
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		Parser(Node &root);
Packit 01d647
		Parser(Node &root, const std::string &json);
Packit 01d647
		~Parser();
Packit 01d647
Packit 01d647
		void SetJson(const std::string &json);
Packit 01d647
		bool Parse();
Packit 01d647
Packit 01d647
		const std::string &GetError() const;
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		enum Token
Packit 01d647
		{
Packit 01d647
			T_UNKNOWN,
Packit 01d647
			T_OBJ_BEGIN,
Packit 01d647
			T_OBJ_END,
Packit 01d647
			T_ARRAY_BEGIN,
Packit 01d647
			T_ARRAY_END,
Packit 01d647
			T_SEPARATOR_NODE,
Packit 01d647
			T_SEPARATOR_NAME,
Packit 01d647
			T_VALUE
Packit 01d647
		};
Packit 01d647
Packit 01d647
		void tokenize();
Packit 01d647
		bool assemble();
Packit 01d647
Packit 01d647
		char peek();
Packit 01d647
		void jumpToNext(char c);
Packit 01d647
		void jumpToCommentEnd();
Packit 01d647
Packit 01d647
		void readString();
Packit 01d647
		bool interpretValue(const std::string &value);
Packit 01d647
Packit 01d647
		std::string json;
Packit 01d647
		std::size_t jsonSize;
Packit 01d647
Packit 01d647
		std::queue<Token> tokens;
Packit 01d647
		std::queue<Pair<Value::ValueType, std::string> > data;
Packit 01d647
Packit 01d647
		std::size_t cursor;
Packit 01d647
Packit 01d647
		Node &roo;;
Packit 01d647
Packit 01d647
		std::string error;
Packit 01d647
Packit 01d647
		// Disable assignment operator
Packit 01d647
		Parser &operator=(const Parser&);
Packit 01d647
	};
Packit 01d647
}
Packit 01d647
Packit 01d647
#endif // Jzon_h__