Selaa lähdekoodia

Working on the serialization functions for repeated messages.

Bart Hertog 6 vuotta sitten
vanhempi
sitoutus
a57cb7cab2

+ 2 - 7
generator/Header_Template.h

@@ -72,14 +72,9 @@ class {{ msg.name }} final: public ::EmbeddedProto::MessageInterface
 
       {% for field in msg.fields() %}
       {% if field.of_type_message %}
-      const uint32_t size_{{field.name}} = {{field.variable_name}}.serialized_size();
-      result = (size_{{field.name}} <= buffer.get_available_size());
-      if(result && (0 < size_{{field.name}}))
+      if(result)
       {
-        uint32_t tag = ::EmbeddedProto::WireFormatter::MakeTag({{field.variable_id_name}}, ::EmbeddedProto::WireFormatter::WireType::{{field.wire_type}});
-        result = ::EmbeddedProto::WireFormatter::SerializeVarint(tag, buffer);
-        result = result && ::EmbeddedProto::WireFormatter::SerializeVarint(size_{{field.name}}, buffer);
-        result = result && {{field.variable_name}}.serialize(buffer);
+        result = ::EmbeddedProto::{{field.serialization_func}}({{field.variable_id_name}}, {{field.variable_name}}, buffer);
       }
       {% elif field.of_type_enum %}
       if(({{field.default_value}} != {{field.variable_name}}) && result)

+ 4 - 3
generator/protoc-gen-eams.py

@@ -89,6 +89,7 @@ class FieldTemplateParameters:
                         FieldDescriptorProto.TYPE_BOOL:     "serialize",
                         FieldDescriptorProto.TYPE_ENUM:     "serialize",
                         FieldDescriptorProto.TYPE_STRING:   "TODO",     # TODO
+                        FieldDescriptorProto.TYPE_MESSAGE:  "serialize",
                         FieldDescriptorProto.TYPE_BYTES:    "TODO",     # TODO
                         FieldDescriptorProto.TYPE_UINT32:   "serialize",
                         FieldDescriptorProto.TYPE_SFIXED32: "serialize",
@@ -106,6 +107,7 @@ class FieldTemplateParameters:
                           FieldDescriptorProto.TYPE_BOOL:     "deserialize",
                           FieldDescriptorProto.TYPE_ENUM:     "deserialize",
                           FieldDescriptorProto.TYPE_STRING:   "TODO",     # TODO
+                          FieldDescriptorProto.TYPE_MESSAGE:  "deserialize",
                           FieldDescriptorProto.TYPE_BYTES:    "TODO",     # TODO
                           FieldDescriptorProto.TYPE_UINT32:   "deserialize",
                           FieldDescriptorProto.TYPE_SFIXED32: "deserialize",
@@ -121,9 +123,8 @@ class FieldTemplateParameters:
 
         self.of_type_message = FieldDescriptorProto.TYPE_MESSAGE == field_proto.type
         self.wire_type = self.type_to_wire_type[field_proto.type]
-        if not self.of_type_message:
-            self.serialization_func = self.type_to_ser_func[field_proto.type]
-            self.deserialization_func = self.type_to_deser_func[field_proto.type]
+        self.serialization_func = self.type_to_ser_func[field_proto.type]
+        self.deserialization_func = self.type_to_deser_func[field_proto.type]
 
         if FieldDescriptorProto.TYPE_MESSAGE == field_proto.type or FieldDescriptorProto.TYPE_ENUM == field_proto.type:
             self.type = field_proto.type_name if "." != field_proto.type_name[0] else field_proto.type_name[1:]

+ 31 - 0
src/MessageInterface.h

@@ -59,6 +59,37 @@ private:
 
 };
 
+bool serialize(uint32_t field_number, const MessageInterface& x, WriteBufferInterface& buffer)
+{
+  const uint32_t size_x = x.serialized_size();
+  bool result = (size_x < buffer.get_available_size());
+  if(result && (0 < size_x))
+  {
+    uint32_t tag = ::EmbeddedProto::WireFormatter::MakeTag(field_number, ::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED);
+    result = ::EmbeddedProto::WireFormatter::SerializeVarint(tag, buffer);
+    result = result && ::EmbeddedProto::WireFormatter::SerializeVarint(size_x, buffer);
+    result = result && x.serialize(buffer);
+  }
+  return result;
+}
+
+bool serialize(const MessageInterface& x, WriteBufferInterface& buffer)
+{
+  const uint32_t size_x = x.serialized_size();
+  bool result = (size_x < buffer.get_available_size());
+  if(result && (0 < size_x))
+  {
+    result = ::EmbeddedProto::WireFormatter::SerializeVarint(size_x, buffer);
+    result = result && x.serialize(buffer);
+  }
+  return result;
+}
+
+inline bool deserialize(ReadBufferInterface& buffer, MessageInterface& x)
+{
+    return x.deserialize(buffer);
+}
+
 } // End of namespace EmbeddedProto
 
 #endif // _MESSAGE_INTERFACE_H_

+ 35 - 1
src/RepeatedField.h

@@ -149,7 +149,7 @@ namespace EmbeddedProto
 
       RepeatedFieldSize()
         : current_size_(0),
-          data_{0}
+          data_{}
       {
 
       }  
@@ -212,6 +212,40 @@ namespace EmbeddedProto
       DATA_TYPE data_[MAX_SIZE];
   };
 
+  template<class DATA_TYPE>
+  bool serialize(uint32_t field_number, const RepeatedField<DATA_TYPE>& x, WriteBufferInterface& buffer)
+  {
+    const uint32_t size_x = x.serialized_size();
+    bool result = (size_x < buffer.get_available_size());
+    if(result && (0 < size_x))
+    {
+      uint32_t tag = ::EmbeddedProto::WireFormatter::MakeTag(field_number, ::EmbeddedProto::WireFormatter::WireType::LENGTH_DELIMITED);
+      result = ::EmbeddedProto::WireFormatter::SerializeVarint(tag, buffer);
+      result = result && ::EmbeddedProto::WireFormatter::SerializeVarint(size_x, buffer);
+      result = result && x.serialize(buffer);
+    }
+    return result;
+  }
+
+  template<class DATA_TYPE>
+  bool serialize(const RepeatedField<DATA_TYPE>& x, WriteBufferInterface& buffer)
+  {
+    const uint32_t size_x = x.serialized_size();
+    bool result = (size_x < buffer.get_available_size());
+    if(result && (0 < size_x))
+    {
+      result = ::EmbeddedProto::WireFormatter::SerializeVarint(size_x, buffer);
+      result = result && x.serialize(buffer);
+    }
+    return result;
+  }
+
+  template<class DATA_TYPE>
+  inline bool deserialize(ReadBufferInterface& buffer, RepeatedField<DATA_TYPE>& x)
+  {
+      return x.deserialize(buffer);
+  }
+
 } // End of namespace EmbeddedProto
 
 #endif // End of _DYNAMIC_BUFFER_H_

+ 13 - 0
test/proto/repeated_fields.proto

@@ -8,3 +8,16 @@ message repeated_fields
   repeated uint32 y   = 2;
   uint32 z            = 3;
 }
+
+message repeated_nested_message
+{
+  uint32 u = 1;
+  uint32 v = 2;
+}
+
+message repeated_message
+{
+  uint32 x                            = 1;
+  repeated repeated_nested_message y  = 2;
+  uint32 z                            = 3;
+}

+ 1 - 0
test/test_RepeatedFieldMessage.cpp

@@ -24,6 +24,7 @@ static constexpr uint32_t Y_SIZE = 3;
 TEST(RepeatedFieldMessage, construction) 
 {
   repeated_fields<Y_SIZE> msg;
+  repeated_message<Y_SIZE> msg2;
 }
 
 TEST(RepeatedFieldMessage, serialize_empty) 

+ 26 - 1
test_data.py

@@ -2,6 +2,7 @@ import build.python.simple_types_pb2 as st
 import build.python.nested_message_pb2 as nm
 import build.python.repeated_fields_pb2 as rf
 
+
 def test_simple_types():
     # A test function used to generate encoded data to test the implementation of the wireformatter
     # and header template.
@@ -131,4 +132,28 @@ def test_repeated_fields():
     print()
 
 
-test_repeated_fields()
+def test_repeated_message():
+    nmsg = rf.nested_message()
+    nmsg.u = 1
+    nmsg.v = 1
+
+    msg = rf.repeated_message()
+
+    msg.x = 0
+    for i in range(3):
+        nmsg = msg.y.add()
+        nmsg.u = 1
+        nmsg.v = 1
+    msg.z = 0
+
+    str = ""
+    msg_str = msg.SerializeToString()
+    print(len(msg_str))
+    print(msg_str)
+    for x in msg_str:
+      str += "0x{:02x}, ".format(x)
+
+    print(str)
+    print()
+
+test_repeated_message()