Jelajahi Sumber

Add JSONElement, an helper class to parse JSON documents

Daniele Bartolini 12 tahun lalu
induk
melakukan
4a2255bfc9
2 mengubah file dengan 83 tambahan dan 47 penghapusan
  1. 33 22
      engine/core/json/JSONParser.cpp
  2. 50 25
      engine/core/json/JSONParser.h

+ 33 - 22
engine/core/json/JSONParser.cpp

@@ -194,23 +194,21 @@ static bool is_escapee(char c)
 }
 
 //--------------------------------------------------------------------------
-JSONParser::JSONParser(const char* s) :
-	m_document(s),
-	m_at(s)
+JSONElement::JSONElement() :
+	m_parser(NULL),
+	m_at(NULL)
 {
-	CE_ASSERT_NOT_NULL(s);
 }
 
 //--------------------------------------------------------------------------
-JSONParser&	JSONParser::root()
+JSONElement::JSONElement(JSONParser& parser, const char* at) :
+	m_parser(&parser),
+	m_at(at)
 {
-	m_at = skip_whites(m_document);
-
-	return *this;
 }
 
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::operator[](uint32_t i)
+JSONElement& JSONElement::operator[](uint32_t i)
 {
 	TempAllocator1024 alloc;
 	List<const char*> array(alloc);
@@ -225,13 +223,13 @@ JSONParser& JSONParser::operator[](uint32_t i)
 }
 
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::index(uint32_t i)
+JSONElement& JSONElement::index(uint32_t i)
 {
 	return this->operator[](i);
 }
 
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::key(const char* k)
+JSONElement& JSONElement::key(const char* k)
 {
 	TempAllocator1024 alloc;
 	List<JSONPair> object(alloc);
@@ -260,25 +258,25 @@ JSONParser& JSONParser::key(const char* k)
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::bool_value() const
+bool JSONElement::bool_value() const
 {
 	return JSONParser::parse_bool(m_at);
 }
 
 //--------------------------------------------------------------------------
-int32_t JSONParser::int_value() const
+int32_t JSONElement::int_value() const
 {
 	return JSONParser::parse_int(m_at);
 }
 
 //--------------------------------------------------------------------------
-float JSONParser::float_value() const
+float JSONElement::float_value() const
 {
 	return JSONParser::parse_float(m_at);
 }
 
 //--------------------------------------------------------------------------
-const char* JSONParser::string_value() const
+const char* JSONElement::string_value() const
 {
 	static TempAllocator1024 alloc;
 	static List<char> string(alloc);
@@ -291,43 +289,43 @@ const char* JSONParser::string_value() const
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_nil() const
+bool JSONElement::is_nil() const
 {
 	return JSONParser::type(m_at) == JT_NIL;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_bool() const
+bool JSONElement::is_bool() const
 {
 	return JSONParser::type(m_at) == JT_BOOL;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_number() const
+bool JSONElement::is_number() const
 {
 	return JSONParser::type(m_at) == JT_NUMBER;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_string() const
+bool JSONElement::is_string() const
 {
 	return JSONParser::type(m_at) == JT_STRING;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_array() const
+bool JSONElement::is_array() const
 {
 	return JSONParser::type(m_at) == JT_ARRAY;
 }
 
 //--------------------------------------------------------------------------
-bool JSONParser::is_object() const
+bool JSONElement::is_object() const
 {
 	return JSONParser::type(m_at) == JT_OBJECT;
 }
 
 //--------------------------------------------------------------------------
-uint32_t JSONParser::size() const
+uint32_t JSONElement::size() const
 {
 	switch(JSONParser::type(m_at))
 	{
@@ -374,6 +372,19 @@ uint32_t JSONParser::size() const
 	}
 }
 
+//--------------------------------------------------------------------------
+JSONParser::JSONParser(const char* s) :
+	m_document(s)
+{
+	CE_ASSERT_NOT_NULL(s);
+}
+
+//--------------------------------------------------------------------------
+JSONElement JSONParser::root()
+{
+	return JSONElement(*this, skip_whites(m_document));
+}
+
 //-----------------------------------------------------------------------------
 JSONType JSONParser::type(const char* s)
 {

+ 50 - 25
engine/core/json/JSONParser.h

@@ -42,58 +42,60 @@ enum JSONType
 	JT_BOOL
 };
 
+/// Represents a pair
 struct JSONPair
 {
 	const char* key;
 	const char* val;
 };
 
-/// Parses JSON documents.
-class JSONParser
+class JSONParser;
+
+/// Represents a JSON element.
+/// The objects of this class are valid until the parser
+/// which has generated them, will exist.
+class JSONElement
 {
 public:
 
-	/// Read the JSON document contained in the non-null @a s string.
-	/// @note
-	/// The @a s string has to remain valid for the whole parser's
-	/// existence scope.
-						JSONParser(const char* s);
-
-	/// Returns the root element of the JSON document.
-	JSONParser&			root();
+	/// Used only to forward-instantiate elements.
+	/// In order to be able to use the element, it must be
+	/// obtained from JSONParser::root() or copied from an
+	/// already existent and valid element.
+						JSONElement();
 
 	/// Returns the @a i -th item of the current array.
-	JSONParser&			operator[](uint32_t i);
+	JSONElement&		operator[](uint32_t i);
 
 	/// @copydoc JSONParser::operator[]
-	JSONParser&			index(uint32_t i);
+	JSONElement&		index(uint32_t i);
 
 	/// Returns the element corresponding to key @a k of the
 	/// current object.
 	/// @note
 	/// If the key is not unique in the object scope, the last
 	/// key in order of appearance will be selected.
-	JSONParser&			key(const char* k);
+	JSONElement&		key(const char* k);
 
-	/// Returns true wheter the current element is the JSON nil special value.
+	/// Returns true wheter the element is the JSON nil special value.
 	bool				is_nil() const;
 
-	/// Returns true wheter the current element is a JSON boolean (true or false).
+	/// Returns true wheter the element is a JSON boolean (true or false).
 	bool				is_bool() const;
 
-	/// Returns true wheter the current element is a JSON number.
+	/// Returns true wheter the element is a JSON number.
 	bool				is_number() const;
 
-	/// Returns true whether the current element is a JSON string.
+	/// Returns true whether the element is a JSON string.
 	bool				is_string() const;
 
-	/// Returns true whether the current element is a JSON array.
+	/// Returns true whether the element is a JSON array.
 	bool				is_array() const;
 
-	/// Returns true whether the current element is a JSON object.
+	/// Returns true whether the element is a JSON object.
 	bool				is_object() const;
 
-	/// Returns the size of the current element based on the
+	/// Returns the size of the element based on the
 	/// element's type:
 	/// * nil, bool, number: 1
 	/// * string: length of the string
@@ -101,22 +103,46 @@ public:
 	/// * object: number of keys in the object
 	uint32_t			size() const;
 
-	/// Returns the boolean value of the current element.
+	/// Returns the boolean value of the element.
 	bool				bool_value() const;
 
-	/// Returns the integer value of the current element.
+	/// Returns the integer value of the element.
 	int32_t				int_value() const;
 
-	/// Returns the float value of the current element.
+	/// Returns the float value of the element.
 	float				float_value() const;
 
-	/// Returns the string value of the current element.
+	/// Returns the string value of the element.
 	/// @warning
 	/// The returned string is kept internally until the next call to
 	/// this function, so it is highly unsafe to just keep the pointer
 	/// instead of copying its content somewhere else.
 	const char*			string_value() const;
 
+private:
+
+						JSONElement(JSONParser& parser, const char* at);
+
+	JSONParser*			m_parser;
+	const char*			m_at;
+
+	friend class 		JSONParser;
+};
+
+/// Parses JSON documents.
+class JSONParser
+{
+public:
+
+	/// Read the JSON document contained in the non-null @a s string.
+	/// @note
+	/// The @a s string has to remain valid for the whole parser's
+	/// existence scope.
+						JSONParser(const char* s);
+
+	/// Returns the root element of the JSON document.
+	JSONElement			root();
+
 public:
 
 	/// Returns the type of the @a s JSON text. 
@@ -148,7 +174,6 @@ public:
 private:
 
 	const char* const	m_document;
-	const char*			m_at;
 
 private: