Pārlūkot izejas kodu

Merge branch 'master' of https://github.com/taylor001/crown

Daniele Bartolini 12 gadi atpakaļ
vecāks
revīzija
be7e6b8d7d
3 mainītis faili ar 133 papildinājumiem un 622 dzēšanām
  1. 13 0
      engine/Device.cpp
  2. 101 509
      engine/JSONParser.cpp
  3. 19 113
      engine/JSONParser.h

+ 13 - 0
engine/Device.cpp

@@ -473,6 +473,19 @@ void Device::create_lua_environment()
 	m_lua_environment->init();
 	m_lua_environment->init();
 
 
 	Log::d("Lua environment created.");
 	Log::d("Lua environment created.");
+
+
+	JSONParser json(m_allocator, "{\"asd\": 10, \"boot\":[1,2,3], \"boot2\": {\"asd\":10.0564}}");
+
+	List<char> str(default_allocator());
+
+	double num = json.root().number("asd");
+
+	Log::i("num: %f", num);
+
+	double arr = json.root().array("boot", 0).number();
+
+	Log::i("arr: %f", arr);
 }
 }
 
 
 void Device::create_console_server()
 void Device::create_console_server()

+ 101 - 509
engine/JSONParser.cpp

@@ -3,622 +3,214 @@
 #include "OS.h"
 #include "OS.h"
 #include "StringUtils.h"
 #include "StringUtils.h"
 #include "Assert.h"
 #include "Assert.h"
-#include <stdlib.h>
+#include "Log.h"
 
 
 namespace crown
 namespace crown
 {
 {
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-JSONParser::JSONParser(Allocator& allocator, File* file, size_t size) :
-	m_allocator(allocator),
-	m_file(file),
-	m_next_token(0),
-	m_prev_token(-1),
-	m_nodes_count(0)
+JSONParser::JSONParser(Allocator& allocator, const char* s) :
+	m_buffer(s),
+	m_nodes(allocator)
 {
 {
-	if (size > 1024)
-	{
-		m_tokens = CE_NEW(m_allocator, JSONToken[1024]);
-	}
-	else
-	{
-		m_tokens = m_tokens_list;
-	}
-
-	m_tokens_number = size;
-
-	parse();
-
-	m_nodes = CE_NEW(m_allocator, JSONNode[16]);
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-JSONParser::~JSONParser()
+JSONParser&	JSONParser::root()
 {
 {
-	if (m_tokens_number > 1024 && m_tokens != NULL)
-	{
-		CE_DELETE(m_allocator, m_tokens);
-	}
-	if (m_nodes != NULL)
-	{
-		CE_DELETE(m_allocator, m_nodes);
-	}
-}
+	m_nodes.clear();
 
 
-//--------------------------------------------------------------------------
-void JSONParser::parse()
-{
-	JSONToken* token;
-
-	char c;
-
-	while(!m_file->end_of_file())
-	{
-		JSONType type;
-
-		m_file->read(&c, 1);
-
-		switch(c)
-		{
-			case '{':
-			case '[':
-			{
-				token = allocate_token();
-
-				CE_ASSERT(token != NULL, "Cannot allocate a new token for parsing.\n");
+	List<JSONPair> tmp(default_allocator());
 
 
-				if (m_prev_token != -1)
-				{
-					m_tokens[m_prev_token].m_size++;
-					token->m_parent = m_prev_token;
-				}
+	JSON::parse_object(m_buffer, tmp);
 
 
-				token->m_type = c == '{' ? JSON_OBJECT : JSON_ARRAY;
-				token->m_start = m_file->position() - 1;
-				m_prev_token = m_next_token - 1;
+	JSONNode node;
 
 
-				break;
-			}
-			case '}':
-			case ']':
-			{
-				type = c == '}' ? JSON_OBJECT : JSON_ARRAY;
-
-				CE_ASSERT(m_next_token > 0, "");
-
-				token = &m_tokens[m_next_token - 1];
-
-				while (true)
-				{
-					// If token does not have a parent
-					if (token->m_parent == -1)
-					{
-						token->m_end = m_file->position();
-						break;
-					}
-					// If token is started but not finished
-					if (token->m_start != -1 && token->m_end == -1)
-					{
-						CE_ASSERT(token->m_type == type, "Token %d does not have type %d.\n", token->m_id, type);
-						
-						token->m_end = m_file->position();
-						m_prev_token = token->m_parent;
-
-						break;
-					}
-
-					token = &m_tokens[token->m_parent];
-				}
+	for (int i = 0; i < tmp.size(); i++)
+	{
+		node.type = JSON::type(tmp[i].val);
+		node.key = tmp[i].key;
+		node.val = tmp[i].val;
 
 
-				fill_token(token, type, token->m_start, token->m_end);
-				break;
-			}
-			case '\"':
-			{
-				parse_string();
-            	if (m_prev_token != -1)
-            	{
-            		m_tokens[m_prev_token].m_size++;
-            	}
-				break;
-			}
-			case ':':
-			{
-				break;
-			}
-            case '\t': 
-            case '\r': 
-            case '\n': 
-            case ',': 
-            case ' ': 
-            {
-            	break;
-            }
-            case '-':
-            case '0':
-            case '1':
-            case '2':
-            case '3':
-            case '4':
-            case '5':
-            case '6':
-            case '7':
-            case '8':
-            case '9':
-            {
-            	parse_number();
-            	if (m_prev_token != -1)
-            	{
-            		m_tokens[m_prev_token].m_size++;
-            	}
-            	break;
-            }
-            case 't':	// true
-            case 'f':	// false
-            {
-            	parse_bool();
-            	if (m_prev_token != -1)
-            	{
-            		m_tokens[m_prev_token].m_size++;
-            	}
-            	break;
-            }
-            case 'n':	// null
-            {
-            	break;
-            }
-		}
+		m_nodes.push_back(node);
 	}
 	}
 
 
-	for (int i = m_next_token - 1; i >= 0; i--)
-	{
-		if (m_tokens[i].m_start != -1 && m_tokens[i].m_end == -1)
-		{
-			CE_ASSERT(false, "There is an error in JSON syntax.");
-		}
-	}
+	return *this;
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-void JSONParser::parse_string()
+JSONParser&	JSONParser::object(const char* key)
 {
 {
-	JSONToken* token;
-
-	int start = m_file->position();
-
-	char c; 
-
-	while(!m_file->end_of_file())
-	{	
-		m_file->read(&c, 1);
-
-		if (c == '\"' || c == '\'')
-		{
-			token = allocate_token();
-
-			CE_ASSERT(token != NULL, "Cannot allocate a new token for parsing.\n");
-
-			fill_token(token, JSON_STRING, start, m_file->position() - 1);
-			token->m_parent = m_prev_token;
-
-			return;
-		}
+	bool found = false;
 
 
-		if (c == '\\')
+	for (int i = 0; i < m_nodes.size(); i++)
+	{
+		if (m_nodes[i].type == JT_OBJECT)
 		{
 		{
-			m_file->read(&c, 1);
+			List<char> str(default_allocator());
+			JSON::parse_string(m_nodes[i].key, str);
 
 
-			switch(c)
+			if (string::strcmp(key, str.begin()) == 0)
 			{
 			{
-				case '\"': 
-				case '/' : 
-				case '\\': 
-				case 'b':
-                case 'f': 
-                case 'r': 
-                case 'n': 
-                case 't':
-                case 'u':
-                {
-                	break;
-                }
-                default:
-               	{
-                	CE_ASSERT(false, "Wrong character.\n");
-                }
-			}
-		}
-	}
-}
-
-//--------------------------------------------------------------------------
-void JSONParser::parse_number()
-{
-	JSONToken* token;
-
-	int start = m_file->position() - 1;
-
-	char c;
+				List<JSONPair> obj(default_allocator());
+				JSON::parse_object(m_nodes[i].val, obj);
 
 
-	while (!m_file->end_of_file())
-	{
-		m_file->read(&c, 1);
+				m_nodes.clear();
 
 
-		switch (c)
-		{
-			case '\t': 
-			case '\r': 
-			case '\n': 
-			case ' ':
-			case ',': 
-			case '}':
-			case ']':
-			{
-				token = allocate_token();
+				JSONNode node;
 
 
-				CE_ASSERT(token != NULL, "Cannot allocate a new token for parsing.\n");
-				
-				fill_token(token, JSON_NUMBER, start, m_file->position() - 1);
+				for (int j = 0; j < obj.size(); j++)
+				{
+					node.type = JSON::type(obj[j].val);
+					node.key = obj[j].key;
+					node.val = obj[j].val;
 
 
-				token->m_parent = m_prev_token;
+					m_nodes.push_back(node);
+				}
 
 
-				m_file->seek(m_file->position() - 1);
+				found = true;
 
 
-				return;
+				break;
 			}
 			}
 		}
 		}
-
-		CE_ASSERT(c >= 32 || c < 127, "Wrong character.\n");
 	}
 	}
-}
-
-//--------------------------------------------------------------------------
-void JSONParser::parse_bool()
-{
-	JSONToken* token;
-
-	int start = m_file->position() - 1;
-
-	char c;
-
-	while (!m_file->end_of_file())
-	{
-		m_file->read(&c, 1);
-
-		switch (c)
-		{
-			case '\t': 
-			case '\r': 
-			case '\n': 
-			case ' ':
-			case ',': 
-			case '}':
-			case ']':
-			{
-				token = allocate_token();
 
 
-				CE_ASSERT(token != NULL, "Cannot allocate a new token.\n");
-				
-				fill_token(token, JSON_BOOL, start, m_file->position() - 1);
-
-				token->m_parent = m_prev_token;
-
-				m_file->seek(m_file->position() - 1);
-
-				return;
-			}
-		}
-
-		CE_ASSERT(c >= 32 || c < 127, "Wrong character.\n");
-	}	
-}
-
-//--------------------------------------------------------------------------
-JSONToken* JSONParser::allocate_token()
-{
-	JSONToken* token;
-
-	if (m_next_token >= m_tokens_number)
-	{
-		return NULL;
-	}	
-
-	int32_t id = m_next_token;
-
-	token = &m_tokens[id];
-	token->m_id = id;
-	token->m_start = -1;
-	token->m_end = -1;
-	token->m_size = 0;
-	token->m_parent = -1;
-
-	m_next_token++;
-
-	return token;
-}
-
-//--------------------------------------------------------------------------
-void JSONParser::fill_token(JSONToken* token, JSONType type, int32_t start, int32_t end)
-{
-	uint32_t cur_pos = m_file->position();
-
-	token->m_type = type;
-	token->m_start = start;
-	token->m_end = end;
-	token->m_size = token->m_end - token->m_start;
-
-	char tmp[1024];
-	m_file->seek(token->m_start);
-	m_file->read(tmp, token->m_size);
-	tmp[token->m_size] = '\0';
-	string::strncpy(token->m_value, tmp, 1024);
-
-	m_file->seek(cur_pos);
-}
-
-//--------------------------------------------------------------------------
-void JSONParser::reset_nodes()
-{
-	CE_DELETE(m_allocator, m_nodes);
-
-	m_nodes = CE_NEW(m_allocator, JSONNode[16]);
-
-	// reset nodes counter 	
-	m_nodes_count = 0;
-}
-
-//--------------------------------------------------------------------------
-JSONParser& JSONParser::get_root()
-{
-	// Check if root node is an object and if it's the first
-	CE_ASSERT(m_tokens[0].m_type == JSON_OBJECT && m_nodes_count == 0, "JSON root element '{'' must be first.\n");
-
-	m_nodes[m_nodes_count].m_id = m_tokens[0].m_id;	
-	m_nodes[m_nodes_count].m_type = JSON_OBJECT;
-
-	m_nodes_count++;
+	CE_ASSERT(found, "Object called %s not found", key);
 
 
 	return *this;
 	return *this;
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-JSONParser&	JSONParser::get_object(const char* key)
+JSONParser&	JSONParser::array(const char* key, uint32_t index)
 {
 {
 	bool found = false;
 	bool found = false;
 
 
-	int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
-	// For each token
-	for (int i = begin; i < m_next_token; i++)
+	for (int i = 0; i < m_nodes.size(); i++)
 	{
 	{
-		// Check key and type
-		if ((string::strcmp(m_tokens[i].m_value, key) == 0)	&& m_tokens[i].m_type == JSON_STRING)
+		if (m_nodes[i].type == JT_ARRAY)
 		{
 		{
-			// Check if the successive token is an array
-			CE_ASSERT(m_tokens[i+1].m_type == JSON_OBJECT, "Token %d is not an Object.\n", m_tokens[i+1].m_id);
-
-			found = true;
+			List<char> str(default_allocator());
+			JSON::parse_string(m_nodes[i].key, str);
 
 
-			// Store token's id in a json node
-			m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;	
-			m_nodes[m_nodes_count].m_type = JSON_OBJECT;
-
-			// If token stored has parent
-			if (m_tokens[i+1].has_parent())
+			if (string::strcmp(key, str.begin()) == 0)
 			{
 			{
-				// Check if precedent token stored is the parent of current token
-				CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent, "The precedent node is not parent of current.\n");
-			}
-
-			break;
-		}
-	}
-
-	CE_ASSERT(found, "Node '%s' not found!\n", key);
-
-	// Incremente nodes count for the next token
-	m_nodes_count++;
-
-	return *this;
-}
-
-//--------------------------------------------------------------------------
-JSONParser& JSONParser::get_array(const char* key, uint32_t element)
-{
-	bool found = false;
-
-	int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
-
-	element++;
-
-	// For each token
-	for (int i = begin; i < m_next_token; i++)
-	{
-		// Check key and type
-		if ((string::strcmp(m_tokens[i].m_value, key) == 0)	&& m_tokens[i].m_type == JSON_STRING)
-		{
-			// Check if the successive token is an array
-			CE_ASSERT(m_tokens[i + 1].m_type == JSON_ARRAY, "Token %d is not an Array.\n", m_tokens[i+1].m_id);
+				List<const char*> arr(default_allocator());
+				JSON::parse_array(m_nodes[i].val, arr);
 
 
-			found = true;
+				m_nodes.clear();
 
 
-			// Store array-token's id in a json node
-			m_nodes[m_nodes_count].m_id = m_tokens[i + 1].m_id;	
-			m_nodes[m_nodes_count].m_type = JSON_ARRAY;
+				JSONNode node;
 
 
-			// If token stored has parent
-			if (m_tokens[i + 1].has_parent())
-			{
-				// Check if precedent token stored is the parent of current token
-				CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i + 1].m_parent,
-					"The precedent node is not parent of current.\n");
-			}
+				node.type = JSON::type(arr[index]);
+				node.key = NULL;
+				node.val = arr[index];
 
 
-			m_nodes_count++;
+				m_nodes.push_back(node);
 
 
-			// Store element-token's id in a json node
-			m_nodes[m_nodes_count].m_id = m_tokens[i + 1 + element].m_id;	
-			m_nodes[m_nodes_count].m_type = JSON_ARRAY;
+				found = true;
 
 
-			if (m_tokens[i + 1 + element].has_parent())
-			{
-				// Check if precedent token stored is the parent of current token
-				CE_ASSERT(m_nodes[m_nodes_count-1].m_id == m_tokens[i + 1 + element].m_parent, 
-					"The precedent node is not parent of current.\n");				
+				break;
 			}
 			}
-
-			break;
 		}
 		}
 	}
 	}
 
 
-	CE_ASSERT(found, "Node '%s' not found!\n", key);
-
-	m_nodes_count++;
+	CE_ASSERT(found, "Array called %s not found", key);
 
 
 	return *this;
 	return *this;
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-JSONParser&	JSONParser::get_string(const char* key)
+const char* JSONParser::string(const char* key, List<char>& str)
 {
 {
 	bool found = false;
 	bool found = false;
 
 
-	int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
-
-	for (int i = begin; i < m_next_token; i++)
+	for (int i = 0; i < m_nodes.size(); i++)
 	{
 	{
-		if ((string::strcmp(m_tokens[i].m_value, key) == 0)	&& m_tokens[i].m_type == JSON_STRING)
+		if (JSON::type(m_nodes[i].val) == JT_STRING)
 		{
 		{
-			CE_ASSERT(m_tokens[i+1].m_type == JSON_STRING, "Token %d is not a String.\n", m_tokens[i+1].m_id);
+			List<char> tmp(default_allocator());
+			JSON::parse_string(m_nodes[i].key, tmp);
 
 
-			found = true;
+			if (string::strcmp(key, tmp.begin()) == 0)
+			{
+				JSON::parse_string(m_nodes[i].val, str);	
 
 
-			m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;	
-			m_nodes[m_nodes_count].m_type = JSON_STRING;
+				found = true;
 
 
-			if (m_tokens[i+1].has_parent())
-			{
-				CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent,
-					"The precedent node is not parent of current.\n");
+				break;
 			}
 			}
-
-			break;
 		}
 		}
 	}
 	}
 
 
-	CE_ASSERT(found, "Node '%s' not found!\n", key);
-
-	m_nodes_count++;
-
-	return *this;
+	CE_ASSERT(found, "String not found");
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::get_number(const char* key)
+double JSONParser::number(const char* key)
 {
 {
-	bool found = false;
-
-	int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
-
-	for (int i = begin; i < m_next_token; i++)
+	for (int i = 0; i < m_nodes.size(); i++)
 	{
 	{
-		if ((string::strcmp(m_tokens[i].m_value, key) == 0)	&& m_tokens[i].m_type == JSON_STRING)
+		if (JSON::type(m_nodes[i].val) == JT_NUMBER)
 		{
 		{
-			CE_ASSERT(m_tokens[i+1].m_type == JSON_NUMBER, "Token %d is not a Number.\n", m_tokens[i+1].m_id);
+			if (m_nodes[i].key == NULL)
+			{
+				return JSON::parse_number(m_nodes[i].val);	
+			}
 
 
-			found = true;
+			List<char> tmp(default_allocator());
+			JSON::parse_string(m_nodes[i].key, tmp);
 
 
-			m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;	
-			m_nodes[m_nodes_count].m_type = JSON_NUMBER;
 
 
-			if (m_tokens[i+1].has_parent())
-			{
-				CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent,
-					"The precedent node is not parent of current.\n");
+			if (string::strcmp(key, tmp.begin()) == 0)
+			{			
+				return JSON::parse_number(m_nodes[i].val);	
 			}
 			}
-
-			break;
 		}
 		}
 	}
 	}
 
 
-	CE_ASSERT(found, "Node '%s' not found!\n", key);
-
-	m_nodes_count++;
-
-	return *this;
-}
+	CE_ASSERT(found, "Number not found");
+}		
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-JSONParser& JSONParser::get_bool(const char* key)
+bool JSONParser::boolean(const char* key)
 {
 {
-	bool found = false;
-
-	int32_t begin = m_nodes_count != 0 ? m_nodes[m_nodes_count-1].m_id : 0;
-
-	for (int i = begin; i < m_next_token; i++)
+	for (int i = 0; i < m_nodes.size(); i++)
 	{
 	{
-		if ((string::strcmp(m_tokens[i].m_value, key) == 0)	&& m_tokens[i].m_type == JSON_STRING)
+		if (JSON::type(m_nodes[i].val) == JT_BOOL)
 		{
 		{
-			CE_ASSERT(m_tokens[i+1].m_type == JSON_BOOL, "Token %d is not a Boolean.\n", m_tokens[i+1].m_id);
-
-			found = true;
-
-			m_nodes[m_nodes_count].m_id = m_tokens[i+1].m_id;	
-			m_nodes[m_nodes_count].m_type = JSON_BOOL;
-
-			if (m_tokens[i+1].has_parent())
+			if (m_nodes[i].key == NULL)
 			{
 			{
-				CE_ASSERT(m_nodes_count && m_nodes[m_nodes_count-1].m_id == m_tokens[i+1].m_parent,
-					"The precedent node is not parent of current.\n");
+				return JSON::parse_bool(m_nodes[i].val);	
 			}
 			}
 
 
-			break;
+			List<char> tmp(default_allocator());
+			JSON::parse_string(m_nodes[i].key, tmp);
+
+			if (string::strcmp(key, tmp.begin()) == 0)
+			{			
+				return JSON::parse_bool(m_nodes[i].val);	
+			}
 		}
 		}
 	}
 	}
 
 
-	CE_ASSERT(found, "Node '%s' not found!\n", key);
-
-	m_nodes_count++;
-
-	return *this;
+	CE_ASSERT(found, "Boolean not found");
 }
 }
 
 
 //--------------------------------------------------------------------------
 //--------------------------------------------------------------------------
-void JSONParser::to_string(char* value)
+void JSONParser::print_nodes()
 {
 {
-	string::strncpy(value, m_tokens[m_nodes[m_nodes_count-1].m_id].m_value, JSONToken::MAX_TOKEN_LEN);
-
-	reset_nodes();
+	for (int i = 0; i < m_nodes.size(); i++)
+	{
+		Log::i("Index: %d", i);	
+		Log::i("Type : %d", m_nodes[i].type);
+		Log::i("Key  : %s", m_nodes[i].key);
+		Log::i("Val  : %s", m_nodes[i].val);
+	}
 }
 }
 
 
-//--------------------------------------------------------------------------
-void JSONParser::to_float(float& value)
-{
-	value = atof(m_tokens[m_nodes[m_nodes_count-1].m_id].m_value);
-
-	reset_nodes();
-}
 
 
-//--------------------------------------------------------------------------
-void JSONParser::to_int(int& value)
-{
-	value = atoi(m_tokens[m_nodes[m_nodes_count-1].m_id].m_value);
 
 
-	reset_nodes();
-}
 
 
-//--------------------------------------------------------------------------
-void JSONParser::to_bool(bool& value)
-{
-	if (string::strcmp(m_tokens[m_nodes[m_nodes_count-1].m_id].m_value, "true") == 0)
-	{
-		value = true;
-	}
-	else
-	{
-		value = false;
-	}
 
 
-	reset_nodes();
-}
 
 
 } //namespace crown
 } //namespace crown

+ 19 - 113
engine/JSONParser.h

@@ -2,139 +2,45 @@
 
 
 #include <cstdarg>
 #include <cstdarg>
 #include "Types.h"
 #include "Types.h"
-#include "OS.h"
-#include "File.h"
 #include "List.h"
 #include "List.h"
-#include "Allocator.h"
+#include "HeapAllocator.h"
+#include "JSON.h"
 
 
 namespace crown
 namespace crown
 {
 {
 
 
-/// JSON Token types
-enum JSONType
-{
-	JSON_OBJECT 	= 0,	// Object
-	JSON_ARRAY 		= 1,	// Array
-	JSON_STRING 	= 2,	// String
-	JSON_NUMBER		= 3,	// Number
-	JSON_BOOL 		= 4		// Boolean
-
-};
-
-/// JSONToken is a container which have pointer to a single json entity 
-/// (primitive, object, array or string) of a json file.
-struct JSONToken
-{
-	static const uint32_t MAX_TOKEN_LEN = 1024;
-
-	JSONType	m_type;					// Token's type
-	int32_t		m_id;					// Token's id
-	char 		m_value[MAX_TOKEN_LEN];	// Token's value
-	int32_t 	m_start;				// Starting byte
-	int32_t 	m_end;					// Ending byte
-	size_t 		m_size;					// Token's dimension
-	int32_t 	m_parent;				// Token's parent
-
-	inline void print()
-	{
-		os::printf("Id:\t%d\n", m_id);
-		os::printf("Value:\t%s\n", m_value);
-		os::printf("Type:\t%d\n", m_type);
-		os::printf("Start:\t%d\n", m_start);
-		os::printf("End:\t%d\n", m_end);
-		os::printf("Parent:\t%d\n", m_parent);
-		os::printf("Size:\t%d\n", m_size);
-		os::printf("\n");		
-	}
-
-	inline bool has_parent()
-	{
-		return m_parent != -1;
-	}
-};
-
-///
 struct JSONNode
 struct JSONNode
 {
 {
-	int32_t 	m_id;
-	JSONType 	m_type;
-
-	inline void print()
-	{
-		os::printf("----------------\n");
-		os::printf("Id:\t%d\n", m_id);
-		os::printf("----------------\n");
-	}
+	JSONType	type;
+	const char* key;
+	const char* val;
 };
 };
 
 
-/// JSONParser parses JSON file and stores all relative tokens.
-/// It is designed to be robust (it should work with erroneus data)
-/// and fast (data parsing on fly).
 class JSONParser
 class JSONParser
 {
 {
 public:
 public:
 	/// Constructor
 	/// Constructor
-					JSONParser(Allocator& allocator, File* file, size_t size = 1024);
-	/// Destructor
-					~JSONParser();
+							JSONParser(Allocator& allocator, const char* s);
 	/// Get root element
 	/// Get root element
-	JSONParser&		get_root();
+	JSONParser&				root();
 	/// Get object @a key
 	/// Get object @a key
-	JSONParser&		get_object(const char* key);
+	JSONParser&				object(const char* key);
 	/// Get array @a key and element @a index  
 	/// Get array @a key and element @a index  
-	JSONParser&		get_array(const char* key, uint32_t index);
-	/// Get string @a key
-	JSONParser& 	get_string(const char* key);
-	/// Get number @a key
-	JSONParser&		get_number(const char* key);		
-	/// Get boolean @a key
-	JSONParser&		get_bool(const char* key);
-	/// Convert element taken from @a get_string to string
-	void			to_string(char* value);
-	/// Convert element taken from @a get_number to float
-	void			to_float(float& value);
-	/// Convert element taken from @a get_number to int
-	void			to_int(int& value);
-	/// Convert element taken from @a get_bool to boolean
-	void			to_bool(bool& value);
+	JSONParser&				array(const char* key, uint32_t index);
+	/// Get string
+	const char* 			string(const char* key, List<char>& str);
+	/// Get number
+	double					number(const char* key = NULL);	
+	/// Get boolean
+	bool 					boolean(const char* key = NULL);
 
 
-private:
-	/// Parse JSON data and fill tokens
-	void	 		parse();
-	/// Parse string in JSON data
-	void			parse_string();
-	/// Parse boolean in JSON data
-	void			parse_bool();
-	/// Parse float in JSON data
-	void			parse_number();
-	/// Allocate token node
-	JSONToken* 		allocate_token();
-	/// Fill @a token with @a type and boundaries (@a start and @a stop)
-	void			fill_token(JSONToken* token, JSONType type, int32_t start, int32_t end);
-	/// Reset all JSON nodes
-	void			reset_nodes();
-
-	/// JSONParser allocator
-	Allocator& 		m_allocator;
-	/// JSON data
-	File*			m_file;
+	void					print_nodes();
 
 
-	/// Next token to allocate				
-	int32_t			m_next_token;
-	/// Previous token e.g parent or array		
-	int32_t			m_prev_token;
-	/// JSON tokens list, used as default
-	JSONToken		m_tokens_list[1024];
-	/// JSON tokens ptr (used only if we need more then 1024 tokens)
-	JSONToken* 		m_tokens;
-	/// m_tokens default size, default 1024
-	size_t			m_tokens_number;
+private:
 
 
-	/// DOM-like abstraction
-	JSONNode*		m_nodes;
-	/// Number of nodes in DOM-like abtraction
-	uint32_t 		m_nodes_count;
+	const char*				m_buffer;
 
 
+	List<JSONNode>			m_nodes;
 };
 };
 
 
 } // namespace crown
 } // namespace crown