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 QListIterator< QVariant > it( list );
161
162 while (it.hasNext())
163 {
164 if (bFirst)
165 bFirst = false;
166 else
167 m_stream << ",";
168
169 RenderValue( it.next() );
170 }
171
172 m_stream << "]";
173}
174
176//
178
179void JSONSerializer::RenderStringList( const QStringList &list )
180{
181 bool bFirst = true;
182
183 m_stream << "[";
184
185 QListIterator< QString > it( list );
186
187 while (it.hasNext())
188 {
189 if (bFirst)
190 bFirst = false;
191 else
192 m_stream << ",";
193
194 m_stream << "\"" << Encode( it.next() ) << "\"";
195 }
196
197 m_stream << "]";
198}
199
201//
203
204void JSONSerializer::RenderMap( const QVariantMap &map )
205{
206 bool bFirst = true;
207
208 m_stream << "{";
209
210 QMapIterator< QString, QVariant > it( map );
211
212 while (it.hasNext())
213 {
214 it.next();
215
216 if (bFirst)
217 bFirst = false;
218 else
219 m_stream << ",";
220
221 m_stream << "\"" << it.key() << "\":";
222 m_stream << "\"" << Encode( it.value().toString() ) << "\"";
223 }
224
225 m_stream << "}";
226}
227
229//
231
232QString JSONSerializer::Encode(const QString &sIn)
233{
234 if (sIn.isEmpty())
235 return sIn;
236
237 QString sStr = sIn;
238
239 sStr.replace( '\\', "\\\\" ); // This must be first
240 sStr.replace( '"' , "\\\"" );
241 sStr.replace( '\b', "\\b" ); // ^H (\u0008)
242 sStr.replace( '\f', "\\f" ); // ^L (\u000C)
243 sStr.replace( '\n', "\\n" ); // ^J (\u000A)
244 sStr.replace( "\r", "\\r" ); // ^M (\u000D)
245 sStr.replace( "\t", "\\t" ); // ^I (\u0009)
246 sStr.replace( "/", "\\/" );
247
248 // Escape remaining chars from \u0000 - \u001F
249 // Details at https://en.wikipedia.org/wiki/C0_and_C1_control_codes
250 sStr.replace(QChar('\u0000'), "\\u0000"); // ^@ NULL
251 sStr.replace(QChar('\u0001'), "\\u0001"); // ^A
252 sStr.replace(QChar('\u0002'), "\\u0002"); // ^B
253 sStr.replace(QChar('\u0003'), "\\u0003"); // ^C
254 sStr.replace(QChar('\u0004'), "\\u0004"); // ^D
255 sStr.replace(QChar('\u0005'), "\\u0005"); // ^E
256 sStr.replace(QChar('\u0006'), "\\u0006"); // ^F
257 sStr.replace(QChar('\u0007'), "\\u0007"); // ^G (\a)
258 sStr.replace(QChar('\u000B'), "\\u000B"); // ^K (\v)
259 sStr.replace(QChar('\u000E'), "\\u000E"); // ^N
260 sStr.replace(QChar('\u000F'), "\\u000F"); // ^O
261 sStr.replace(QChar('\u0010'), "\\u0010"); // ^P
262 sStr.replace(QChar('\u0011'), "\\u0011"); // ^Q XON
263 sStr.replace(QChar('\u0012'), "\\u0012"); // ^R
264 sStr.replace(QChar('\u0013'), "\\u0013"); // ^S XOFF
265 sStr.replace(QChar('\u0014'), "\\u0014"); // ^T
266 sStr.replace(QChar('\u0015'), "\\u0015"); // ^U
267 sStr.replace(QChar('\u0016'), "\\u0016"); // ^V
268 sStr.replace(QChar('\u0017'), "\\u0017"); // ^W
269 sStr.replace(QChar('\u0018'), "\\u0018"); // ^X
270 sStr.replace(QChar('\u0019'), "\\u0019"); // ^Y
271 sStr.replace(QChar('\u001A'), "\\u001A"); // ^Z
272 sStr.replace(QChar('\u001B'), "\\u001B");
273 sStr.replace(QChar('\u001C'), "\\u001C");
274 sStr.replace(QChar('\u001D'), "\\u001D");
275 sStr.replace(QChar('\u001E'), "\\u001E");
276 sStr.replace(QChar('\u001F'), "\\u001F");
277
278 return sStr;
279}
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