[PVR][Estuary] Timer settings dialog: Show client name in timer type selection dialog...
[xbmc.git] / xbmc / utils / JSONVariantParser.cpp
blob493abfdbe4fe0ccafed78bbbe83cc530ff4bde1e
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "JSONVariantParser.h"
11 #include <rapidjson/reader.h>
13 class CJSONVariantParserHandler
15 public:
16 explicit CJSONVariantParserHandler(CVariant& parsedObject);
18 bool Null();
19 bool Bool(bool b);
20 bool Int(int i);
21 bool Uint(unsigned u);
22 bool Int64(int64_t i);
23 bool Uint64(uint64_t u);
24 bool Double(double d);
25 bool RawNumber(const char* str, rapidjson::SizeType length, bool copy);
26 bool String(const char* str, rapidjson::SizeType length, bool copy);
27 bool StartObject();
28 bool Key(const char* str, rapidjson::SizeType length, bool copy);
29 bool EndObject(rapidjson::SizeType memberCount);
30 bool StartArray();
31 bool EndArray(rapidjson::SizeType elementCount);
33 private:
34 template <typename... TArgs>
35 bool Primitive(TArgs... args)
37 PushObject(CVariant(std::forward<TArgs>(args)...));
38 PopObject();
40 return true;
43 void PushObject(const CVariant& variant);
44 void PopObject();
46 CVariant& m_parsedObject;
47 std::vector<CVariant *> m_parse;
48 std::string m_key;
49 CVariant m_root;
51 enum class PARSE_STATUS
53 Variable,
54 Array,
55 Object
57 PARSE_STATUS m_status;
60 CJSONVariantParserHandler::CJSONVariantParserHandler(CVariant& parsedObject)
61 : m_parsedObject(parsedObject),
62 m_parse(),
63 m_key(),
64 m_status(PARSE_STATUS::Variable)
65 { }
67 bool CJSONVariantParserHandler::Null()
69 PushObject(CVariant::ConstNullVariant);
70 PopObject();
72 return true;
75 bool CJSONVariantParserHandler::Bool(bool b)
77 return Primitive(b);
80 bool CJSONVariantParserHandler::Int(int i)
82 return Primitive(i);
85 bool CJSONVariantParserHandler::Uint(unsigned u)
87 return Primitive(u);
90 bool CJSONVariantParserHandler::Int64(int64_t i)
92 return Primitive(i);
95 bool CJSONVariantParserHandler::Uint64(uint64_t u)
97 return Primitive(u);
100 bool CJSONVariantParserHandler::Double(double d)
102 return Primitive(d);
105 bool CJSONVariantParserHandler::RawNumber(const char* str, rapidjson::SizeType length, bool copy)
107 return Primitive(str, length);
110 bool CJSONVariantParserHandler::String(const char* str, rapidjson::SizeType length, bool copy)
112 return Primitive(str, length);
115 bool CJSONVariantParserHandler::StartObject()
117 PushObject(CVariant::VariantTypeObject);
119 return true;
122 bool CJSONVariantParserHandler::Key(const char* str, rapidjson::SizeType length, bool copy)
124 m_key = std::string(str, 0, length);
126 return true;
129 bool CJSONVariantParserHandler::EndObject(rapidjson::SizeType memberCount)
131 PopObject();
133 return true;
136 bool CJSONVariantParserHandler::StartArray()
138 PushObject(CVariant::VariantTypeArray);
140 return true;
143 bool CJSONVariantParserHandler::EndArray(rapidjson::SizeType elementCount)
145 PopObject();
147 return true;
150 void CJSONVariantParserHandler::PushObject(const CVariant& variant)
152 if (m_status == PARSE_STATUS::Object)
154 (*m_parse[m_parse.size() - 1])[m_key] = variant;
155 m_parse.push_back(&(*m_parse[m_parse.size() - 1])[m_key]);
157 else if (m_status == PARSE_STATUS::Array)
159 CVariant *temp = m_parse[m_parse.size() - 1];
160 temp->push_back(variant);
161 m_parse.push_back(&(*temp)[temp->size() - 1]);
163 else if (m_parse.empty())
165 m_root = variant;
166 m_parse.push_back(&m_root);
169 if (variant.isObject())
170 m_status = PARSE_STATUS::Object;
171 else if (variant.isArray())
172 m_status = PARSE_STATUS::Array;
173 else
174 m_status = PARSE_STATUS::Variable;
177 void CJSONVariantParserHandler::PopObject()
179 CVariant *variant = m_parse[m_parse.size() - 1];
180 m_parse.pop_back();
182 if (!m_parse.empty())
184 variant = m_parse[m_parse.size() - 1];
185 if (variant->isObject())
186 m_status = PARSE_STATUS::Object;
187 else if (variant->isArray())
188 m_status = PARSE_STATUS::Array;
189 else
190 m_status = PARSE_STATUS::Variable;
192 else
194 m_parsedObject = *variant;
195 m_status = PARSE_STATUS::Variable;
199 bool CJSONVariantParser::Parse(const char* json, CVariant& data)
201 if (json == nullptr)
202 return false;
204 rapidjson::Reader reader;
205 rapidjson::StringStream stringStream(json);
207 CJSONVariantParserHandler handler(data);
208 // use kParseIterativeFlag to eliminate possible stack overflow
209 // from json parsing via reentrant calls
210 if (reader.Parse<rapidjson::kParseIterativeFlag>(stringStream, handler))
211 return true;
213 return false;
216 bool CJSONVariantParser::Parse(const std::string& json, CVariant& data)
218 return Parse(json.c_str(), data);