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