qprotobufjsonserializer.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. /*
  2. * MIT License
  3. *
  4. * Copyright (c) 2020 Alexey Edelev <semlanik@gmail.com>
  5. *
  6. * This file is part of QtProtobuf project https://git.semlanik.org/semlanik/qtprotobuf
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy of this
  9. * software and associated documentation files (the "Software"), to deal in the Software
  10. * without restriction, including without limitation the rights to use, copy, modify,
  11. * merge, publish, distribute, sublicense, and/or sell copies of the Software, and
  12. * to permit persons to whom the Software is furnished to do so, subject to the following
  13. * conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in all copies
  16. * or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  19. * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  20. * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
  21. * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  22. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  23. * DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "qprotobufjsonserializer.h"
  26. #include "qprotobufmetaobject.h"
  27. #include "qprotobufmetaproperty.h"
  28. #include "qtprotobuflogging.h"
  29. #include <microjson.h>
  30. #include <QMetaProperty>
  31. using namespace QtProtobuf;
  32. namespace QtProtobuf {
  33. //! \private
  34. class QProtobufJsonSerializerPrivate final
  35. {
  36. Q_DISABLE_COPY_MOVE(QProtobufJsonSerializerPrivate)
  37. public:
  38. using Serializer = std::function<QByteArray(const QVariant&)>;
  39. using Deserializer = std::function<QVariant(QByteArray, microjson::JsonType, bool &)>;
  40. struct SerializationHandlers {
  41. Serializer serializer; /*!< serializer assigned to class */
  42. Deserializer deserializer;/*!< deserializer assigned to class */
  43. };
  44. using SerializerRegistry = std::unordered_map<int/*metatypeid*/, SerializationHandlers>;
  45. static QByteArray serializeFloat(const QVariant &propertyValue) {
  46. bool ok = false;
  47. float value = propertyValue.toFloat(&ok);
  48. if (!ok) {
  49. return QByteArray("NaN");
  50. }
  51. return QString::number(static_cast<double>(value), 'g').toUtf8();
  52. }
  53. static QByteArray serializeString(const QVariant &propertyValue) {
  54. return QString("\"%1\"").arg(propertyValue.toString()).toUtf8() ;
  55. }
  56. static QByteArray serializeBytes(const QVariant &propertyValue) {
  57. return QByteArray("\"") + propertyValue.toByteArray().toBase64() + "\"";
  58. }
  59. template<typename L>
  60. static QByteArray serializeList(const QVariant &propertyValue) {
  61. L listValue = propertyValue.value<L>();
  62. QByteArray result("[");
  63. for (auto value : listValue) {
  64. result += QString::number(value).toUtf8() + ",";
  65. }
  66. if (listValue.size() > 0) {
  67. result.resize(result.size() - 1);//Remove trailing `,`
  68. }
  69. result += "]";
  70. return result;
  71. }
  72. static QByteArray serializeDoubleList(const QVariant &propertyValue) {
  73. DoubleList listValue = propertyValue.value<DoubleList>();
  74. QByteArray result("[");
  75. for (auto value : listValue) {
  76. result += QString::number(value, 'g').toUtf8() + ",";
  77. }
  78. if (listValue.size() > 0) {
  79. result.resize(result.size() - 1);//Remove trailing `,`
  80. }
  81. result += "]";
  82. return result;
  83. }
  84. static QByteArray serializeStringList(const QVariant &propertyValue) {
  85. QStringList listValue = propertyValue.value<QStringList>();
  86. QByteArray result("[");
  87. for (auto value : listValue) {
  88. result += QByteArray("\"") + value.toUtf8() + "\",";
  89. }
  90. if (listValue.size() > 0) {
  91. result.resize(result.size() - 1);//Remove trailing `,`
  92. }
  93. result += "]";
  94. return result;
  95. }
  96. static QByteArray serializeBytesList(const QVariant &propertyValue) {
  97. QByteArrayList listValue = propertyValue.value<QByteArrayList>();
  98. QByteArray result("[");
  99. for (auto value : listValue) {
  100. result += QByteArray("\"") + value.toBase64() + "\",";
  101. }
  102. if (listValue.size() > 0) {
  103. result.resize(result.size() - 1);//Remove trailing `,`
  104. }
  105. result += "]";
  106. return result;
  107. }
  108. QProtobufJsonSerializerPrivate(QProtobufJsonSerializer *q) : qPtr(q) {
  109. if (handlers.empty()) {
  110. handlers[qMetaTypeId<QtProtobuf::int32>()] = {{}, QProtobufJsonSerializerPrivate::deserializeInt32};
  111. handlers[qMetaTypeId<QtProtobuf::sfixed32>()] = {{}, QProtobufJsonSerializerPrivate::deserializeInt32};
  112. handlers[qMetaTypeId<QtProtobuf::sint32>()] = {{}, QProtobufJsonSerializerPrivate::deserializeInt32};
  113. handlers[qMetaTypeId<QtProtobuf::sint64>()] = {{}, QProtobufJsonSerializerPrivate::deserializeInt64};
  114. handlers[qMetaTypeId<QtProtobuf::int64>()] = {{}, QProtobufJsonSerializerPrivate::deserializeInt64};
  115. handlers[qMetaTypeId<QtProtobuf::sfixed64>()] = {{}, QProtobufJsonSerializerPrivate::deserializeInt64};
  116. handlers[qMetaTypeId<QtProtobuf::uint32>()] = {{}, QProtobufJsonSerializerPrivate::deserializeUInt32};
  117. handlers[qMetaTypeId<QtProtobuf::fixed32>()] = {{}, QProtobufJsonSerializerPrivate::deserializeUInt32};
  118. handlers[qMetaTypeId<QtProtobuf::uint64>()] = {{}, QProtobufJsonSerializerPrivate::deserializeUInt64};
  119. handlers[qMetaTypeId<QtProtobuf::fixed64>()] = {{}, QProtobufJsonSerializerPrivate::deserializeUInt64};
  120. handlers[qMetaTypeId<bool>()] = {{}, QProtobufJsonSerializerPrivate::deserializeBool};
  121. handlers[QMetaType::Float] = {QProtobufJsonSerializerPrivate::serializeFloat, QProtobufJsonSerializerPrivate::deserializeFloat};
  122. handlers[QMetaType::Double] = {{}, QProtobufJsonSerializerPrivate::deserializeDouble};
  123. handlers[QMetaType::QString] = {QProtobufJsonSerializerPrivate::serializeString, QProtobufJsonSerializerPrivate::deserializeString};
  124. handlers[QMetaType::QByteArray] = {QProtobufJsonSerializerPrivate::serializeBytes, QProtobufJsonSerializerPrivate::deserializeByteArray};
  125. handlers[qMetaTypeId<QtProtobuf::int32List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::int32List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::int32>};
  126. handlers[qMetaTypeId<QtProtobuf::int64List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::int64List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::int64>};
  127. handlers[qMetaTypeId<QtProtobuf::sint32List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sint32List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sint32>};
  128. handlers[qMetaTypeId<QtProtobuf::sint64List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sint64List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sint64>};
  129. handlers[qMetaTypeId<QtProtobuf::uint32List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::uint32List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::uint32>};
  130. handlers[qMetaTypeId<QtProtobuf::uint64List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::uint64List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::uint64>};
  131. handlers[qMetaTypeId<QtProtobuf::fixed32List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::fixed32List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::fixed32>};
  132. handlers[qMetaTypeId<QtProtobuf::fixed64List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::fixed64List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::fixed64>};
  133. handlers[qMetaTypeId<QtProtobuf::sfixed32List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sfixed32List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sfixed32>};
  134. handlers[qMetaTypeId<QtProtobuf::sfixed64List>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::sfixed64List>, QProtobufJsonSerializerPrivate::deserializeList<QtProtobuf::sfixed64>};
  135. handlers[qMetaTypeId<QtProtobuf::FloatList>()] = {QProtobufJsonSerializerPrivate::serializeList<QtProtobuf::FloatList>, QProtobufJsonSerializerPrivate::deserializeList<float>};
  136. handlers[qMetaTypeId<QtProtobuf::DoubleList>()] = {QProtobufJsonSerializerPrivate::serializeDoubleList, QProtobufJsonSerializerPrivate::deserializeList<double>};
  137. handlers[qMetaTypeId<QStringList>()] = {QProtobufJsonSerializerPrivate::serializeStringList, QProtobufJsonSerializerPrivate::deserializeStringList};
  138. handlers[qMetaTypeId<QByteArrayList>()] = {QProtobufJsonSerializerPrivate::serializeBytesList, QProtobufJsonSerializerPrivate::deserializeList<QByteArray>};
  139. }
  140. }
  141. ~QProtobufJsonSerializerPrivate() = default;
  142. QByteArray serializeValue(const QVariant &propertyValue, const QProtobufMetaProperty &metaProperty) {
  143. QByteArray buffer;
  144. auto userType = propertyValue.userType();
  145. auto value = QtProtobufPrivate::findHandler(userType);
  146. if (value.serializer) {
  147. value.serializer(qPtr, propertyValue, metaProperty, buffer);
  148. } else {
  149. auto handler = handlers.find(userType);
  150. if (handler != handlers.end() && handler->second.serializer) {
  151. buffer += handler->second.serializer(propertyValue);
  152. } else {
  153. buffer += propertyValue.toString().toUtf8();
  154. }
  155. }
  156. return buffer;
  157. }
  158. QByteArray serializeProperty(const QVariant &propertyValue, const QProtobufMetaProperty &metaProperty) {
  159. return QByteArray("\"") + metaProperty.jsonPropertyName().toUtf8() + "\":" + serializeValue(propertyValue, metaProperty);
  160. }
  161. QByteArray serializeObject(const QObject *object, const QProtobufMetaObject &metaObject) {
  162. QByteArray result = "{";
  163. for (const auto &field : metaObject.propertyOrdering) {
  164. int propertyIndex = field.second;
  165. int fieldIndex = field.first;
  166. Q_ASSERT_X(fieldIndex < 536870912 && fieldIndex > 0, "", "fieldIndex is out of range");
  167. QMetaProperty metaProperty = metaObject.staticMetaObject.property(propertyIndex);
  168. const char *propertyName = metaProperty.name();
  169. const QVariant &propertyValue = object->property(propertyName);
  170. result.append(serializeProperty(propertyValue, QProtobufMetaProperty(metaProperty,
  171. fieldIndex,
  172. field.second)));
  173. result.append(",");
  174. }
  175. result.resize(result.size() - 1);//Remove trailing `,`
  176. result.append("}");
  177. return result;
  178. }
  179. static QVariant deserializeInt32(const QByteArray &data, microjson::JsonType type, bool &ok) {
  180. auto val = data.toInt(&ok);
  181. ok |= type == microjson::JsonNumberType;
  182. return QVariant::fromValue(val);
  183. }
  184. static QVariant deserializeUInt32(const QByteArray &data, microjson::JsonType type, bool &ok) {
  185. auto val = data.toUInt(&ok);
  186. ok |= type == microjson::JsonNumberType;
  187. return QVariant::fromValue(val);
  188. }
  189. static QVariant deserializeInt64(const QByteArray &data, microjson::JsonType type, bool &ok) {
  190. auto val = data.toLongLong(&ok);
  191. ok |= type == microjson::JsonNumberType;
  192. return QVariant::fromValue(val);
  193. }
  194. static QVariant deserializeUInt64(const QByteArray &data, microjson::JsonType type, bool &ok) {
  195. auto val = data.toULongLong(&ok);
  196. ok |= type == microjson::JsonNumberType;
  197. return QVariant::fromValue(val);
  198. }
  199. static QVariant deserializeFloat(const QByteArray &data, microjson::JsonType type, bool &ok) {
  200. if (data == "NaN" || data == "Infinity" || data == "-Infinity") {
  201. ok = true;
  202. return QVariant();
  203. }
  204. auto val = data.toFloat(&ok);
  205. ok |= type == microjson::JsonNumberType;
  206. return QVariant::fromValue(val);
  207. }
  208. static QVariant deserializeDouble(const QByteArray &data, microjson::JsonType type, bool &ok) {
  209. if (data == "NaN" || data == "Infinity" || data == "-Infinity") {
  210. ok = true;
  211. return QVariant();
  212. }
  213. auto val = data.toDouble(&ok);
  214. ok |= type == microjson::JsonNumberType;
  215. return QVariant::fromValue(val);
  216. }
  217. static QVariant deserializeBool(const QByteArray &data, microjson::JsonType type, bool &ok) {
  218. if (type == microjson::JsonBoolType) {
  219. ok = true;
  220. return QVariant::fromValue(data == "true");
  221. }
  222. ok = false;
  223. return QVariant();
  224. }
  225. static QVariant deserializeString(const QByteArray &data, microjson::JsonType type, bool &ok) {
  226. if (type == microjson::JsonStringType) {
  227. ok = true;
  228. return QVariant::fromValue(QString::fromUtf8(data).replace("\\\"", "\""));
  229. }
  230. ok = false;
  231. return QVariant();
  232. }
  233. static QVariant deserializeByteArray(const QByteArray &data, microjson::JsonType type, bool &ok) {
  234. if (type == microjson::JsonStringType) {
  235. ok = true;
  236. return QVariant::fromValue(QByteArray::fromBase64(data));
  237. }
  238. ok = false;
  239. return QVariant();
  240. }
  241. template<typename T>
  242. static QVariant deserializeList(const QByteArray &data, microjson::JsonType type, bool &ok) {
  243. if (type != microjson::JsonArrayType) {
  244. ok = false;
  245. return QVariant();
  246. }
  247. ok = true;
  248. QList<T> list;
  249. auto arrayValues = microjson::parseJsonArray(data.data(), static_cast<size_t>(data.size()));
  250. auto handler = handlers.find(qMetaTypeId<T>());
  251. if (handler == handlers.end() || !handler->second.deserializer) {
  252. qProtoWarning() << "Unable to deserialize simple type list. Could not find desrializer for type" << qMetaTypeId<T>();
  253. return QVariant::fromValue(list);
  254. }
  255. for (auto &arrayValue : arrayValues) {
  256. bool valueOk = false;
  257. QVariant newValue = handler->second.deserializer(QByteArray::fromStdString(arrayValue.value), arrayValue.type, valueOk);
  258. list.append(newValue.value<T>());
  259. }
  260. return QVariant::fromValue(list);
  261. }
  262. static QVariant deserializeStringList(const QByteArray &data, microjson::JsonType type, bool &ok) {
  263. if (type != microjson::JsonArrayType) {
  264. ok = false;
  265. return QVariant();
  266. }
  267. ok = true;
  268. QStringList list;
  269. auto arrayValues = microjson::parseJsonArray(data.data(), static_cast<size_t>(data.size()));
  270. for (auto &arrayValue : arrayValues) {
  271. bool valueOk = false;
  272. QVariant newValue = deserializeString(QByteArray::fromStdString(arrayValue.value), arrayValue.type, valueOk);
  273. list.append(newValue.value<QString>());
  274. }
  275. return QVariant::fromValue(list);
  276. }
  277. QVariant deserializeValue(int type, const QByteArray &data, microjson::JsonType jsonType, bool &ok) {
  278. QVariant newValue;
  279. auto handler = QtProtobufPrivate::findHandler(type);
  280. if (handler.deserializer) {
  281. QtProtobuf::QProtobufSelfcheckIterator it(data);
  282. QtProtobuf::QProtobufSelfcheckIterator last = it;
  283. last += it.size();
  284. while (it != last) {
  285. ok = true;
  286. handler.deserializer(qPtr, it, newValue);
  287. qDebug() << "newValue" << newValue;
  288. }
  289. } else {
  290. auto handler = handlers.find(type);
  291. if (handler != handlers.end() && handler->second.deserializer) {
  292. newValue = handler->second.deserializer(data, jsonType, ok);
  293. }
  294. }
  295. return newValue;
  296. }
  297. void deserializeObject(QObject *object, const QProtobufMetaObject &metaObject, const char *data, int size) {
  298. microjson::JsonObject obj = microjson::parseJsonObject(data, static_cast<size_t>(size));
  299. for (auto &property : obj) {
  300. auto name = property.first;
  301. auto it = std::find_if(metaObject.propertyOrdering.begin(),
  302. metaObject.propertyOrdering.end(),
  303. [&name](const auto &val)->bool {
  304. return val.second == QString::fromStdString(name);
  305. });
  306. if (it != metaObject.propertyOrdering.end()) {
  307. QMetaProperty metaProperty = metaObject.staticMetaObject.property(it->second);
  308. auto userType = metaProperty.userType();
  309. QByteArray rawValue = QByteArray::fromStdString(property.second.value);
  310. if (rawValue == "null" && property.second.type == microjson::JsonObjectType) {
  311. metaProperty.write(object, QVariant());
  312. continue;
  313. }
  314. bool ok = false;
  315. QVariant value = deserializeValue(userType, rawValue, property.second.type, ok);
  316. if (ok) {
  317. metaProperty.write(object, value);
  318. }
  319. }
  320. }
  321. }
  322. private:
  323. static SerializerRegistry handlers;
  324. QProtobufJsonSerializer *qPtr;
  325. };
  326. QProtobufJsonSerializerPrivate::SerializerRegistry QProtobufJsonSerializerPrivate::handlers = {};
  327. }
  328. QProtobufJsonSerializer::QProtobufJsonSerializer() : dPtr(new QProtobufJsonSerializerPrivate(this))
  329. {
  330. }
  331. QProtobufJsonSerializer::~QProtobufJsonSerializer() = default;
  332. QByteArray QProtobufJsonSerializer::serializeMessage(const QObject *object, const QProtobufMetaObject &metaObject) const
  333. {
  334. return dPtr->serializeObject(object, metaObject);
  335. }
  336. void QProtobufJsonSerializer::deserializeMessage(QObject *object, const QProtobufMetaObject &metaObject, const QByteArray &data) const
  337. {
  338. dPtr->deserializeObject(object, metaObject, data.data(), data.size());
  339. }
  340. QByteArray QProtobufJsonSerializer::serializeObject(const QObject *object, const QProtobufMetaObject &metaObject, const QProtobufMetaProperty &/*metaProperty*/) const
  341. {
  342. return dPtr->serializeObject(object, metaObject);
  343. }
  344. void QProtobufJsonSerializer::deserializeObject(QObject *object, const QProtobufMetaObject &metaObject, QProtobufSelfcheckIterator &it) const
  345. {
  346. dPtr->deserializeObject(object, metaObject, it.data(), it.size());
  347. it += it.size();
  348. }
  349. QByteArray QProtobufJsonSerializer::serializeListBegin(const QProtobufMetaProperty &/*metaProperty*/) const
  350. {
  351. return {"["};
  352. }
  353. QByteArray QProtobufJsonSerializer::serializeListObject(const QObject *object, const QProtobufMetaObject &metaObject, const QProtobufMetaProperty &/*metaProperty*/) const
  354. {
  355. return dPtr->serializeObject(object, metaObject) + ",";
  356. }
  357. QByteArray QProtobufJsonSerializer::serializeListEnd(QByteArray &buffer, const QProtobufMetaProperty &/*metaProperty*/) const
  358. {
  359. if (buffer[buffer.size() - 1] == ',') {
  360. buffer.resize(buffer.size() - 1);
  361. }
  362. return {"]"};
  363. }
  364. bool QProtobufJsonSerializer::deserializeListObject(QObject *object, const QProtobufMetaObject &metaObject, QProtobufSelfcheckIterator &it) const
  365. {
  366. if (*it == '[') {
  367. qDebug() << "Begin of list";
  368. ++it;
  369. }
  370. size_t i = 0;
  371. microjson::JsonProperty property;
  372. if (microjson::extractValue(it.data(), static_cast<size_t>(it.size()), i, ']', property)) {
  373. dPtr->deserializeObject(object, metaObject, it.data() + property.valueBegin, property.valueSize());
  374. } else {
  375. it += it.size();
  376. return false;
  377. }
  378. it += i;
  379. return true;
  380. }
  381. QByteArray QProtobufJsonSerializer::serializeMapBegin(const QProtobufMetaProperty &/*metaProperty*/) const
  382. {
  383. return {"{"};
  384. }
  385. QByteArray QProtobufJsonSerializer::serializeMapPair(const QVariant &key, const QVariant &value, const QProtobufMetaProperty &metaProperty) const
  386. {
  387. return QByteArray("\"") + key.toString().toUtf8() + "\":" + dPtr->serializeValue(value, metaProperty) + ",";
  388. }
  389. QByteArray QProtobufJsonSerializer::serializeMapEnd(QByteArray &buffer, const QProtobufMetaProperty &/*metaProperty*/) const
  390. {
  391. if (buffer[buffer.size() - 1] == ',') {
  392. buffer.resize(buffer.size() - 1);
  393. }
  394. return {"}"};
  395. }
  396. bool QProtobufJsonSerializer::deserializeMapPair(QVariant &key, QVariant &value, QProtobufSelfcheckIterator &it) const
  397. {
  398. if (*it == '{') {
  399. qDebug() << "Begin of map";
  400. ++it;
  401. }
  402. size_t i = 0;
  403. microjson::JsonProperty property;
  404. if (microjson::extractProperty(it.data(), static_cast<size_t>(it.size()), i, '}', property)) {
  405. bool ok = false;
  406. key = dPtr->deserializeValue(key.userType(), QByteArray(it.data() + property.nameBegin, property.nameSize()), microjson::JsonStringType, ok);
  407. if (!ok) {
  408. key = QVariant();
  409. }
  410. value = dPtr->deserializeValue(value.userType(), QByteArray(it.data() + property.valueBegin, property.valueSize()), property.type, ok);
  411. if (!ok) {
  412. value = QVariant();
  413. }
  414. } else {
  415. it += it.size();
  416. return false;
  417. }
  418. it += i;
  419. return true;
  420. }
  421. QByteArray QProtobufJsonSerializer::serializeEnum(int64 value, const QMetaEnum &metaEnum, const QtProtobuf::QProtobufMetaProperty &/*metaProperty*/) const
  422. {
  423. return QByteArray("\"") + metaEnum.key(static_cast<int>(value)) + "\"";
  424. }
  425. QByteArray QProtobufJsonSerializer::serializeEnumList(const QList<int64> &values, const QMetaEnum &metaEnum, const QtProtobuf::QProtobufMetaProperty &/*metaProperty*/) const
  426. {
  427. QByteArray result = "[";
  428. for (auto value : values) {
  429. result.append("\"");
  430. result.append(metaEnum.key(static_cast<int>(value)));
  431. result.append("\",");
  432. }
  433. if (values.size() > 0) {
  434. result.resize(result.size() - 1);
  435. }
  436. result.append("]");
  437. return result;
  438. }
  439. void QProtobufJsonSerializer::deserializeEnum(int64 &value, const QMetaEnum &metaEnum, QProtobufSelfcheckIterator &it) const
  440. {
  441. value = metaEnum.keyToValue(it.data());
  442. it += it.size();
  443. }
  444. void QProtobufJsonSerializer::deserializeEnumList(QList<int64> &value, const QMetaEnum &metaEnum, QProtobufSelfcheckIterator &it) const
  445. {
  446. auto arrayValues = microjson::parseJsonArray(it.data(), static_cast<size_t>(it.size()));
  447. for (auto &arrayValue : arrayValues) {
  448. if (arrayValue.value == "null") {
  449. value.append(metaEnum.value(0));
  450. } else {
  451. value.append(metaEnum.keyToValue(arrayValue.value.c_str()));
  452. }
  453. }
  454. it += it.size();
  455. }