diff options
author | Tobias Arrskog <topfs2@xbmc.org> | 2011-05-17 20:47:07 +0200 |
---|---|---|
committer | Tobias Arrskog <topfs2@xbmc.org> | 2011-05-20 15:01:19 +0200 |
commit | 8f9536610a581f48db1be920709c76ea5016ca26 (patch) | |
tree | 840ee0e7790b0b256a7e8ca14635cb5501904c8e | |
parent | ed993c30c498f689e16304acb1716cd36220c21f (diff) |
Added yajl parser for Variant
-rw-r--r-- | xbmc/utils/JSONVariantParser.cpp | 214 | ||||
-rw-r--r-- | xbmc/utils/JSONVariantParser.h | 87 | ||||
-rw-r--r-- | xbmc/utils/Makefile | 1 |
3 files changed, 302 insertions, 0 deletions
diff --git a/xbmc/utils/JSONVariantParser.cpp b/xbmc/utils/JSONVariantParser.cpp new file mode 100644 index 0000000000..0dec423e03 --- /dev/null +++ b/xbmc/utils/JSONVariantParser.cpp @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2005-2011 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include "JSONVariantParser.h" + +yajl_callbacks CJSONVariantParser::callbacks = { + CJSONVariantParser::ParseNull, + CJSONVariantParser::ParseBoolean, + CJSONVariantParser::ParseInteger, + CJSONVariantParser::ParseDouble, + NULL, + CJSONVariantParser::ParseString, + CJSONVariantParser::ParseMapStart, + CJSONVariantParser::ParseMapKey, + CJSONVariantParser::ParseMapEnd, + CJSONVariantParser::ParseArrayStart, + CJSONVariantParser::ParseArrayEnd +}; + +CJSONVariantParser::CJSONVariantParser(IParseCallback *callback) +{ + m_callback = callback; + + yajl_status stat; + yajl_parser_config cfg = { 1, 1 }; + + m_handler = yajl_alloc(&callbacks, &cfg, NULL, this); + + m_status = ParseVariable; +} + +CJSONVariantParser::~CJSONVariantParser() +{ + yajl_status sta = yajl_parse_complete(m_handler); +} + +void CJSONVariantParser::push_buffer(const unsigned char *buffer, unsigned int length) +{ + yajl_status sta = yajl_parse(m_handler, buffer, length); +} + +CVariant CJSONVariantParser::Parse(const unsigned char *json, unsigned int length) +{ + CSimpleParseCallback callback; + CJSONVariantParser parser(&callback); + + parser.push_buffer(json, length); + + return callback.GetOutput(); +} + +int CJSONVariantParser::ParseNull(void * ctx) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PushObject(CVariant::VariantTypeNull); + parser->PopObject(); + + return 1; +} + +int CJSONVariantParser::ParseBoolean(void * ctx, int boolean) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PushObject(CVariant(boolean != 0)); + parser->PopObject(); + + return 1; +} + +int CJSONVariantParser::ParseInteger(void * ctx, long integerVal) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PushObject(CVariant((int64_t)integerVal)); + parser->PopObject(); + + return 1; +} + +int CJSONVariantParser::ParseDouble(void * ctx, double doubleVal) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PushObject(CVariant((float)doubleVal)); + parser->PopObject(); + + return 1; +} + +int CJSONVariantParser::ParseString(void * ctx, const unsigned char * stringVal, unsigned int stringLen) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PushObject(CVariant((const char *)stringVal, stringLen)); + parser->PopObject(); + + return 1; +} + +int CJSONVariantParser::ParseMapStart(void * ctx) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PushObject(CVariant::VariantTypeObject); + + return 1; +} + +int CJSONVariantParser::ParseMapKey(void * ctx, const unsigned char * stringVal, unsigned int stringLen) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->m_key = std::string((const char *)stringVal, 0, stringLen); + + return 1; +} + +int CJSONVariantParser::ParseMapEnd(void * ctx) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PopObject(); + + return 1; +} + +int CJSONVariantParser::ParseArrayStart(void * ctx) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PushObject(CVariant::VariantTypeArray); + + return 1; +} + +int CJSONVariantParser::ParseArrayEnd(void * ctx) +{ + CJSONVariantParser *parser = (CJSONVariantParser *)ctx; + + parser->PopObject(); + + return 1; +} + +void CJSONVariantParser::PushObject(CVariant variant) +{ + if (m_status == ParseObject) + { + (*m_parse[m_parse.size() - 1])[m_key] = variant; + m_parse.push_back(&(*m_parse[m_parse.size() - 1])[m_key]); + } + else if (m_status == ParseArray) + { + CVariant *temp = m_parse[m_parse.size() - 1]; + temp->push_back(variant); + m_parse.push_back(&(*temp)[temp->size() - 1]); + } + else if (m_parse.size() == 0) + { + m_parse.push_back(new CVariant(variant)); + } + + if (variant.isObject()) + m_status = ParseObject; + else if (variant.isArray()) + m_status = ParseArray; + else + m_status = ParseVariable; +} + +void CJSONVariantParser::PopObject() +{ + CVariant *variant = m_parse[m_parse.size() - 1]; + m_parse.pop_back(); + + if (m_parse.size()) + { + variant = m_parse[m_parse.size() - 1]; + if (variant->isObject()) + m_status = ParseObject; + else if (variant->isArray()) + m_status = ParseArray; + else + m_status = ParseVariable; + } + else if (m_callback) + { + m_callback->onParsed(variant); + delete variant; + + m_parse.clear(); + m_status = ParseVariable; + } +} diff --git a/xbmc/utils/JSONVariantParser.h b/xbmc/utils/JSONVariantParser.h new file mode 100644 index 0000000000..f0a72dbdc1 --- /dev/null +++ b/xbmc/utils/JSONVariantParser.h @@ -0,0 +1,87 @@ +#pragma once +/* + * Copyright (C) 2005-2011 Team XBMC + * http://www.xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, write to + * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * http://www.gnu.org/copyleft/gpl.html + * + */ + +#include <yajl/yajl_parse.h> +#include <yajl/yajl_gen.h> + +#include "Variant.h" + +class IParseCallback +{ +public: + virtual ~IParseCallback() { } + + virtual void onParsed(CVariant *variant) = 0; +}; + +class CSimpleParseCallback : public IParseCallback +{ +public: + virtual void onParsed(CVariant *variant) { m_parsed = *variant; } + CVariant &GetOutput() { return m_parsed; } + +private: + CVariant m_parsed; +}; + +class CJSONVariantParser +{ +public: + CJSONVariantParser(IParseCallback *callback); + ~CJSONVariantParser(); + + void push_buffer(const unsigned char *buffer, unsigned int length); + + static CVariant Parse(const unsigned char *json, unsigned int length); + +private: + static int ParseNull(void * ctx); + static int ParseBoolean(void * ctx, int boolean); + static int ParseInteger(void * ctx, long integerVal); + static int ParseDouble(void * ctx, double doubleVal); + static int ParseString(void * ctx, const unsigned char * stringVal, unsigned int stringLen); + static int ParseMapStart(void * ctx); + static int ParseMapKey(void * ctx, const unsigned char * stringVal, unsigned int stringLen); + static int ParseMapEnd(void * ctx); + static int ParseArrayStart(void * ctx); + static int ParseArrayEnd(void * ctx); + + void PushObject(CVariant variant); + void PopObject(); + + static yajl_callbacks callbacks; + + IParseCallback *m_callback; + yajl_handle m_handler; + + CVariant m_parsedObject; + std::vector<CVariant *> m_parse; + std::string m_key; + + enum PARSE_STATUS + { + ParseArray = 1, + ParseObject = 2, + ParseVariable = 0 + }; + PARSE_STATUS m_status; +}; diff --git a/xbmc/utils/Makefile b/xbmc/utils/Makefile index 8258231eec..44e7502816 100644 --- a/xbmc/utils/Makefile +++ b/xbmc/utils/Makefile @@ -22,6 +22,7 @@ SRCS=AlarmClock.cpp \ HttpHeader.cpp \ InfoLoader.cpp \ JobManager.cpp \ + JSONVariantParser.cpp \ LabelFormatter.cpp \ LangCodeExpander.cpp \ LCD.cpp \ |