qprotobufobject_p.cpp 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * MIT License
  3. *
  4. * Copyright (c) 2019 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 "qprotobufobject_p.h"
  26. using namespace qtprotobuf;
  27. ProtobufObjectPrivate::SerializerRegistry ProtobufObjectPrivate::serializers = {};
  28. void ProtobufObjectPrivate::registerSerializers()
  29. {
  30. wrapSerializer<float>(ProtobufObjectPrivate::serializeBasic<float>, ProtobufObjectPrivate::deserializeBasic<float>, Fixed32);
  31. wrapSerializer<double>(ProtobufObjectPrivate::serializeBasic<double>, ProtobufObjectPrivate::deserializeBasic<double>, Fixed64);
  32. wrapSerializer<int32>(ProtobufObjectPrivate::serializeBasic<int64>, ProtobufObjectPrivate::deserializeBasic<int64>, Varint);
  33. wrapSerializer<int64>(ProtobufObjectPrivate::serializeBasic<int64>, ProtobufObjectPrivate::deserializeBasic<int64>, Varint);
  34. wrapSerializer<uint32>(ProtobufObjectPrivate::serializeBasic<uint32>, ProtobufObjectPrivate::deserializeBasic<uint32>, Varint);
  35. wrapSerializer<uint64>(ProtobufObjectPrivate::serializeBasic<uint64>, ProtobufObjectPrivate::deserializeBasic<uint64>, Varint);
  36. wrapSerializer<sint32>(ProtobufObjectPrivate::serializeBasic<sint32>, ProtobufObjectPrivate::deserializeBasic<sint32>, Varint);
  37. wrapSerializer<sint64>(ProtobufObjectPrivate::serializeBasic<sint64>, ProtobufObjectPrivate::deserializeBasic<sint64>, Varint);
  38. wrapSerializer<fixed32>(ProtobufObjectPrivate::serializeBasic<fixed32>, ProtobufObjectPrivate::deserializeBasic<fixed32>, Fixed32);
  39. wrapSerializer<fixed64>(ProtobufObjectPrivate::serializeBasic<fixed64>, ProtobufObjectPrivate::deserializeBasic<fixed64>, Fixed64);
  40. wrapSerializer<sfixed32>(ProtobufObjectPrivate::serializeBasic<sfixed32>, ProtobufObjectPrivate::deserializeBasic<sfixed32>, Fixed32);
  41. wrapSerializer<sfixed64>(ProtobufObjectPrivate::serializeBasic<sfixed64>, ProtobufObjectPrivate::deserializeBasic<sfixed64>, Fixed64);
  42. wrapSerializer<bool>(ProtobufObjectPrivate::serializeBasic<uint32>, ProtobufObjectPrivate::deserializeBasic<uint32>, Varint);
  43. wrapSerializer<QString>([](const QString &data, int &/*fieldIndex*/) {
  44. return serializeLengthDelimited(data);
  45. }, [](QByteArray::const_iterator &it){
  46. return QVariant::fromValue(QString::fromUtf8(deserializeLengthDelimited(it)));
  47. }, LengthDelimited);
  48. wrapSerializer<QByteArray>([](const QByteArray &data, int &/*fieldIndex*/) {
  49. return serializeLengthDelimited(data);
  50. }, ProtobufObjectPrivate::deserializeLengthDelimited, LengthDelimited);
  51. wrapSerializer<FloatList>(ProtobufObjectPrivate::serializeListType<float>, ProtobufObjectPrivate::deserializeList<float>, LengthDelimited);
  52. wrapSerializer<DoubleList>(ProtobufObjectPrivate::serializeListType<double>, ProtobufObjectPrivate::deserializeList<double>, LengthDelimited);
  53. wrapSerializer<fixed32List>(ProtobufObjectPrivate::serializeListType<fixed32>, ProtobufObjectPrivate::deserializeList<fixed32>, LengthDelimited);
  54. wrapSerializer<fixed64List>(ProtobufObjectPrivate::serializeListType<fixed64>, ProtobufObjectPrivate::deserializeList<fixed64>, LengthDelimited);
  55. wrapSerializer<sfixed32List>(ProtobufObjectPrivate::serializeListType<sfixed32>, ProtobufObjectPrivate::deserializeList<sfixed32>, LengthDelimited);
  56. wrapSerializer<sfixed64List>(ProtobufObjectPrivate::serializeListType<sfixed64>, ProtobufObjectPrivate::deserializeList<sfixed64>, LengthDelimited);
  57. wrapSerializer<int32List>(ProtobufObjectPrivate::serializeListType<int32>, ProtobufObjectPrivate::deserializeList<int32>, LengthDelimited);
  58. wrapSerializer<int64List>(ProtobufObjectPrivate::serializeListType<int64>, ProtobufObjectPrivate::deserializeList<int64>, LengthDelimited);
  59. wrapSerializer<sint32List>(ProtobufObjectPrivate::serializeListType<sint32>, ProtobufObjectPrivate::deserializeList<sint32>, LengthDelimited);
  60. wrapSerializer<sint64List>(ProtobufObjectPrivate::serializeListType<sint64>, ProtobufObjectPrivate::deserializeList<sint64>, LengthDelimited);
  61. wrapSerializer<uint32List>(ProtobufObjectPrivate::serializeListType<uint32>, ProtobufObjectPrivate::deserializeList<uint32>, LengthDelimited);
  62. wrapSerializer<uint64List>(ProtobufObjectPrivate::serializeListType<uint64>, ProtobufObjectPrivate::deserializeList<uint64>, LengthDelimited);
  63. wrapSerializer<QStringList>(ProtobufObjectPrivate::serializeListType<QString>, ProtobufObjectPrivate::deserializeList<QString>, LengthDelimited);
  64. wrapSerializer<QByteArrayList>(ProtobufObjectPrivate::serializeListType<QByteArray>, ProtobufObjectPrivate::deserializeList<QByteArray>, LengthDelimited);
  65. }
  66. QByteArray ProtobufObjectPrivate::serializeValue(const QVariant &propertyValue, int fieldIndex, const QMetaProperty &metaProperty)
  67. {
  68. qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex
  69. << "typeName" << metaProperty.typeName() << static_cast<QMetaType::Type>(propertyValue.type());
  70. QByteArray result;
  71. WireTypes type = UnknownWireType;
  72. if (metaProperty.isEnumType()) {
  73. type = Varint;
  74. result.append(serializeBasic(propertyValue.toLongLong(), fieldIndex));
  75. } else {
  76. result.append(serializeUserType(propertyValue, fieldIndex, type));
  77. }
  78. if (fieldIndex != NotUsedFieldIndex
  79. && type != UnknownWireType) {
  80. result.prepend(encodeHeaderByte(fieldIndex, type));
  81. }
  82. return result;
  83. }
  84. QByteArray ProtobufObjectPrivate::serializeUserType(const QVariant &propertyValue, int &fieldIndex, WireTypes &type)
  85. {
  86. qProtoDebug() << __func__ << "propertyValue" << propertyValue << "fieldIndex" << fieldIndex;
  87. int userType = propertyValue.userType();
  88. auto serializer = serializers[userType].serializer;
  89. Q_ASSERT_X(serializer, "ProtobufObjectPrivate", "Serialization of unknown type is impossible. QtProtobuf::init() missed?");
  90. type = serializers[userType].type;
  91. return serializer(propertyValue, fieldIndex);
  92. }
  93. void ProtobufObjectPrivate::deserializeProperty(QObject *object, WireTypes wireType, const QMetaProperty &metaProperty, QByteArray::const_iterator &it)
  94. {
  95. qProtoDebug() << __func__ << " wireType: " << wireType << " metaProperty: " << metaProperty.typeName()
  96. << "currentByte:" << QString::number((*it), 16);
  97. QVariant newPropertyValue;
  98. //TODO: this switch should be removed in future and replaced by wrapped serializer
  99. switch (metaProperty.userType()) {
  100. case QMetaType::QByteArrayList: {
  101. QByteArrayList currentValue = metaProperty.read(object).value<QByteArrayList>();
  102. currentValue.append(deserializeLengthDelimited(it));
  103. metaProperty.write(object, QVariant::fromValue<QByteArrayList>(currentValue));
  104. }
  105. return;
  106. case QMetaType::QStringList: {
  107. QStringList currentValue = metaProperty.read(object).value<QStringList>();
  108. currentValue.append(QString::fromUtf8(deserializeLengthDelimited(it)));
  109. metaProperty.write(object, currentValue);
  110. }
  111. return;
  112. default:
  113. if (metaProperty.isEnumType()) {
  114. newPropertyValue = deserializeBasic<int32>(it);
  115. } else {
  116. newPropertyValue = metaProperty.read(object);
  117. deserializeUserType(metaProperty, it, newPropertyValue);
  118. }
  119. break;
  120. }
  121. metaProperty.write(object, newPropertyValue);
  122. }
  123. void ProtobufObjectPrivate::deserializeUserType(const QMetaProperty &metaType, QByteArray::const_iterator& it, QVariant &newValue)
  124. {
  125. qProtoDebug() << __func__ << "userType" << metaType.userType() << "typeName" << metaType.typeName()
  126. << "currentByte:" << QString::number((*it), 16);
  127. auto deserializer = serializers[metaType.userType()].deserializer;
  128. Q_ASSERT_X(deserializer, "ProtobufObjectPrivate", "Deserialization of unknown type is impossible. QtProtobuf::init() missed?");
  129. deserializer(it, newValue);
  130. }