|
|
@@ -3,622 +3,214 @@
|
|
|
#include "OS.h"
|
|
|
#include "StringUtils.h"
|
|
|
#include "Assert.h"
|
|
|
-#include <stdlib.h>
|
|
|
+#include "Log.h"
|
|
|
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
-JSONParser& JSONParser::get_object(const char* key)
|
|
|
+JSONParser& JSONParser::array(const char* key, uint32_t index)
|
|
|
{
|
|
|
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;
|
|
|
}
|
|
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
-JSONParser& JSONParser::get_string(const char* key)
|
|
|
+const char* JSONParser::string(const char* key, List<char>& str)
|
|
|
{
|
|
|
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
|