MythTV  master
xmlplistSerializer.cpp
Go to the documentation of this file.
1 /* Class XmlPListSerializer
2 *
3 * Copyright (C) Mark Kendall 2012
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19 
20 #include <QMetaClassInfo>
21 #include <QDateTime>
22 
23 #include "xmlplistSerializer.h"
24 
25 #define XMLPLIST_SERIALIZER_VERSION "1.0"
26 
27 void XmlPListSerializer::BeginSerialize(QString &/*sName*/)
28 {
29  m_pXmlWriter->setAutoFormatting(true);
30  m_pXmlWriter->setAutoFormattingIndent(4);
31  m_pXmlWriter->writeStartDocument("1.0");
32  m_pXmlWriter->writeDTD("<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">");
33  m_pXmlWriter->writeStartElement("plist");
34  m_pXmlWriter->writeAttribute("version", "1.0");
35  m_pXmlWriter->writeStartElement("dict"); // top level node
36 }
37 
39 {
40  m_pXmlWriter->writeEndElement(); // "dict"
41  m_pXmlWriter->writeEndElement(); // "plist"
42  m_pXmlWriter->writeEndDocument();
43 }
44 
46 {
47  return "text/x-apple-plist+xml";
48 }
49 
50 void XmlPListSerializer::RenderValue(const QString &sName,
51  const QVariant &vValue,
52  bool needKey)
53 {
54  if ( vValue.canConvert<QObject*>())
55  {
56  const QObject *pObject = vValue.value<QObject*>();
57  SerializePListObjectProperties(sName, pObject, needKey);
58  return;
59  }
60 
61  switch(vValue.type())
62  {
63  case QVariant::List:
64  {
65  RenderList(sName, vValue.toList());
66  break;
67  }
68 
69  case QVariant::StringList:
70  {
71  RenderStringList(sName, vValue.toStringList());
72  break;
73  }
74 
75  case QVariant::Map:
76  {
77  RenderMap(sName, vValue.toMap());
78  break;
79  }
80 
81  case QVariant::DateTime:
82  {
83  if (vValue.toDateTime().isValid())
84  {
85  if (needKey)
86  m_pXmlWriter->writeTextElement("key", sName);
87  m_pXmlWriter->writeTextElement("date", vValue.toDateTime()
88  .toUTC().toString("yyyy-MM-ddThh:mm:ssZ"));
89  }
90  break;
91  }
92 
93  case QVariant::ByteArray:
94  {
95  if (!vValue.toByteArray().isNull())
96  {
97  if (needKey)
98  m_pXmlWriter->writeTextElement("key", sName);
99  m_pXmlWriter->writeTextElement("data",
100  vValue.toByteArray().toBase64().data());
101  }
102  break;
103  }
104 
105  case QVariant::Bool:
106  {
107  if (needKey)
108  m_pXmlWriter->writeTextElement("key", sName);
109  m_pXmlWriter->writeEmptyElement(vValue.toBool() ?
110  "true" : "false");
111  break;
112  }
113 
114  case QVariant::UInt:
115  case QVariant::ULongLong:
116  {
117  if (needKey)
118  m_pXmlWriter->writeTextElement("key", sName);
119  m_pXmlWriter->writeTextElement("integer",
120  QString::number(vValue.toULongLong()));
121  break;
122  }
123 
124  case QVariant::Int:
125  case QVariant::LongLong:
126  case QVariant::Double:
127  {
128  if (needKey)
129  m_pXmlWriter->writeTextElement("key", sName);
130  m_pXmlWriter->writeTextElement("real",
131  QString("%1").arg(vValue.toDouble(), 0, 'f', 6));
132  break;
133  }
134 
135  // anything else will be unrecognised, so wrap in a string
136  case QVariant::String:
137  default:
138  {
139  if (needKey)
140  m_pXmlWriter->writeTextElement("key", sName);
141  m_pXmlWriter->writeTextElement("string", vValue.toString());
142  break;
143  }
144  }
145 }
146 
147 void XmlPListSerializer::RenderList(const QString &sName,
148  const QVariantList &list)
149 {
150  bool array = true;
151  if (!list.isEmpty())
152  {
153  QVariant::Type t = list[0].type();
154  QListIterator<QVariant> it(list);
155  while (it.hasNext())
156  {
157  if (it.next().type() != t)
158  {
159  array = false;
160  break;
161  }
162  }
163  }
164 
165  QString sItemName = GetItemName(sName);
166  m_pXmlWriter->writeTextElement("key", sName);
167  m_pXmlWriter->writeStartElement(array ? "array" : "dict");
168 
169  QListIterator<QVariant> it(list);
170  while (it.hasNext())
171  RenderValue(sItemName, it.next(), !array);
172 
173  m_pXmlWriter->writeEndElement();
174 }
175 
176 void XmlPListSerializer::RenderStringList(const QString &sName,
177  const QStringList &list)
178 {
179  m_pXmlWriter->writeTextElement("key", sName);
180  m_pXmlWriter->writeStartElement("array");
181 
182  QListIterator<QString> it(list);
183  while (it.hasNext())
184  m_pXmlWriter->writeTextElement("string", it.next());
185 
186  m_pXmlWriter->writeEndElement();
187 }
188 
189 void XmlPListSerializer::RenderMap(const QString &sName,
190  const QVariantMap &map)
191 {
192  QString sItemName = GetItemName(sName);
193  m_pXmlWriter->writeTextElement("key", sItemName);
194  m_pXmlWriter->writeStartElement("dict");
195 
196  QMapIterator<QString,QVariant> it(map);
197  while (it.hasNext())
198  {
199  it.next();
200  RenderValue(it.key(), it.value());
201  }
202 
203  m_pXmlWriter->writeEndElement();
204 }
205 
206 void XmlPListSerializer::BeginObject(const QString &sName,
207  const QObject *pObject)
208 {
209  const QMetaObject *pMeta = pObject->metaObject();
210 
211  int nIdx = -1;
212 
213  if (pMeta)
214  nIdx = pMeta->indexOfClassInfo("version");
215 
216  if (nIdx >=0)
217  {
218  m_pXmlWriter->writeTextElement("key", "version");
219  m_pXmlWriter->writeTextElement("string", pMeta->classInfo(nIdx).value());
220  }
221 
222  m_pXmlWriter->writeTextElement("key", "serializerversion");
223  m_pXmlWriter->writeTextElement("string", XMLPLIST_SERIALIZER_VERSION);
224 
225  m_pXmlWriter->writeTextElement("key", sName);
226  m_pXmlWriter->writeStartElement("dict");
227 }
228 
229 void XmlPListSerializer::EndObject(const QString &/*sName*/,
230  const QObject */*pObject*/)
231 {
232  m_pXmlWriter->writeEndElement(); // dict
233 }
234 
235 void XmlPListSerializer::AddProperty(const QString &sName,
236  const QVariant &vValue,
237  const QMetaObject */*pMetaParent*/,
238  const QMetaProperty */*pMetaProp*/)
239 {
240  RenderValue(sName, vValue);
241 }
242 
244  const QObject *pObject,
245  bool needKey )
246 {
247  if (!pObject)
248  return;
249 
250  if (needKey)
251  {
252  QString sItemName = GetItemName(sName);
253  m_pXmlWriter->writeTextElement("key", sItemName);
254  }
255  m_pXmlWriter->writeStartElement("dict");
256 
257  const QMetaObject *pMetaObject = pObject->metaObject();
258 
259  int nCount = pMetaObject->propertyCount();
260 
261  for (int nIdx=0; nIdx < nCount; ++nIdx)
262  {
263  QMetaProperty metaProperty = pMetaObject->property(nIdx);
264 
265  if (metaProperty.isDesignable(pObject))
266  {
267  const char *pszPropName = metaProperty.name();
268  QString sPropName(pszPropName);
269 
270  if (sPropName.compare("objectName") == 0)
271  continue;
272 
273  QVariant value(pObject->property(pszPropName));
274 
275  AddProperty(sPropName, value, pMetaObject, &metaProperty);
276  }
277  }
278 
279  m_pXmlWriter->writeEndElement();
280 }
void RenderList(const QString &sName, const QVariantList &list)
#define XMLPLIST_SERIALIZER_VERSION
void RenderStringList(const QString &sName, const QStringList &list)
void BeginSerialize(QString &sName) override
void RenderValue(const QString &sName, const QVariant &vValue, bool needKey=true)
void SerializePListObjectProperties(const QString &sName, const QObject *pObject, bool needKey)
void EndObject(const QString &sName, const QObject *pObject) override
void RenderMap(const QString &sName, const QVariantMap &map)
unsigned char t
Definition: ParseText.cpp:329
QXmlStreamWriter * m_pXmlWriter
Definition: xmlSerializer.h:37
QString GetContentType() override
void AddProperty(const QString &sName, const QVariant &vValue, const QMetaObject *pMetaParent, const QMetaProperty *pMetaProp) override
void EndSerialize() override
QString GetItemName(const QString &sName)
void BeginObject(const QString &sName, const QObject *pObject) override