MythTV master
jsonSerializer.cpp
Go to the documentation of this file.
1
2// Program Name: jsonSerializer.cpp
3// Created : Nov. 28, 2009
4//
5// Purpose : Serialization Implementation for JSON
6//
7// Copyright (c) 2005 David Blain <dblain@mythtv.org>
8//
9// Licensed under the GPL v2 or later, see LICENSE for details
10//
12
13#include "jsonSerializer.h"
15
16#include <QVariant>
17
19//
21
23{
24 return "application/json";
25}
26
27
29//
31
32void JSONSerializer::BeginSerialize( QString &/*sName*/ )
33{
34 m_bCommaNeeded = false;
35
36 m_stream << "{";
37}
38
40//
42
44{
45 m_bCommaNeeded = false;
46
47 m_stream << "}";
48
49 m_stream.flush();
50}
51
52
54//
56
57void JSONSerializer::BeginObject( const QString &sName, const QObject */*pObject*/ )
58{
59 m_bCommaNeeded = false;
60
61 m_stream << "\"" << sName << "\": {";
62}
63
65//
67
68void JSONSerializer::EndObject ( const QString &/*sName*/, const QObject */*pObject*/ )
69{
70 m_bCommaNeeded = false;
71
72 m_stream << "}";
73}
74
76//
78
79void JSONSerializer::AddProperty( const QString &sName,
80 const QVariant &vValue,
81 const QMetaObject */*pMetaParent*/,
82 const QMetaProperty */*pMetaProp*/ )
83{
85 m_stream << ", ";
86
87 m_stream << "\"" << sName << "\": ";
88
89 RenderValue( vValue );
90
91 m_bCommaNeeded = true;
92}
93
95//
97
98void JSONSerializer::RenderValue( const QVariant &vValue )
99{
100
101 // -----------------------------------------------------------------------
102 // See if this value is actually a child object
103 // -----------------------------------------------------------------------
104
105 if ( vValue.canConvert< QObject* >())
106 {
107 const QObject *pObject = vValue.value< QObject* >();
108
109 bool bSavedCommaNeeded = m_bCommaNeeded;
110 m_bCommaNeeded = false;
111
112 m_stream << "{";
113 SerializeObjectProperties( pObject );
114 m_stream << "}";
115
116 m_bCommaNeeded = bSavedCommaNeeded;
117
118 return;
119 }
120
121 // -----------------------------------------------------------------------
122 // Handle QVariant special cases...
123 // -----------------------------------------------------------------------
124
125#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
126 auto type = static_cast<QMetaType::Type>(vValue.type());
127#else
128 auto type = vValue.typeId();
129#endif
130 switch( type )
131 {
132 case QMetaType::QVariantList: RenderList ( vValue.toList() ); break;
133 case QMetaType::QStringList: RenderStringList( vValue.toStringList() ); break;
134 case QMetaType::QVariantMap: RenderMap ( vValue.toMap() ); break;
135 case QMetaType::QDateTime:
136 {
137 m_stream << "\"" << Encode(
138 MythDate::toString( vValue.toDateTime(), MythDate::ISODate ) )
139 << "\"";
140 break;
141 }
142 default:
143 {
144 m_stream << "\"" << Encode( vValue.toString() ) << "\"";
145 break;
146 }
147 }
148}
149
151//
153
154void JSONSerializer::RenderList( const QVariantList &list )
155{
156 bool bFirst = true;
157
158 m_stream << "[";
159
160 for (const auto& variant : list)
161 {
162 if (bFirst)
163 bFirst = false;
164 else
165 m_stream << ",";
166
167 RenderValue( variant );
168 }
169
170 m_stream << "]";
171}
172
174//
176
177void JSONSerializer::RenderStringList( const QStringList &list )
178{
179 bool bFirst = true;
180
181 m_stream << "[";
182
183 for (const auto& str : list)
184 {
185 if (bFirst)
186 bFirst = false;
187 else
188 m_stream << ",";
189
190 m_stream << "\"" << Encode( str ) << "\"";
191 }
192
193 m_stream << "]";
194}
195
197//
199
200void JSONSerializer::RenderMap( const QVariantMap &map )
201{
202 bool bFirst = true;
203
204 m_stream << "{";
205
206 for (auto it = map.cbegin(); it != map.cend(); ++it)
207 {
208 if (bFirst)
209 bFirst = false;
210 else
211 m_stream << ",";
212
213 m_stream << "\"" << it.key() << "\":";
214 m_stream << "\"" << Encode( it.value().toString() ) << "\"";
215 }
216
217 m_stream << "}";
218}
219
221//
223
224QString JSONSerializer::Encode(const QString &sIn)
225{
226 if (sIn.isEmpty())
227 return sIn;
228
229 QString sStr = sIn;
230
231 sStr.replace( '\\', "\\\\" ); // This must be first
232 sStr.replace( '"' , "\\\"" );
233 sStr.replace( '\b', "\\b" ); // ^H (\u0008)
234 sStr.replace( '\f', "\\f" ); // ^L (\u000C)
235 sStr.replace( '\n', "\\n" ); // ^J (\u000A)
236 sStr.replace( "\r", "\\r" ); // ^M (\u000D)
237 sStr.replace( "\t", "\\t" ); // ^I (\u0009)
238 sStr.replace( "/", "\\/" );
239
240 // Escape remaining chars from \u0000 - \u001F
241 // Details at https://en.wikipedia.org/wiki/C0_and_C1_control_codes
242 sStr.replace(QChar('\u0000'), "\\u0000"); // ^@ NULL
243 sStr.replace(QChar('\u0001'), "\\u0001"); // ^A
244 sStr.replace(QChar('\u0002'), "\\u0002"); // ^B
245 sStr.replace(QChar('\u0003'), "\\u0003"); // ^C
246 sStr.replace(QChar('\u0004'), "\\u0004"); // ^D
247 sStr.replace(QChar('\u0005'), "\\u0005"); // ^E
248 sStr.replace(QChar('\u0006'), "\\u0006"); // ^F
249 sStr.replace(QChar('\u0007'), "\\u0007"); // ^G (\a)
250 sStr.replace(QChar('\u000B'), "\\u000B"); // ^K (\v)
251 sStr.replace(QChar('\u000E'), "\\u000E"); // ^N
252 sStr.replace(QChar('\u000F'), "\\u000F"); // ^O
253 sStr.replace(QChar('\u0010'), "\\u0010"); // ^P
254 sStr.replace(QChar('\u0011'), "\\u0011"); // ^Q XON
255 sStr.replace(QChar('\u0012'), "\\u0012"); // ^R
256 sStr.replace(QChar('\u0013'), "\\u0013"); // ^S XOFF
257 sStr.replace(QChar('\u0014'), "\\u0014"); // ^T
258 sStr.replace(QChar('\u0015'), "\\u0015"); // ^U
259 sStr.replace(QChar('\u0016'), "\\u0016"); // ^V
260 sStr.replace(QChar('\u0017'), "\\u0017"); // ^W
261 sStr.replace(QChar('\u0018'), "\\u0018"); // ^X
262 sStr.replace(QChar('\u0019'), "\\u0019"); // ^Y
263 sStr.replace(QChar('\u001A'), "\\u001A"); // ^Z
264 sStr.replace(QChar('\u001B'), "\\u001B");
265 sStr.replace(QChar('\u001C'), "\\u001C");
266 sStr.replace(QChar('\u001D'), "\\u001D");
267 sStr.replace(QChar('\u001E'), "\\u001E");
268 sStr.replace(QChar('\u001F'), "\\u001F");
269
270 return sStr;
271}
static QString Encode(const QString &sIn)
void RenderStringList(const QStringList &list)
void RenderMap(const QVariantMap &map)
QTextStream m_stream
QString GetContentType() override
void EndSerialize() override
void BeginObject(const QString &sName, const QObject *pObject) override
void BeginSerialize(QString &sName) override
void RenderValue(const QVariant &vValue)
void AddProperty(const QString &sName, const QVariant &vValue, const QMetaObject *pMetaParent, const QMetaProperty *pMetaProp) override
void EndObject(const QString &sName, const QObject *pObject) override
void RenderList(const QVariantList &list)
void SerializeObjectProperties(const QObject *pObject)
Definition: serializer.cpp:103
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
@ ISODate
Default UTC.
Definition: mythdate.h:17