2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
21 #include "JSONVariantParser.h"
23 yajl_callbacks CJSONVariantParser::callbacks = {
24 CJSONVariantParser::ParseNull,
25 CJSONVariantParser::ParseBoolean,
26 CJSONVariantParser::ParseInteger,
27 CJSONVariantParser::ParseDouble,
29 CJSONVariantParser::ParseString,
30 CJSONVariantParser::ParseMapStart,
31 CJSONVariantParser::ParseMapKey,
32 CJSONVariantParser::ParseMapEnd,
33 CJSONVariantParser::ParseArrayStart,
34 CJSONVariantParser::ParseArrayEnd
37 CJSONVariantParser::CJSONVariantParser(IParseCallback *callback)
39 m_callback = callback;
42 m_handler = yajl_alloc(&callbacks, NULL, this);
44 yajl_config(m_handler, yajl_allow_comments, 1);
45 yajl_config(m_handler, yajl_dont_validate_strings, 0);
47 yajl_parser_config cfg = { 1, 1 };
49 m_handler = yajl_alloc(&callbacks, &cfg, NULL, this);
52 m_status = ParseVariable;
55 CJSONVariantParser::~CJSONVariantParser()
58 yajl_complete_parse(m_handler);
60 yajl_parse_complete(m_handler);
65 void CJSONVariantParser::push_buffer(const unsigned char *buffer, unsigned int length)
67 yajl_parse(m_handler, buffer, length);
70 CVariant CJSONVariantParser::Parse(const unsigned char *json, unsigned int length)
72 CSimpleParseCallback callback;
73 CJSONVariantParser parser(&callback);
75 parser.push_buffer(json, length);
77 return callback.GetOutput();
80 int CJSONVariantParser::ParseNull(void * ctx)
82 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
84 parser->PushObject(CVariant::VariantTypeNull);
90 int CJSONVariantParser::ParseBoolean(void * ctx, int boolean)
92 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
94 parser->PushObject(CVariant(boolean != 0));
101 int CJSONVariantParser::ParseInteger(void * ctx, long long integerVal)
103 int CJSONVariantParser::ParseInteger(void * ctx, long integerVal)
106 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
108 parser->PushObject(CVariant((int64_t)integerVal));
114 int CJSONVariantParser::ParseDouble(void * ctx, double doubleVal)
116 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
118 parser->PushObject(CVariant((float)doubleVal));
125 int CJSONVariantParser::ParseString(void * ctx, const unsigned char * stringVal, size_t stringLen)
127 int CJSONVariantParser::ParseString(void * ctx, const unsigned char * stringVal, unsigned int stringLen)
130 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
132 parser->PushObject(CVariant((const char *)stringVal, stringLen));
138 int CJSONVariantParser::ParseMapStart(void * ctx)
140 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
142 parser->PushObject(CVariant::VariantTypeObject);
148 int CJSONVariantParser::ParseMapKey(void * ctx, const unsigned char * stringVal, size_t stringLen)
150 int CJSONVariantParser::ParseMapKey(void * ctx, const unsigned char * stringVal, unsigned int stringLen)
153 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
155 parser->m_key = std::string((const char *)stringVal, 0, stringLen);
160 int CJSONVariantParser::ParseMapEnd(void * ctx)
162 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
169 int CJSONVariantParser::ParseArrayStart(void * ctx)
171 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
173 parser->PushObject(CVariant::VariantTypeArray);
178 int CJSONVariantParser::ParseArrayEnd(void * ctx)
180 CJSONVariantParser *parser = (CJSONVariantParser *)ctx;
187 void CJSONVariantParser::PushObject(CVariant variant)
189 if (m_status == ParseObject)
191 (*m_parse[m_parse.size() - 1])[m_key] = variant;
192 m_parse.push_back(&(*m_parse[m_parse.size() - 1])[m_key]);
194 else if (m_status == ParseArray)
196 CVariant *temp = m_parse[m_parse.size() - 1];
197 temp->push_back(variant);
198 m_parse.push_back(&(*temp)[temp->size() - 1]);
200 else if (m_parse.size() == 0)
202 m_parse.push_back(new CVariant(variant));
205 if (variant.isObject())
206 m_status = ParseObject;
207 else if (variant.isArray())
208 m_status = ParseArray;
210 m_status = ParseVariable;
213 void CJSONVariantParser::PopObject()
215 CVariant *variant = m_parse[m_parse.size() - 1];
220 variant = m_parse[m_parse.size() - 1];
221 if (variant->isObject())
222 m_status = ParseObject;
223 else if (variant->isArray())
224 m_status = ParseArray;
226 m_status = ParseVariable;
230 m_callback->onParsed(variant);
234 m_status = ParseVariable;