| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- #include "JSONParser.h"
- #include "FileStream.h"
- namespace crown
- {
- //--------------------------------------------------------------------------
- JSONParser::JSONParser(Stream* stream, size_t size)
- {
- if (size > 1024)
- {
- m_tokens = new JSONToken[size];
- }
- else
- {
- m_tokens = m_tokens_list;
- }
- m_size = size;
- m_stream = stream;
- }
- //--------------------------------------------------------------------------
- JSONParser::~JSONParser()
- {
- if (m_size > 1024)
- {
- delete m_tokens;
- }
- else
- {
- delete [] m_tokens_list;
- }
- }
- //--------------------------------------------------------------------------
- void
- JSONParser::init()
- {
- m_pos = m_stream->position();
- m_next_token = 0;
- m_prev_token = -1;
- is_init = true;
- }
- //--------------------------------------------------------------------------
- void
- JSONParser::shutdown()
- {
- m_pos = 0;
- m_next_token = 0;
- m_prev_token = -1;
- is_init = false;
- }
- //--------------------------------------------------------------------------
- json_error
- JSONParser::parse()
- {
- if (!is_init)
- {
- return JSON_NO_INIT;
- }
- json_error error;
- JSONToken* token;
- char c;
- while(!m_stream->end_of_stream())
- {
- json_type type;
- c = (char)m_stream->read_byte();
- m_pos = m_stream->position();
- 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;
- 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];
- }
- token->m_size = token->m_end - token->m_start;
- break;
- }
- case '\"':
- {
- error = parse_string();
- 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();
- if (m_prev_token != -1)
- {
- m_tokens[m_prev_token].m_size++;
- }
- break;
- }
- }
- }
- for (int i = m_next_token - 1; i >= 0; i--)
- {
- if (m_tokens[i].m_start != -1 && m_tokens[i].m_end == -1)
- {
- return JSON_INV_PART;
- }
- }
- return JSON_SUCCESS;
- }
- //--------------------------------------------------------------------------
- json_error
- JSONParser::parse_string()
- {
- JSONToken* token;
- int start = m_pos;
- char c;
- while(!m_stream->end_of_stream())
- {
- c = (char) m_stream->read_byte();
- m_pos = m_stream->position();
- 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 == '\\')
- {
- c = (char)m_stream->read_byte();
- m_pos = m_stream->position();
- switch(c)
- {
- case '\"':
- case '/' :
- case '\\':
- case 'b':
- case 'f':
- case 'r':
- case 'n':
- case 't':
- case 'u':
- {
- break;
- }
- default:
- {
- m_pos = start;
- return JSON_INV_CHAR;
- }
- }
- }
- }
- m_pos = start;
- return JSON_INV_PART;
- }
- //--------------------------------------------------------------------------
- json_error
- JSONParser::parse_primitive()
- {
- JSONToken* token;
- int start = m_stream->position();
- char c;
- while (!m_stream->end_of_stream())
- {
- c = (char)m_stream->read_byte();
- m_pos = m_stream->position();
- switch (c)
- {
- 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_stream->seek(start);
- return JSON_SUCCESS;
- }
- }
- if (c < 32 || c >= 127)
- {
- m_pos = start;
- return JSON_INV_CHAR;
- }
- }
- }
- //--------------------------------------------------------------------------
- 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 = token->m_end - token->m_start;
- }
- //--------------------------------------------------------------------------
- JSONToken* JSONParser::get_tokens()
- {
- return m_tokens;
- }
- //--------------------------------------------------------------------------
- int32_t JSONParser::get_tokens_number()
- {
- return m_next_token;
- }
- } //namespace crown
|