aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Arrskog <topfs2@xbmc.org>2011-05-17 20:47:07 +0200
committerTobias Arrskog <topfs2@xbmc.org>2011-05-20 15:01:19 +0200
commit8f9536610a581f48db1be920709c76ea5016ca26 (patch)
tree840ee0e7790b0b256a7e8ca14635cb5501904c8e
parented993c30c498f689e16304acb1716cd36220c21f (diff)
Added yajl parser for Variant
-rw-r--r--xbmc/utils/JSONVariantParser.cpp214
-rw-r--r--xbmc/utils/JSONVariantParser.h87
-rw-r--r--xbmc/utils/Makefile1
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 \