Просмотр исходного кода

JSONParser implemented, testing

mikymod 13 лет назад
Родитель
Сommit
ad10fe3cb7

+ 1 - 1
android/build.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project name="test" default="help">
+<project name="Crown" default="help">
 
     <!-- The local.properties file is created and updated by the 'android' tool.
          It contains the path to the SDK. It should *NOT* be checked into

+ 10 - 0
android/local.properties

@@ -0,0 +1,10 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+
+# location of the SDK. This is only used by Ant
+# For customization when using a Version Control System, please read the
+# header note.
+sdk.dir=/opt/android-sdk

+ 1 - 1
android/project.properties

@@ -11,4 +11,4 @@
 #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
 
 # Project target.
-target=android-16
+target=Google Inc.:Google APIs:17

+ 4 - 0
samples/CMakeLists.txt

@@ -37,6 +37,7 @@ add_executable(chain ${CHAINSAWBUFFET_SRC})
 add_executable(fs filesystem/filesystem.cpp)
 add_executable(textrenderer textrenderer/textrenderer.cpp)
 add_executable(collision collision/collision.cpp)
+add_executable(json json/json.cpp)
 
 target_link_libraries(terrain crown)
 target_link_libraries(texturing crown)
@@ -45,3 +46,6 @@ target_link_libraries(chain crown)
 target_link_libraries(fs crown)
 target_link_libraries(textrenderer crown)
 target_link_libraries(collision crown)
+target_link_libraries(json crown)
+
+

+ 26 - 0
samples/json/json.cpp

@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "JSONParser.h"
+
+using namespace crown;
+
+int main(int argc, char** argv)
+{
+	const char* src = "'test' : {string' : 'dio', 'number' : 33}";
+
+	JSONParser* parser = new JSONParser();
+	json_error error;
+	JSONToken* tokens;
+
+	parser->init();
+	error = parser->parse(src);
+	tokens = parser->get_tokens();
+
+	for (int i = 0; i < parser->get_tokens_number(); i++)
+	{
+		tokens[i].print();
+	}
+
+	printf("return: %d\n", error);
+
+	return 0;
+}

+ 2 - 0
src/CMakeLists.txt

@@ -22,6 +22,7 @@ set (SRC
 	TextRenderer.cpp
 	World.cpp
 	FPSSystem.cpp
+	JSONParser.cpp
 )
 
 set (HEADERS
@@ -59,6 +60,7 @@ set (HEADERS
 	VertexBuffer.h
 	World.h
 	FPSSystem.h
+	JSONParser.h
 )
 
 set (CORE_SRC

+ 342 - 0
src/JSONParser.cpp

@@ -0,0 +1,342 @@
+#include "JSONParser.h"
+#include "OS.h"
+
+namespace crown
+{
+
+void JSONToken::print()
+{
+	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");
+}
+
+//--------------------------------------------------------------------------
+JSONParser::JSONParser(size_t size)
+{
+	if (size > 1024)
+	{
+		m_tokens = new JSONToken[size];
+	}
+	else
+	{
+		m_tokens = m_tokens_list;
+	}
+
+	m_size = size;
+}
+
+//--------------------------------------------------------------------------
+void 
+JSONParser::init()
+{
+	m_pos = 0;
+	m_next_token = 0;
+	m_prev_token = -1;
+
+	is_init = true;
+}
+
+//--------------------------------------------------------------------------
+json_error 
+JSONParser::parse(const char* src)
+{
+	json_error error;
+	JSONToken* token;
+
+	if (!is_init)
+	{
+		return JSON_NO_INIT; 
+	}
+
+	while(src[m_pos] != '\0')
+	{
+		json_type type;
+		char c;
+
+		c = src[m_pos];
+
+		switch(c)
+		{
+			case '{':
+			case '[':
+			{
+				token = allocate_token();
+
+				if (token == NULL)
+				{
+					return JSON_NO_MEMORY;
+				}
+				if (m_prev_token != -1)
+				{
+					m_tokens[m_prev_token].m_size++;
+					token->m_parent = m_prev_token;
+				}
+
+				token->m_type = c == '{' ? JSON_OBJECT : JSON_ARRAY;
+				token->m_start = m_pos;
+				m_prev_token = m_next_token - 1;
+
+				// os::printf("char: %c\n", c);
+				// os::printf("pos: %d\n", m_pos);
+				// os::printf("prev_token: %d\n", m_prev_token);
+				// os::printf("next_token: %d\n", m_next_token);
+
+				break;
+			}
+			case '}':
+			case ']':
+			{
+				type = c == '}' ? JSON_OBJECT : JSON_ARRAY;
+
+				if (m_next_token < 1)
+				{
+					return JSON_INV_CHAR;
+				}
+
+				token = &m_tokens[m_next_token -1];
+
+				while (true)
+				{
+					if (token->m_start != -1 && token->m_end != -1)
+					{
+						if (token->m_type != type)
+						{
+							return JSON_INV_CHAR;
+						}
+						token->m_end = m_pos + 1;
+						m_prev_token = token->m_parent;
+						break;
+					}
+
+					if (token->m_parent == -1)
+					{
+						break;
+					}
+
+					token = &m_tokens[token->m_parent];
+				}
+
+				// os::printf("char: %c\n", c);
+				// os::printf("pos: %d\n", m_pos);
+				// os::printf("prev_token: %d\n", m_prev_token);
+				// os::printf("next_token: %d\n", m_next_token);
+
+				break;
+			}
+			case '\"':
+			case '\'':
+			{
+				error = parse_string(src);
+            	if (m_prev_token != -1)
+            	{
+            		m_tokens[m_prev_token].m_size++;
+            	}
+				break;
+			}
+  //           case '\t': 
+  //           case '\r': 
+  //           case '\n': 
+  //           case ':': 
+  //           case ',': 
+  //           case ' ': 
+  //           {
+  //           	break;
+  //           }
+            case '-':
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            case 't':
+            case 'f':
+            case 'n':
+            {
+            	error = parse_primitive(src);
+            	if (m_prev_token != -1)
+            	{
+            		m_tokens[m_prev_token].m_size++;
+            	}
+            	break;
+            }
+		}
+		m_pos++;
+	}
+
+	return JSON_SUCCESS;
+}
+
+//--------------------------------------------------------------------------
+json_error
+JSONParser::parse_string(const char* src)
+{
+	JSONToken* token;
+
+	int start = m_pos;
+
+	m_pos++;
+
+	while(src[m_pos] != '\0')
+	{	
+		char c = src[m_pos];
+
+		if (c == '\"' || c == '\'')
+		{
+			token = allocate_token();
+
+			if (token == NULL)
+			{
+				m_pos = start;
+				return JSON_NO_MEMORY;
+			}
+
+			fill_token(token, JSON_STRING, start + 1, m_pos);
+			token->m_parent = m_prev_token;
+
+			return JSON_SUCCESS;
+		}
+
+		if (c == '\\')
+		{
+			m_pos++;
+
+			switch(src[m_pos])
+			{
+				case '\"': 
+				case '/' : 
+				case '\\': 
+				case 'b':
+                case 'f': 
+                case 'r': 
+                case 'n': 
+                case 't':
+                {
+                	break;
+                }
+                case 'u' :
+                {
+                	// TODO
+                	break;
+                }
+                default:
+               	{
+                	m_pos = start;
+                	return JSON_INV_CHAR;
+                }
+			}
+		}
+		// os::printf("char: %c\n", c);
+		// os::printf("pos: %d\n", m_pos);
+		// os::printf("prev_token: %d\n", m_prev_token);
+		// os::printf("next_token: %d\n", m_next_token);
+		m_pos++;
+	}
+
+	m_pos = start;
+	return JSON_INV_PART;
+}
+
+//--------------------------------------------------------------------------
+json_error
+JSONParser::parse_primitive(const char* src)
+{
+	JSONToken* token;
+
+	int start = m_pos;
+
+	while (src[m_pos] != '\0')
+	{
+		char c = src[m_pos];
+
+		switch (c)
+		{
+			case ':' :
+			case '\t': 
+			case '\r':
+			case '\n': 
+			case ' ' :
+			case ',' : 
+			case ']' : 
+			case '}' :
+			{
+				token = allocate_token();
+				if (token == NULL)
+				{
+					m_pos = start;
+					return JSON_NO_MEMORY;
+				}
+
+				fill_token(token, JSON_PRIMITIVE, start, m_pos);
+
+				token->m_parent = m_prev_token;
+				m_pos--;
+
+				return JSON_SUCCESS;
+			}
+		}
+
+		if (c < 32 || c >= 127)
+		{
+			m_pos = start;
+			return JSON_INV_CHAR;
+		}
+
+		// os::printf("char: %c\n", c);
+		// os::printf("pos: %d\n", m_pos);
+		// os::printf("prev_token: %d\n", m_prev_token);
+		// os::printf("next_token: %d\n", m_next_token);
+
+		m_pos++;
+	}
+}
+
+//--------------------------------------------------------------------------
+JSONToken* 
+JSONParser::allocate_token()
+{
+	JSONToken* token;
+
+	if (m_next_token >= m_size)
+	{
+		return NULL;
+	}	
+
+	token = &m_tokens[m_next_token++];
+	token->m_start = token->m_end = -1;
+	token->m_size = 0;
+	token->m_parent = -1;
+
+	return token;
+}
+
+//--------------------------------------------------------------------------
+void JSONParser::fill_token(JSONToken* token, json_type type, int32_t start, int32_t end)
+{
+	token->m_type = type;
+	token->m_start = start;
+	token->m_end = end;
+	token->m_size = 0;
+}
+
+//--------------------------------------------------------------------------
+JSONToken* JSONParser::get_tokens()
+{
+	return m_tokens;
+}
+
+//--------------------------------------------------------------------------
+int32_t JSONParser::get_tokens_number()
+{
+	return m_next_token;
+}
+
+} //namespace crown

+ 77 - 0
src/JSONParser.h

@@ -0,0 +1,77 @@
+#pragma once
+
+#include "Types.h"
+
+namespace crown
+{
+
+enum json_type
+{
+	JSON_PRIMITIVE 	= 0,	// Number, boolean or null
+	JSON_OBJECT 	= 1,	// Object
+	JSON_ARRAY 		= 2,	// Array
+	JSON_STRING 	= 3		// String
+};
+
+enum json_error
+{
+	JSON_NO_MEMORY	= 0,	// Not enough token provided
+	JSON_INV_CHAR	= 1,	// Invalid character inside JSON string
+	JSON_INV_PART	= 2,	// JSON string is incompleted
+	JSON_NO_INIT	= 3,	// JSON parser not initialized
+	JSON_SUCCESS	= 4		// Everything OK!
+};
+
+struct JSONToken
+{
+	json_type	m_type;
+	int32_t 	m_start;
+	int32_t 	m_end;
+	size_t 		m_size;
+	int32_t 	m_parent;
+
+	void print();
+};
+
+class JSONParser
+{
+public:
+	/// Constructor
+					JSONParser(size_t size = 1024);
+	/// Init JSON parser, must be called for each different JSON string
+	void 			init();
+	/// Parse JSON data
+	json_error 		parse(const char* src);
+	/// Parse string in JSON data
+	json_error		parse_string(const char* src);
+	/// Parse number or boolean in JSON data
+	json_error		parse_primitive(const char* src);
+	/// Allocate token node
+	JSONToken* 		allocate_token();
+	/// Fill token and set boundaries
+	void			fill_token(JSONToken* token, json_type type, int32_t start, int32_t end);
+	/// Get all tokens
+	JSONToken*		get_tokens();
+	/// Get next token
+	int32_t			get_tokens_number();
+
+private:
+	/// JSON string offset
+	uint32_t 		m_pos;
+	/// 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_size;
+
+	// is JSON parser initilized
+	bool 			is_init;		
+};
+
+} // namespace crown