1 /*
2 * Copyright (C) 2014 Jean-Luc Barriere
3 *
4 * This Program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2, or (at your option)
7 * any later version.
8 *
9 * This Program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING. If not, write to
16 * the Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
17 * MA 02110-1301 USA
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 */
21
22 #include "jsonparser.h"
23
24 #include <QDebug>
25 #include <cstring>
26
27 using namespace thumbnailer;
28
29 ///////////////////////////////////////////////////////////////////////////////
30 ////
31 //// Node
32 ////
33
Node()34 JSON::Node::Node()
35 : m_value(sajson::TYPE_NULL, nullptr, nullptr)
36 {
37 }
38
Node(const sajson::value & value)39 JSON::Node::Node(const sajson::value& value)
40 : m_value(value)
41 {
42 }
43
IsNull() const44 bool JSON::Node::IsNull() const
45 {
46 return (m_value.get_type() == sajson::TYPE_NULL);
47 }
48
IsObject() const49 bool JSON::Node::IsObject() const
50 {
51 return (m_value.get_type() == sajson::TYPE_OBJECT);
52 }
53
IsArray() const54 bool JSON::Node::IsArray() const
55 {
56 return (m_value.get_type() == sajson::TYPE_ARRAY);
57 }
58
IsString() const59 bool JSON::Node::IsString() const
60 {
61 return (m_value.get_type() == sajson::TYPE_STRING);
62 }
63
IsDouble() const64 bool JSON::Node::IsDouble() const
65 {
66 return (m_value.get_type() == sajson::TYPE_DOUBLE);
67 }
68
IsInt() const69 bool JSON::Node::IsInt() const
70 {
71 return (m_value.get_type() == sajson::TYPE_INTEGER);
72 }
73
IsTrue() const74 bool JSON::Node::IsTrue() const
75 {
76 return (m_value.get_type() == sajson::TYPE_TRUE);
77 }
78
IsFalse() const79 bool JSON::Node::IsFalse() const
80 {
81 return (m_value.get_type() == sajson::TYPE_FALSE);
82 }
83
GetStringValue() const84 QString JSON::Node::GetStringValue() const
85 {
86 if (m_value.get_type() == sajson::TYPE_STRING)
87 return QString::fromUtf8(m_value.as_string().c_str());
88 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
89 return QString();
90 }
91
GetStringSize() const92 size_t JSON::Node::GetStringSize() const
93 {
94 if (m_value.get_type() == sajson::TYPE_STRING)
95 return m_value.get_string_length();
96 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
97 return 0;
98 }
99
GetDoubleValue() const100 double JSON::Node::GetDoubleValue() const
101 {
102 if (m_value.get_type() == sajson::TYPE_DOUBLE)
103 return m_value.get_double_value();
104 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
105 return 0.0;
106 }
107
GetBigIntValue() const108 int64_t JSON::Node::GetBigIntValue() const
109 {
110 if (m_value.get_type() == sajson::TYPE_DOUBLE || m_value.get_type() == sajson::TYPE_INTEGER)
111 return (int64_t) m_value.get_number_value();
112 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
113 return 0;
114 }
115
GetIntValue() const116 int32_t JSON::Node::GetIntValue() const
117 {
118 if (m_value.get_type() == sajson::TYPE_INTEGER)
119 return (int32_t) m_value.get_integer_value();
120 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
121 return 0;
122 }
123
Size() const124 size_t JSON::Node::Size() const
125 {
126 if (m_value.get_type() == sajson::TYPE_ARRAY || m_value.get_type() == sajson::TYPE_OBJECT)
127 return m_value.get_length();
128 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
129 return 0;
130 }
131
GetArrayElement(size_t index) const132 JSON::Node JSON::Node::GetArrayElement(size_t index) const
133 {
134 if (m_value.get_type() == sajson::TYPE_ARRAY)
135 return Node(m_value.get_array_element(index));
136 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
137 return Node();
138 }
139
GetObjectKey(size_t index) const140 QString JSON::Node::GetObjectKey(size_t index) const
141 {
142 if (m_value.get_type() == sajson::TYPE_OBJECT)
143 return QString::fromUtf8(m_value.get_object_key(index).as_string().c_str());
144 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
145 return QString();
146 }
147
GetObjectValue(size_t index) const148 JSON::Node JSON::Node::GetObjectValue(size_t index) const
149 {
150 if (m_value.get_type() == sajson::TYPE_OBJECT)
151 return Node(m_value.get_object_value(index));
152 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
153 return Node();
154 }
155
GetObjectValue(const char * key) const156 JSON::Node JSON::Node::GetObjectValue(const char *key) const
157 {
158 if (m_value.get_type() == sajson::TYPE_OBJECT)
159 {
160 size_t idx = m_value.find_object_key(sajson::literal(key));
161 if (idx < m_value.get_length())
162 return Node(m_value.get_object_value(idx));
163 return Node();
164 }
165 qWarning().noquote() << __FUNCTION__ << ": bad type " << (int) m_value.get_type();
166 return Node();
167 }
168
169 ///////////////////////////////////////////////////////////////////////////////
170 ////
171 //// Document
172 ////
173
Document(const char * doc)174 JSON::Document::Document(const char* doc)
175 : m_isValid(false)
176 , m_document(nullptr)
177 {
178 size_t len = strlen(doc);
179 if (len > 0)
180 {
181 // Parse JSON content
182 m_document = new sajson::document(sajson::parse(sajson::string(doc, len)));
183 if (!m_document)
184 qWarning().noquote() << __FUNCTION__ << ": memory allocation failed";
185 else if (!m_document->is_valid())
186 qWarning().noquote() << __FUNCTION__ << ": failed to parse: " << (int) m_document->get_error_line()
187 << ": " << m_document->get_error_message().c_str();
188 else
189 m_isValid = true;
190 }
191 else
192 {
193 qWarning().noquote() << __FUNCTION__ << ": document is empty";
194 }
195 }
196
GetRoot() const197 JSON::Node JSON::Document::GetRoot() const
198 {
199 if (m_document)
200 return Node(m_document->get_root());
201 return Node();
202 }
203
204