Blame samples/Jzon.cpp

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
Packit 01d647
#ifdef  _WINDLL
Packit 01d647
#define JzonAPI __declspec(dllexport)
Packit 01d647
#endif
Packit 01d647
Packit 01d647
#include "Jzon.h"
Packit 01d647
Packit 01d647
#include <sstream>
Packit 01d647
#include <fstream>
Packit 01d647
#include <stack>
Packit 01d647
#include <algorithm>
Packit 01d647
Packit 01d647
namespace Jzon
Packit 01d647
{
Packit 01d647
	class FormatInterpreter
Packit 01d647
	{
Packit 01d647
	public:
Packit 01d647
		FormatInterpreter()
Packit 01d647
		{
Packit 01d647
			SetFormat(NoFormat);
Packit 01d647
		}
Packit 01d647
		FormatInterpreter(const Format &format)
Packit 01d647
		{
Packit 01d647
			SetFormat(format);
Packit 01d647
		}
Packit 01d647
Packit 01d647
		void SetFormat(const Format &format)
Packit 01d647
		{
Packit 01d647
			this->format = format;
Packit 01d647
			indentationChar = (format.useTabs ? '\t' : ' ');
Packit 01d647
			spacing = (format.spacing ? " " : "");
Packit 01d647
			newline = (format.newline ? "\n" : spacing);
Packit 01d647
		}
Packit 01d647
Packit 01d647
		std::string GetIndentation(unsigned int level) const
Packit 01d647
		{
Packit 01d647
			if (!format.newline)
Packit 01d647
			{
Packit 01d647
				return "";
Packit 01d647
			}
Packit 01d647
			else
Packit 01d647
			{
Packit 01d647
				return std::string(format.indentSize * level, indentationChar);
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
Packit 01d647
		inline const std::string &GetNewline() const
Packit 01d647
		{
Packit 01d647
			return newline;
Packit 01d647
		}
Packit 01d647
		inline const std::string &GetSpacing() const
Packit 01d647
		{
Packit 01d647
			return spacing;
Packit 01d647
		}
Packit 01d647
Packit 01d647
	private:
Packit 01d647
		Format format;
Packit 01d647
		char indentationChar;
Packit 01d647
		std::string newline;
Packit 01d647
		std::string spacing;
Packit 01d647
	};
Packit 01d647
Packit 01d647
	inline bool IsWhitespace(char c)
Packit 01d647
	{
Packit 01d647
		return (c == '\n' || c == ' ' || c == '\t' || c == '\r' || c == '\f');
Packit 01d647
	}
Packit 01d647
	inline bool IsNumber(char c)
Packit 01d647
	{
Packit 01d647
		return ((c >= '0' && c <= '9') || c == '.' || c == '-');
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node::Node()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
	Node::~Node()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Object &Node::AsObject()
Packit 01d647
	{
Packit 01d647
		if (IsObject())
Packit 01d647
			return static_cast<Object&>(*this);
Packit 01d647
		else
Packit 01d647
			throw TypeException();
Packit 01d647
	}
Packit 01d647
	const Object &Node::AsObject() const
Packit 01d647
	{
Packit 01d647
		if (IsObject())
Packit 01d647
			return static_cast<const Object&>(*this);
Packit 01d647
		else
Packit 01d647
			throw TypeException();
Packit 01d647
	}
Packit 01d647
	Array &Node::AsArray()
Packit 01d647
	{
Packit 01d647
		if (IsArray())
Packit 01d647
			return static_cast<Array&>(*this);
Packit 01d647
		else
Packit 01d647
			throw TypeException();
Packit 01d647
	}
Packit 01d647
	const Array &Node::AsArray() const
Packit 01d647
	{
Packit 01d647
		if (IsArray())
Packit 01d647
			return static_cast<const Array&>(*this);
Packit 01d647
		else
Packit 01d647
			throw TypeException();
Packit 01d647
	}
Packit 01d647
	Value &Node::AsValue()
Packit 01d647
	{
Packit 01d647
		if (IsValue())
Packit 01d647
			return static_cast<Value&>(*this);
Packit 01d647
		else
Packit 01d647
			throw TypeException();
Packit 01d647
	}
Packit 01d647
	const Value &Node::AsValue() const
Packit 01d647
	{
Packit 01d647
		if (IsValue())
Packit 01d647
			return static_cast<const Value&>(*this);
Packit 01d647
		else
Packit 01d647
			throw TypeException();
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node::Type Node::DetermineType(const std::string &json)
Packit 01d647
	{
Packit 01d647
		std::string::const_iterator jsonIt = json.begin();
Packit 01d647
Packit 01d647
		while (jsonIt != json.end() && IsWhitespace(*jsonIt))
Packit 01d647
			++jsonIt;
Packit 01d647
Packit 01d647
		if (jsonIt == json.end())
Packit 01d647
			return T_VALUE;
Packit 01d647
Packit 01d647
		switch (*jsonIt)
Packit 01d647
		{
Packit 01d647
		case '{' : return T_OBJECT;
Packit 01d647
		case '[' : return T_ARRAY;
Packit 01d647
		default  : return T_VALUE;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
Packit 01d647
Packit 01d647
	Value::Value() : Node()
Packit 01d647
	{
Packit 01d647
		SetNull();
Packit 01d647
	}
Packit 01d647
	Value::Value(const Value &rhs) : Node()
Packit 01d647
	{
Packit 01d647
		Set(rhs);
Packit 01d647
	}
Packit 01d647
	Value::Value(const Node &rhs) : Node()
Packit 01d647
	{
Packit 01d647
		const Value &value = rhs.AsValue();
Packit 01d647
		Set(value);
Packit 01d647
	}
Packit 01d647
	Value::Value(ValueType type, const std::string &value)
Packit 01d647
	{
Packit 01d647
		Set(type, value);
Packit 01d647
	}
Packit 01d647
	Value::Value(const std::string &value)
Packit 01d647
	{
Packit 01d647
		Set(value);
Packit 01d647
	}
Packit 01d647
	Value::Value(const char *value)
Packit 01d647
	{
Packit 01d647
		Set(value);
Packit 01d647
	}
Packit 01d647
	Value::Value(const int value)
Packit 01d647
	{
Packit 01d647
		Set(value);
Packit 01d647
	}
Packit 01d647
	Value::Value(const float value)
Packit 01d647
	{
Packit 01d647
		Set(value);
Packit 01d647
	}
Packit 01d647
	Value::Value(const double value)
Packit 01d647
	{
Packit 01d647
		Set(value);
Packit 01d647
	}
Packit 01d647
	Value::Value(const bool value)
Packit 01d647
	{
Packit 01d647
		Set(value);
Packit 01d647
	}
Packit 01d647
	Value::~Value()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node::Type Value::GetType() const
Packit 01d647
	{
Packit 01d647
		return T_VALUE;
Packit 01d647
	}
Packit 01d647
	Value::ValueType Value::GetValueType() const
Packit 01d647
	{
Packit 01d647
		return type;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	std::string Value::ToString() const
Packit 01d647
	{
Packit 01d647
		if (IsNull())
Packit 01d647
		{
Packit 01d647
			return "null";
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			return valueStr;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	int Value::ToInt() const
Packit 01d647
	{
Packit 01d647
		if (IsNumber())
Packit 01d647
		{
Packit 01d647
			std::stringstream sstr(valueStr);
Packit 01d647
			int val;
Packit 01d647
			sstr >> val;
Packit 01d647
			return val;
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			return 0;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	float Value::ToFloat() const
Packit 01d647
	{
Packit 01d647
		if (IsNumber())
Packit 01d647
		{
Packit 01d647
			std::stringstream sstr(valueStr);
Packit 01d647
			float val;
Packit 01d647
			sstr >> val;
Packit 01d647
			return val;
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			return 0.f;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	double Value::ToDouble() const
Packit 01d647
	{
Packit 01d647
		if (IsNumber())
Packit 01d647
		{
Packit 01d647
			std::stringstream sstr(valueStr);
Packit 01d647
			double val;
Packit 01d647
			sstr >> val;
Packit 01d647
			return val;
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			return 0.0;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	bool Value::ToBool() const
Packit 01d647
	{
Packit 01d647
		if (IsBool())
Packit 01d647
		{
Packit 01d647
			return (valueStr == "true");
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			return false;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Value::SetNull()
Packit 01d647
	{
Packit 01d647
		valueStr = "";
Packit 01d647
		type     = VT_NULL;
Packit 01d647
	}
Packit 01d647
	void Value::Set(const Value &value)
Packit 01d647
	{
Packit 01d647
		if (this != &value)
Packit 01d647
		{
Packit 01d647
			valueStr = value.valueStr;
Packit 01d647
			type     = value.type;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	void Value::Set(ValueType type, const std::string &value)
Packit 01d647
	{
Packit 01d647
		valueStr   = value;
Packit 01d647
		this->type = type;
Packit 01d647
	}
Packit 01d647
	void Value::Set(const std::string &value)
Packit 01d647
	{
Packit 01d647
		valueStr = UnescapeString(value);
Packit 01d647
		type     = VT_STRING;
Packit 01d647
	}
Packit 01d647
	void Value::Set(const char *value)
Packit 01d647
	{
Packit 01d647
		valueStr = UnescapeString(std::string(value));
Packit 01d647
		type     = VT_STRING;
Packit 01d647
	}
Packit 01d647
	void Value::Set(const int value)
Packit 01d647
	{
Packit 01d647
		std::stringstream sstr;
Packit 01d647
		sstr << value;
Packit 01d647
		valueStr = sstr.str();
Packit 01d647
		type     = VT_NUMBER;
Packit 01d647
	}
Packit 01d647
	void Value::Set(const float value)
Packit 01d647
	{
Packit 01d647
		std::stringstream sstr;
Packit 01d647
		sstr << value;
Packit 01d647
		valueStr = sstr.str();
Packit 01d647
		type     = VT_NUMBER;
Packit 01d647
	}
Packit 01d647
	void Value::Set(const double value)
Packit 01d647
	{
Packit 01d647
		std::stringstream sstr;
Packit 01d647
		sstr << value;
Packit 01d647
		valueStr = sstr.str();
Packit 01d647
		type     = VT_NUMBER;
Packit 01d647
	}
Packit 01d647
	void Value::Set(const bool value)
Packit 01d647
	{
Packit 01d647
		if (value)
Packit 01d647
			valueStr = "true";
Packit 01d647
		else
Packit 01d647
			valueStr = "false";
Packit 01d647
		type = VT_BOOL;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Value &Value::operator=(const Value &rhs)
Packit 01d647
	{
Packit 01d647
		if (this != &rhs)
Packit 01d647
			Set(rhs);
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
	Value &Value::operator=(const Node &rhs)
Packit 01d647
	{
Packit 01d647
		if (this != &rhs)
Packit 01d647
			Set(rhs.AsValue());
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
	Value &Value::operator=(const std::string &rhs)
Packit 01d647
	{
Packit 01d647
		Set(rhs);
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
	Value &Value::operator=(const char *rhs)
Packit 01d647
	{
Packit 01d647
		Set(rhs);
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
	Value &Value::operator=(const int rhs)
Packit 01d647
	{
Packit 01d647
		Set(rhs);
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
	Value &Value::operator=(const float rhs)
Packit 01d647
	{
Packit 01d647
		Set(rhs);
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
	Value &Value::operator=(const double rhs)
Packit 01d647
	{
Packit 01d647
		Set(rhs);
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
	Value &Value::operator=(const bool rhs)
Packit 01d647
	{
Packit 01d647
		Set(rhs);
Packit 01d647
		return *this;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	bool Value::operator==(const Value &other) const
Packit 01d647
	{
Packit 01d647
		return ((type == other.type)&&(valueStr == other.valueStr));
Packit 01d647
	}
Packit 01d647
	bool Value::operator!=(const Value &other) const
Packit 01d647
	{
Packit 01d647
		return !(*this == other);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node *Value::GetCopy() const
Packit 01d647
	{
Packit 01d647
		return new Value(*this);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	// This is not the most beautiful place for these, but it'll do
Packit 01d647
	static const char charsUnescaped[] = { '\\'  , '/'  , '\"'  , '\n' , '\t' , '\b' , '\f' , '\r' };
Packit 01d647
	static const char *charsEscaped[]  = { "\\\\", "\\/", "\\\"", "\\n", "\\t", "\\b", "\\f", "\\r" };
Packit 01d647
	static const unsigned int numEscapeChars = 8;
Packit 01d647
	static const char nullUnescaped = '\0';
Packit 01d647
	static const char *nullEscaped  = "\0\0";
Packit 01d647
	const char *&getEscaped(const char &c)
Packit 01d647
	{
Packit 01d647
		for (unsigned int i = 0; i < numEscapeChars; ++i)
Packit 01d647
		{
Packit 01d647
			const char &ue = charsUnescaped[i];
Packit 01d647
Packit 01d647
			if (c == ue)
Packit 01d647
			{
Packit 01d647
				const char *&e = charsEscaped[i];
Packit 01d647
				return e;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
		return nullEscaped;
Packit 01d647
	}
Packit 01d647
	const char &getUnescaped(const char &c1, const char &c2)
Packit 01d647
	{
Packit 01d647
		for (unsigned int i = 0; i < numEscapeChars; ++i)
Packit 01d647
		{
Packit 01d647
			const char *&e = charsEscaped[i];
Packit 01d647
Packit 01d647
			if (c1 == e[0] && c2 == e[1])
Packit 01d647
			{
Packit 01d647
				const char &ue = charsUnescaped[i];
Packit 01d647
				return ue;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
		return nullUnescaped;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	std::string Value::EscapeString(const std::string &value)
Packit 01d647
	{
Packit 01d647
		std::string escaped;
Packit 01d647
Packit 01d647
		for (std::string::const_iterator it = value.begin(); it != value.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const char &c = (*it);
Packit 01d647
Packit 01d647
			const char *&a = getEscaped(c);
Packit 01d647
			if (a[0] != '\0')
Packit 01d647
			{
Packit 01d647
				escaped += a[0];
Packit 01d647
				escaped += a[1];
Packit 01d647
			}
Packit 01d647
			else
Packit 01d647
			{
Packit 01d647
				escaped += c;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
Packit 01d647
		return escaped;
Packit 01d647
	}
Packit 01d647
	std::string Value::UnescapeString(const std::string &value)
Packit 01d647
	{
Packit 01d647
		std::string unescaped;
Packit 01d647
Packit 01d647
		for (std::string::const_iterator it = value.begin(); it != value.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const char &c = (*it);
Packit 01d647
			char c2 = '\0';
Packit 01d647
			if (it+1 != value.end())
Packit 01d647
				c2 = *(it+1);
Packit 01d647
Packit 01d647
			const char &a = getUnescaped(c, c2);
Packit 01d647
			if (a != '\0')
Packit 01d647
			{
Packit 01d647
				unescaped += a;
Packit 01d647
				if (it+1 != value.end())
Packit 01d647
					++it;
Packit 01d647
			}
Packit 01d647
			else
Packit 01d647
			{
Packit 01d647
				unescaped += c;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
Packit 01d647
		return unescaped;
Packit 01d647
	}
Packit 01d647
Packit 01d647
Packit 01d647
	Object::Object() : Node()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
	Object::Object(const Object &other) : Node()
Packit 01d647
	{
Packit 01d647
		for (ChildList::const_iterator it = other.children.begin(); it != other.children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const std::string &name = (*it).first;
Packit 01d647
			Node &value = *(*it).second;
Packit 01d647
Packit 01d647
			children.push_back(NamedNodePtr(name, value.GetCopy()));
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	Object::Object(const Node &other) : Node()
Packit 01d647
	{
Packit 01d647
		const Object &object = other.AsObject();
Packit 01d647
Packit 01d647
		for (ChildList::const_iterator it = object.children.begin(); it != object.children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const std::string &name = (*it).first;
Packit 01d647
			Node &value = *(*it).second;
Packit 01d647
Packit 01d647
			children.push_back(NamedNodePtr(name, value.GetCopy()));
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	Object::~Object()
Packit 01d647
	{
Packit 01d647
		Clear();
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node::Type Object::GetType() const
Packit 01d647
	{
Packit 01d647
		return T_OBJECT;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Object::Add(const std::string &name, Node &node)
Packit 01d647
	{
Packit 01d647
		children.push_back(NamedNodePtr(name, node.GetCopy()));
Packit 01d647
	}
Packit 01d647
	void Object::Add(const std::string &name, Value node)
Packit 01d647
	{
Packit 01d647
		children.push_back(NamedNodePtr(name, new Value(node)));
Packit 01d647
	}
Packit 01d647
	void Object::Remove(const std::string &name)
Packit 01d647
	{
Packit 01d647
		for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			if ((*it).first == name)
Packit 01d647
			{
Packit 01d647
				delete (*it).second;
Packit 01d647
				children.erase(it);
Packit 01d647
				break;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	void Object::Clear()
Packit 01d647
	{
Packit 01d647
		for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			delete (*it).second;
Packit 01d647
			(*it).second = NULL;
Packit 01d647
		}
Packit 01d647
		children.clear();
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Object::iterator Object::begin()
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Object::iterator(&children.front());
Packit 01d647
		else
Packit 01d647
			return Object::iterator(NULL);
Packit 01d647
	}
Packit 01d647
	Object::const_iterator Object::begin() const
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Object::const_iterator(&children.front());
Packit 01d647
		else
Packit 01d647
			return Object::const_iterator(NULL);
Packit 01d647
	}
Packit 01d647
	Object::iterator Object::end()
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Object::iterator(&children.back()+1);
Packit 01d647
		else
Packit 01d647
			return Object::iterator(NULL);
Packit 01d647
	}
Packit 01d647
	Object::const_iterator Object::end() const
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Object::const_iterator(&children.back()+1);
Packit 01d647
		else
Packit 01d647
			return Object::const_iterator(NULL);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	bool Object::Has(const std::string &name) const
Packit 01d647
	{
Packit 01d647
		for (ChildList::const_iterator it = children.begin(); it != children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			if ((*it).first == name)
Packit 01d647
			{
Packit 01d647
				return true;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
		return false;
Packit 01d647
	}
Packit 01d647
	size_t Object::GetCount() const
Packit 01d647
	{
Packit 01d647
		return children.size();
Packit 01d647
	}
Packit 01d647
	Node &Object::Get(const std::string &name) const
Packit 01d647
	{
Packit 01d647
		for (ChildList::const_iterator it = children.begin(); it != children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			if ((*it).first == name)
Packit 01d647
			{
Packit 01d647
				return *(*it).second;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
Packit 01d647
		throw NotFoundException();
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node *Object::GetCopy() const
Packit 01d647
	{
Packit 01d647
		return new Object(*this);
Packit 01d647
	}
Packit 01d647
Packit 01d647
Packit 01d647
	Array::Array() : Node()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
	Array::Array(const Array &other) : Node()
Packit 01d647
	{
Packit 01d647
		for (ChildList::const_iterator it = other.children.begin(); it != other.children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const Node &value = *(*it);
Packit 01d647
Packit 01d647
			children.push_back(value.GetCopy());
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	Array::Array(const Node &other) : Node()
Packit 01d647
	{
Packit 01d647
		const Array &array = other.AsArray();
Packit 01d647
Packit 01d647
		for (ChildList::const_iterator it = array.children.begin(); it != array.children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const Node &value = *(*it);
Packit 01d647
Packit 01d647
			children.push_back(value.GetCopy());
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	Array::~Array()
Packit 01d647
	{
Packit 01d647
		Clear();
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node::Type Array::GetType() const
Packit 01d647
	{
Packit 01d647
		return T_ARRAY;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Array::Add(Node &node)
Packit 01d647
	{
Packit 01d647
		children.push_back(node.GetCopy());
Packit 01d647
	}
Packit 01d647
	void Array::Add(Value node)
Packit 01d647
	{
Packit 01d647
		children.push_back(new Value(node));
Packit 01d647
	}
Packit 01d647
	void Array::Remove(size_t index)
Packit 01d647
	{
Packit 01d647
		if (index < children.size())
Packit 01d647
		{
Packit 01d647
			ChildList::iterator it = children.begin()+index;
Packit 01d647
			delete (*it);
Packit 01d647
			children.erase(it);
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	void Array::Clear()
Packit 01d647
	{
Packit 01d647
		for (ChildList::iterator it = children.begin(); it != children.end(); ++it)
Packit 01d647
		{
Packit 01d647
			delete (*it);
Packit 01d647
			(*it) = NULL;
Packit 01d647
		}
Packit 01d647
		children.clear();
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Array::iterator Array::begin()
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Array::iterator(&children.front());
Packit 01d647
		else
Packit 01d647
			return Array::iterator(NULL);
Packit 01d647
	}
Packit 01d647
	Array::const_iterator Array::begin() const
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Array::const_iterator(&children.front());
Packit 01d647
		else
Packit 01d647
			return Array::const_iterator(NULL);
Packit 01d647
	}
Packit 01d647
	Array::iterator Array::end()
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Array::iterator(&children.back()+1);
Packit 01d647
		else
Packit 01d647
			return Array::iterator(NULL);
Packit 01d647
	}
Packit 01d647
	Array::const_iterator Array::end() const
Packit 01d647
	{
Packit 01d647
		if (!children.empty())
Packit 01d647
			return Array::const_iterator(&children.back()+1);
Packit 01d647
		else
Packit 01d647
			return Array::const_iterator(NULL);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	size_t Array::GetCount() const
Packit 01d647
	{
Packit 01d647
		return children.size();
Packit 01d647
	}
Packit 01d647
	Node &Array::Get(size_t index) const
Packit 01d647
	{
Packit 01d647
		if (index < children.size())
Packit 01d647
		{
Packit 01d647
			return *children.at(index);
Packit 01d647
		}
Packit 01d647
Packit 01d647
		throw NotFoundException();
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node *Array::GetCopy() const
Packit 01d647
	{
Packit 01d647
		return new Array(*this);
Packit 01d647
	}
Packit 01d647
Packit 01d647
Packit 01d647
	FileWriter::FileWriter(const std::string &filename) : filename(filename)
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
	FileWriter::~FileWriter()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void FileWriter::WriteFile(const std::string &filename, const Node &root, const Format &format)
Packit 01d647
	{
Packit 01d647
		FileWriter writer(filename);
Packit 01d647
		writer.Write(root, format);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void FileWriter::Write(const Node &root, const Format &format)
Packit 01d647
	{
Packit 01d647
		Writer writer(root, format);
Packit 01d647
		writer.Write();
Packit 01d647
Packit 01d647
		std::fstream file(filename.c_str(), std::ios::out | std::ios::trunc);
Packit 01d647
		file << writer.GetResult();
Packit 01d647
		file.close();
Packit 01d647
	}
Packit 01d647
Packit 01d647
Packit 01d647
	FileReader::FileReader(const std::string &filename)
Packit 01d647
	{
Packit 01d647
		if (!loadFile(filename, json))
Packit 01d647
		{
Packit 01d647
			error = "Failed to load file";
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	FileReader::~FileReader()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
Packit 01d647
	bool FileReader::ReadFile(const std::string &filename, Node &node)
Packit 01d647
	{
Packit 01d647
		FileReader reader(filename);
Packit 01d647
		return reader.Read(node);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	bool FileReader::Read(Node &node)
Packit 01d647
	{
Packit 01d647
		if (!error.empty())
Packit 01d647
			return false;
Packit 01d647
Packit 01d647
		Parser parser(node, json);
Packit 01d647
		if (!parser.Parse())
Packit 01d647
		{
Packit 01d647
			error = parser.GetError();
Packit 01d647
			return false;
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			return true;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
Packit 01d647
	Node::Type FileReader::DetermineType()
Packit 01d647
	{
Packit 01d647
		return Node::DetermineType(json);
Packit 01d647
	}
Packit 01d647
Packit 01d647
	const std::string &FileReader::GetError() const
Packit 01d647
	{
Packit 01d647
		return error;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	bool FileReader::loadFile(const std::string &filename, std::string &json)
Packit 01d647
	{
Packit 01d647
		std::fstream file(filename.c_str(), std::ios::in | std::ios::binary);
Packit 01d647
Packit 01d647
		if (!file.is_open())
Packit 01d647
		{
Packit 01d647
			return false;
Packit 01d647
		}
Packit 01d647
Packit 01d647
		file.seekg(0, std::ios::end);
Packit 01d647
		std::ios::pos_type size = file.tellg();
Packit 01d647
		file.seekg(0, std::ios::beg);
Packit 01d647
Packit 01d647
		json.resize(static_cast<std::string::size_type>(size), '\0');
Packit 01d647
		file.read(&json[0], size);
Packit 01d647
Packit 01d647
		return true;
Packit 01d647
	}
Packit 01d647
Packit 01d647
Packit 01d647
	Writer::Writer(const Node &root, const Format &format) : fi(new FormatInterpreter), root(root)
Packit 01d647
	{
Packit 01d647
		SetFormat(format);
Packit 01d647
	}
Packit 01d647
	Writer::~Writer()
Packit 01d647
	{
Packit 01d647
		delete fi;
Packit 01d647
		fi = NULL;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Writer::SetFormat(const Format &format)
Packit 01d647
	{
Packit 01d647
		fi->SetFormat(format);
Packit 01d647
	}
Packit 01d647
	const std::string &Writer::Write()
Packit 01d647
	{
Packit 01d647
		result.clear();
Packit 01d647
		writeNode(root, 0);
Packit 01d647
		return result;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	const std::string &Writer::GetResult() const
Packit 01d647
	{
Packit 01d647
		return result;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Writer::writeNode(const Node &node, unsigned int level)
Packit 01d647
	{
Packit 01d647
		switch (node.GetType())
Packit 01d647
		{
Packit 01d647
		case Node::T_OBJECT : writeObject(node.AsObject(), level); break;
Packit 01d647
		case Node::T_ARRAY  : writeArray(node.AsArray(), level);   break;
Packit 01d647
		case Node::T_VALUE  : writeValue(node.AsValue());          break;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	void Writer::writeObject(const Object &node, unsigned int level)
Packit 01d647
	{
Packit 01d647
		result += "{" + fi->GetNewline();
Packit 01d647
Packit 01d647
		for (Object::const_iterator it = node.begin(); it != node.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const std::string &name = (*it).first;
Packit 01d647
			// const Node &value = (*it).second;
Packit 01d647
Packit 01d647
			if (it != node.begin())
Packit 01d647
				result += "," + fi->GetNewline();
Packit 01d647
			result += fi->GetIndentation(level+1) + "\""+name+"\"" + ":" + fi->GetSpacing();
Packit 01d647
			writeNode((*it).second, level+1);
Packit 01d647
		}
Packit 01d647
Packit 01d647
		result += fi->GetNewline() + fi->GetIndentation(level) + "}";
Packit 01d647
	}
Packit 01d647
	void Writer::writeArray(const Array &node, unsigned int level)
Packit 01d647
	{
Packit 01d647
		result += "[" + fi->GetNewline();
Packit 01d647
Packit 01d647
		for (Array::const_iterator it = node.begin(); it != node.end(); ++it)
Packit 01d647
		{
Packit 01d647
			const Node &value = (*it);
Packit 01d647
Packit 01d647
			if (it != node.begin())
Packit 01d647
				result += "," + fi->GetNewline();
Packit 01d647
			result += fi->GetIndentation(level+1);
Packit 01d647
			writeNode(value, level+1);
Packit 01d647
		}
Packit 01d647
Packit 01d647
		result += fi->GetNewline() + fi->GetIndentation(level) + "]";
Packit 01d647
	}
Packit 01d647
	void Writer::writeValue(const Value &node)
Packit 01d647
	{
Packit 01d647
		if (node.IsString())
Packit 01d647
		{
Packit 01d647
			result += "\""+Value::EscapeString(node.ToString())+"\"";
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			result += node.ToString();
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
Packit 01d647
Packit 01d647
	Parser::Parser(Node &root) : jsonSize(0), cursor(0), root(root)
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
	Parser::Parser(Node &root, const std::string &json) : jsonSize(0), cursor(0), root(root)
Packit 01d647
	{
Packit 01d647
		SetJson(json);
Packit 01d647
	}
Packit 01d647
	Parser::~Parser()
Packit 01d647
	{
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Parser::SetJson(const std::string &json)
Packit 01d647
	{
Packit 01d647
		this->json = json;
Packit 01d647
		jsonSize   = json.size();
Packit 01d647
	}
Packit 01d647
	bool Parser::Parse()
Packit 01d647
	{
Packit 01d647
		cursor = 0;
Packit 01d647
Packit 01d647
		tokenize();
Packit 01d647
		bool success = assemble();
Packit 01d647
Packit 01d647
		return success;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	const std::string &Parser::GetError() const
Packit 01d647
	{
Packit 01d647
		return error;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Parser::tokenize()
Packit 01d647
	{
Packit 01d647
		Token token = T_UNKNOWN;
Packit 01d647
		std::string valueBuffer;
Packit 01d647
		bool saveBuffer;
Packit 01d647
Packit 01d647
		for (; cursor < jsonSize; ++cursor)
Packit 01d647
		{
Packit 01d647
            char c = json.at(cursor);
Packit 01d647
Packit 01d647
			if (IsWhitespace(c))
Packit 01d647
				continue;
Packit 01d647
Packit 01d647
			saveBuffer = true;
Packit 01d647
Packit 01d647
			switch (c)
Packit 01d647
			{
Packit 01d647
			case '{' :
Packit 01d647
				{
Packit 01d647
					token = T_OBJ_BEGIN;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case '}' :
Packit 01d647
				{
Packit 01d647
					token = T_OBJ_END;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case '[' :
Packit 01d647
				{
Packit 01d647
					token = T_ARRAY_BEGIN;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case ']' :
Packit 01d647
				{
Packit 01d647
					token = T_ARRAY_END;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case ',' :
Packit 01d647
				{
Packit 01d647
					token = T_SEPARATOR_NODE;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case ':' :
Packit 01d647
				{
Packit 01d647
					token = T_SEPARATOR_NAME;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case '"' :
Packit 01d647
				{
Packit 01d647
					token = T_VALUE;
Packit 01d647
					readString();
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case '/' :
Packit 01d647
				{
Packit 01d647
					char p = peek();
Packit 01d647
					if (p == '*')
Packit 01d647
					{
Packit 01d647
						jumpToCommentEnd();
Packit 01d647
					}
Packit 01d647
					else if (p == '/')
Packit 01d647
					{
Packit 01d647
						jumpToNext('\n');
Packit 01d647
					}
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			default :
Packit 01d647
				{
Packit 01d647
					valueBuffer += c;
Packit 01d647
					saveBuffer = false;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			}
Packit 01d647
Packit 01d647
			if ((saveBuffer || cursor == jsonSize-1) && (!valueBuffer.empty())) // Always save buffer on the last character
Packit 01d647
			{
Packit 01d647
				if (interpretValue(valueBuffer))
Packit 01d647
				{
Packit 01d647
					tokens.push(T_VALUE);
Packit 01d647
				}
Packit 01d647
				else
Packit 01d647
				{
Packit 01d647
					// Store the unknown token, so we can show it to the user
Packit 01d647
					data.push(MakePair(Value::VT_STRING, valueBuffer));
Packit 01d647
					tokens.push(T_UNKNOWN);
Packit 01d647
				}
Packit 01d647
Packit 01d647
				valueBuffer.clear();
Packit 01d647
			}
Packit 01d647
Packit 01d647
			// Push the token last so that any
Packit 01d647
			// value token will get pushed first
Packit 01d647
			// from above.
Packit 01d647
			// If saveBuffer is false, it means that
Packit 01d647
			// we are in the middle of a value, so we
Packit 01d647
			// don't want to push any tokens now.
Packit 01d647
			if (saveBuffer)
Packit 01d647
			{
Packit 01d647
				tokens.push(token);
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	bool Parser::assemble()
Packit 01d647
	{
Packit 01d647
		std::stack<Pair<std::string, Node*> > nodeStack;
Packit 01d647
Packit 01d647
		std::string name = "";
Packit 01d647
Packit 01d647
		Token token;
Packit 01d647
		while (!tokens.empty())
Packit 01d647
		{
Packit 01d647
			token = tokens.front();
Packit 01d647
			tokens.pop();
Packit 01d647
Packit 01d647
			switch (token)
Packit 01d647
			{
Packit 01d647
			case T_UNKNOWN :
Packit 01d647
				{
Packit 01d647
					const std::string &unknownToken = data.front().second;
Packit 01d647
					error = "Unknown token: "+unknownToken;
Packit 01d647
					data.pop();
Packit 01d647
					return false;
Packit 01d647
				}
Packit 01d647
			case T_OBJ_BEGIN :
Packit 01d647
				{
Packit 01d647
					Node *node = NULL;
Packit 01d647
					if (nodeStack.empty())
Packit 01d647
					{
Packit 01d647
						if (!root.IsObject())
Packit 01d647
						{
Packit 01d647
							error = "The given root node is not an object";
Packit 01d647
							return false;
Packit 01d647
						}
Packit 01d647
Packit 01d647
						node = &roo;;
Packit 01d647
					}
Packit 01d647
					else
Packit 01d647
					{
Packit 01d647
						node = new Object;
Packit 01d647
					}
Packit 01d647
Packit 01d647
					nodeStack.push(MakePair(name, node));
Packit 01d647
					name.clear();
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case T_ARRAY_BEGIN :
Packit 01d647
				{
Packit 01d647
					Node *node = NULL;
Packit 01d647
					if (nodeStack.empty())
Packit 01d647
					{
Packit 01d647
						if (!root.IsArray())
Packit 01d647
						{
Packit 01d647
							error = "The given root node is not an array";
Packit 01d647
							return false;
Packit 01d647
						}
Packit 01d647
Packit 01d647
						node = &roo;;
Packit 01d647
					}
Packit 01d647
					else
Packit 01d647
					{
Packit 01d647
						node = new Array;
Packit 01d647
					}
Packit 01d647
Packit 01d647
					nodeStack.push(MakePair(name, node));
Packit 01d647
					name.clear();
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case T_OBJ_END :
Packit 01d647
			case T_ARRAY_END :
Packit 01d647
				{
Packit 01d647
					if (nodeStack.empty())
Packit 01d647
					{
Packit 01d647
						error = "Found end of object or array without beginning";
Packit 01d647
						return false;
Packit 01d647
					}
Packit 01d647
					if (token == T_OBJ_END && !nodeStack.top().second->IsObject())
Packit 01d647
					{
Packit 01d647
						error = "Mismatched end and beginning of object";
Packit 01d647
						return false;
Packit 01d647
					}
Packit 01d647
					if (token == T_ARRAY_END && !nodeStack.top().second->IsArray())
Packit 01d647
					{
Packit 01d647
						error = "Mismatched end and beginning of array";
Packit 01d647
						return false;
Packit 01d647
					}
Packit 01d647
Packit 01d647
					std::string name = nodeStack.top().first;
Packit 01d647
					Node *node = nodeStack.top().second;
Packit 01d647
					nodeStack.pop();
Packit 01d647
Packit 01d647
					if (!nodeStack.empty())
Packit 01d647
					{
Packit 01d647
						if (nodeStack.top().second->IsObject())
Packit 01d647
						{
Packit 01d647
							nodeStack.top().second->AsObject().Add(name, *node);
Packit 01d647
						}
Packit 01d647
						else if (nodeStack.top().second->IsArray())
Packit 01d647
						{
Packit 01d647
							nodeStack.top().second->AsArray().Add(*node);
Packit 01d647
						}
Packit 01d647
						else
Packit 01d647
						{
Packit 01d647
							error = "Can only add elements to objects and arrays";
Packit 01d647
							return false;
Packit 01d647
						}
Packit 01d647
Packit 01d647
						delete node;
Packit 01d647
						node = NULL;
Packit 01d647
					}
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case T_VALUE :
Packit 01d647
				{
Packit 01d647
					if (!tokens.empty() && tokens.front() == T_SEPARATOR_NAME)
Packit 01d647
					{
Packit 01d647
						tokens.pop();
Packit 01d647
						if (data.front().first != Value::VT_STRING)
Packit 01d647
						{
Packit 01d647
							error = "A name has to be a string";
Packit 01d647
							return false;
Packit 01d647
						}
Packit 01d647
						else
Packit 01d647
						{
Packit 01d647
							name = data.front().second;
Packit 01d647
							data.pop();
Packit 01d647
						}
Packit 01d647
					}
Packit 01d647
					else
Packit 01d647
					{
Packit 01d647
						Node *node = NULL;
Packit 01d647
						if (nodeStack.empty())
Packit 01d647
						{
Packit 01d647
							if (!root.IsValue())
Packit 01d647
							{
Packit 01d647
								error = "The given root node is not a value";
Packit 01d647
								return false;
Packit 01d647
							}
Packit 01d647
Packit 01d647
							node = &roo;;
Packit 01d647
						}
Packit 01d647
						else
Packit 01d647
						{
Packit 01d647
							node = new Value;
Packit 01d647
						}
Packit 01d647
Packit 01d647
						if (data.front().first == Value::VT_STRING)
Packit 01d647
						{
Packit 01d647
							static_cast<Value*>(node)->Set(data.front().second); // This method calls UnescapeString()
Packit 01d647
						}
Packit 01d647
						else
Packit 01d647
						{
Packit 01d647
							static_cast<Value*>(node)->Set(data.front().first, data.front().second);
Packit 01d647
						}
Packit 01d647
						data.pop();
Packit 01d647
Packit 01d647
						if (!nodeStack.empty())
Packit 01d647
						{
Packit 01d647
							if (nodeStack.top().second->IsObject())
Packit 01d647
								nodeStack.top().second->AsObject().Add(name, *node);
Packit 01d647
							else if (nodeStack.top().second->IsArray())
Packit 01d647
								nodeStack.top().second->AsArray().Add(*node);
Packit 01d647
Packit 01d647
							delete node;
Packit 01d647
							node = NULL;
Packit 01d647
							name.clear();
Packit 01d647
						}
Packit 01d647
						else
Packit 01d647
						{
Packit 01d647
							nodeStack.push(MakePair(name, node));
Packit 01d647
							name.clear();
Packit 01d647
						}
Packit 01d647
					}
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			case T_SEPARATOR_NAME :
Packit 01d647
			case T_SEPARATOR_NODE : break;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
Packit 01d647
		return true;
Packit 01d647
	}
Packit 01d647
Packit 01d647
	char Parser::peek()
Packit 01d647
	{
Packit 01d647
		if (cursor < jsonSize-1)
Packit 01d647
		{
Packit 01d647
			return json.at(cursor+1);
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			return '\0';
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
	void Parser::jumpToNext(char c)
Packit 01d647
	{
Packit 01d647
		++cursor;
Packit 01d647
		while (cursor < jsonSize && json.at(cursor) != c)
Packit 01d647
			++cursor;
Packit 01d647
	}
Packit 01d647
	void Parser::jumpToCommentEnd()
Packit 01d647
	{
Packit 01d647
		++cursor;
Packit 01d647
        char c1 = '\0';
Packit 01d647
		for (; cursor < jsonSize; ++cursor)
Packit 01d647
		{
Packit 01d647
            char c2 = json.at(cursor);
Packit 01d647
Packit 01d647
			if (c1 == '*' && c2 == '/')
Packit 01d647
				break;
Packit 01d647
Packit 01d647
			c1 = c2;
Packit 01d647
		}
Packit 01d647
	}
Packit 01d647
Packit 01d647
	void Parser::readString()
Packit 01d647
	{
Packit 01d647
		if (json.at(cursor) != '"')
Packit 01d647
			return;
Packit 01d647
Packit 01d647
		std::string str;
Packit 01d647
Packit 01d647
		++cursor;
Packit 01d647
Packit 01d647
        char c1 = '\0';
Packit 01d647
		for (; cursor < jsonSize; ++cursor)
Packit 01d647
		{
Packit 01d647
            char c2 = json.at(cursor);
Packit 01d647
Packit 01d647
			if (c1 != '\\' && c2 == '"')
Packit 01d647
			{
Packit 01d647
				break;
Packit 01d647
			}
Packit 01d647
Packit 01d647
			str += c2;
Packit 01d647
Packit 01d647
			c1 = c2;
Packit 01d647
		}
Packit 01d647
Packit 01d647
		data.push(MakePair(Value::VT_STRING, str));
Packit 01d647
	}
Packit 01d647
	bool Parser::interpretValue(const std::string &value)
Packit 01d647
	{
Packit 01d647
		std::string upperValue(value.size(), '\0');
Packit 01d647
Packit 01d647
		std::transform(value.begin(), value.end(), upperValue.begin(), toupper);
Packit 01d647
Packit 01d647
		if (upperValue == "NULL")
Packit 01d647
		{
Packit 01d647
			data.push(MakePair(Value::VT_NULL, std::string("")));
Packit 01d647
		}
Packit 01d647
		else if (upperValue == "TRUE")
Packit 01d647
		{
Packit 01d647
			data.push(MakePair(Value::VT_BOOL, std::string("true")));
Packit 01d647
		}
Packit 01d647
		else if (upperValue == "FALSE")
Packit 01d647
		{
Packit 01d647
			data.push(MakePair(Value::VT_BOOL, std::string("false")));
Packit 01d647
		}
Packit 01d647
		else
Packit 01d647
		{
Packit 01d647
			bool number = true;
Packit 01d647
			for (std::string::const_iterator it = value.begin(); it != value.end(); ++it)
Packit 01d647
			{
Packit 01d647
				if (!IsNumber(*it))
Packit 01d647
				{
Packit 01d647
					number = false;
Packit 01d647
					break;
Packit 01d647
				}
Packit 01d647
			}
Packit 01d647
Packit 01d647
			if (number)
Packit 01d647
			{
Packit 01d647
				data.push(MakePair(Value::VT_NUMBER, value));
Packit 01d647
			}
Packit 01d647
			else
Packit 01d647
			{
Packit 01d647
				return false;
Packit 01d647
			}
Packit 01d647
		}
Packit 01d647
Packit 01d647
		return true;
Packit 01d647
	}
Packit 01d647
}