MythTV  master
jsonSerializer.cpp
Go to the documentation of this file.
1 // 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 COPYING for details
10 //
12 
13 #include "jsonSerializer.h"
14 #include "mythdate.h"
15 
16 #include <QTextCodec>
17 #include <QVariant>
18 
20 //
22 
24 {
25  return "application/json";
26 }
27 
28 
30 //
32 
33 void JSONSerializer::BeginSerialize( QString &/*sName*/ )
34 {
35  m_bCommaNeeded = false;
36 
37  m_Stream << "{";
38 }
39 
41 //
43 
45 {
46  m_bCommaNeeded = false;
47 
48  m_Stream << "}";
49 
50  m_Stream.flush();
51 }
52 
53 
55 //
57 
58 void JSONSerializer::BeginObject( const QString &sName, const QObject */*pObject*/ )
59 {
60  m_bCommaNeeded = false;
61 
62  m_Stream << "\"" << sName << "\": {";
63 }
64 
66 //
68 
69 void JSONSerializer::EndObject ( const QString &/*sName*/, const QObject */*pObject*/ )
70 {
71  m_bCommaNeeded = false;
72 
73  m_Stream << "}";
74 }
75 
77 //
79 
80 void JSONSerializer::AddProperty( const QString &sName,
81  const QVariant &vValue,
82  const QMetaObject */*pMetaParent*/,
83  const QMetaProperty */*pMetaProp*/ )
84 {
85  if (m_bCommaNeeded)
86  m_Stream << ", ";
87 
88  m_Stream << "\"" << sName << "\": ";
89 
90  RenderValue( vValue );
91 
92  m_bCommaNeeded = true;
93 }
94 
96 //
98 
99 void JSONSerializer::RenderValue( const QVariant &vValue )
100 {
101 
102  // -----------------------------------------------------------------------
103  // See if this value is actually a child object
104  // -----------------------------------------------------------------------
105 
106  if ( vValue.canConvert< QObject* >())
107  {
108  const QObject *pObject = vValue.value< QObject* >();
109 
110  bool bSavedCommaNeeded = m_bCommaNeeded;
111  m_bCommaNeeded = false;
112 
113  m_Stream << "{";
114  SerializeObjectProperties( pObject );
115  m_Stream << "}";
116 
117  m_bCommaNeeded = bSavedCommaNeeded;
118 
119  return;
120  }
121 
122  // -----------------------------------------------------------------------
123  // Handle QVariant special cases...
124  // -----------------------------------------------------------------------
125 
126  switch( vValue.type() )
127  {
128  case QVariant::List: RenderList ( vValue.toList() ); break;
129  case QVariant::StringList: RenderStringList( vValue.toStringList() ); break;
130  case QVariant::Map: RenderMap ( vValue.toMap() ); break;
131  case QVariant::DateTime:
132  {
133  m_Stream << "\"" << Encode(
134  MythDate::toString( vValue.toDateTime(), MythDate::ISODate ) )
135  << "\"";
136  break;
137  }
138  default:
139  {
140  m_Stream << "\"" << Encode( vValue.toString() ) << "\"";
141  break;
142  }
143  }
144 }
145 
147 //
149 
150 void JSONSerializer::RenderList( const QVariantList &list )
151 {
152  bool bFirst = true;
153 
154  m_Stream << "[";
155 
156  QListIterator< QVariant > it( list );
157 
158  while (it.hasNext())
159  {
160  if (bFirst)
161  bFirst = false;
162  else
163  m_Stream << ",";
164 
165  RenderValue( it.next() );
166  }
167 
168  m_Stream << "]";
169 }
170 
172 //
174 
175 void JSONSerializer::RenderStringList( const QStringList &list )
176 {
177  bool bFirst = true;
178 
179  m_Stream << "[";
180 
181  QListIterator< QString > it( list );
182 
183  while (it.hasNext())
184  {
185  if (bFirst)
186  bFirst = false;
187  else
188  m_Stream << ",";
189 
190  m_Stream << "\"" << Encode( it.next() ) << "\"";
191  }
192 
193  m_Stream << "]";
194 }
195 
197 //
199 
200 void JSONSerializer::RenderMap( const QVariantMap &map )
201 {
202  bool bFirst = true;
203 
204  m_Stream << "{";
205 
206  QMapIterator< QString, QVariant > it( map );
207 
208  while (it.hasNext())
209  {
210  it.next();
211 
212  if (bFirst)
213  bFirst = false;
214  else
215  m_Stream << ",";
216 
217  m_Stream << "\"" << it.key() << "\":";
218  m_Stream << "\"" << Encode( it.value().toString() ) << "\"";
219  }
220 
221  m_Stream << "}";
222 }
223 
225 //
227 
228 QString JSONSerializer::Encode(const QString &sIn)
229 {
230  if (sIn.isEmpty())
231  return sIn;
232 
233  QString sStr = sIn;
234 
235  // -=>TODO: Would it be better to just loop through string once and build
236  // new string with encoded chars instead of calling replace multiple times?
237  // It might perform better.
238 
239  sStr.replace( '\\', "\\\\" ); // This must be first
240  sStr.replace( '"' , "\\\"" );
241 
242  sStr.replace( '\b', "\\b" );
243  sStr.replace( '\f', "\\f" );
244  sStr.replace( '\n', "\\n" );
245  sStr.replace( "\r", "\\r" );
246  sStr.replace( "\t", "\\t" );
247  sStr.replace( "/", "\\/" );
248 
249  // we don't handle hex values yet...
250  /*
251  if(ch>='\u0000' && ch<='\u001F')
252  sb.append("\\u####");
253  */
254  return sStr;
255 }
void EndObject(const QString &sName, const QObject *pObject) override
void SerializeObjectProperties(const QObject *pObject)
Definition: serializer.cpp:103
QString GetContentType() override
void BeginSerialize(QString &sName) override
void RenderMap(const QVariantMap &map)
void BeginObject(const QString &sName, const QObject *pObject) override
QTextStream m_Stream
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:101
void RenderValue(const QVariant &vValue)
void EndSerialize() override
void AddProperty(const QString &sName, const QVariant &vValue, const QMetaObject *pMetaParent, const QMetaProperty *pMetaProp) override
void RenderStringList(const QStringList &list)
QString Encode(const QString &sIn)
void RenderList(const QVariantList &list)
Default UTC.
Definition: mythdate.h:14