Bart Hertog 6 лет назад
Родитель
Сommit
3b49418e56
4 измененных файлов с 166 добавлено и 8 удалено
  1. 2 1
      CMakeLists.txt
  2. 76 6
      protoc-gen-eams.py
  3. 2 1
      src/MessageInterface.h
  4. 86 0
      test/test_WireFormatter.cpp

+ 2 - 1
CMakeLists.txt

@@ -9,9 +9,10 @@ add_subdirectory(external/googletest)
 
 file(GLOB src_files
     "test/*.cpp"
+    "build/EAMS/*cpp"
 )
 
-include_directories(test src)
+include_directories(test src build/EAMS)
 include_directories(external/googletest/googletest external/googletest/googletest/include)
 
 add_executable(test_EmbeddedProto ${src_files})

+ 76 - 6
protoc-gen-eams.py

@@ -97,8 +97,8 @@ class {{ msg.name }}: public ::EmbeddedProto::MessageInterface
 {
   public:
     {{ msg.name }}() : 
-        {%- for field in single_fields %}
-        {{field.name}}({{field.default_value}}),
+        {% set j = joiner(",\n") %}
+        {%- for field in single_fields %}{{j()}}_{{field.name}}({{field.default_value}})
         {%- endfor %}
     {
     
@@ -111,6 +111,28 @@ class {{ msg.name }}: public ::EmbeddedProto::MessageInterface
     {{field.type}} get_{{field.name}}() const { return _{{field.name}}; }
     {% endfor %}
     
+    Result serialize(uint8_t* buffer, uint32_t length) const final 
+    {
+    {% for field in single_fields %}
+        if({{field.default_value}} != _{{field.name}})
+        {
+            buffer = ::EmbeddedProto::WireFormatter::{{field.serialize}}({{field.number}}, _{{field.name}}, buffer);
+        }
+    {% endfor %}
+        return Result::OK;
+    };
+    
+    Result deserialize(const uint8_t* buffer, uint32_t length) final
+    {
+        return Result::OK;    
+    }; 
+    
+    void clear() final 
+    {
+    
+    }
+    
+    
   private:
 
     {% for field in single_fields -%}
@@ -125,8 +147,10 @@ class {{ msg.name }}: public ::EmbeddedProto::MessageInterface
     class SingleField:
         def __init__(self, field):
             self.name = field.name
+            self.number = field.number
             self.type = self.type_to_str(field)
-            self.default_value = self.type_to_default(field)
+            self.default_value = self.type_to_default_value(field)
+            self.serialize = self.type_to_serialize(field)
 
         @staticmethod
         def type_to_str(_field):
@@ -141,9 +165,9 @@ class {{ msg.name }}: public ::EmbeddedProto::MessageInterface
             elif FieldDescriptorProto.TYPE_INT32 == _field.type:
                 return "int32_t"
             elif FieldDescriptorProto.TYPE_FIXED64 == _field.type:
-                return "int64_t"
+                return "uint64_t"
             elif FieldDescriptorProto.TYPE_FIXED32 == _field.type:
-                return "int32_t"
+                return "uint32_t"
             elif FieldDescriptorProto.TYPE_BOOL == _field.type:
                 return "bool"
             elif FieldDescriptorProto.TYPE_STRING == _field.type:
@@ -175,7 +199,7 @@ class {{ msg.name }}: public ::EmbeddedProto::MessageInterface
                 pass
 
         @staticmethod
-        def type_to_default(_field):
+        def type_to_default_value(_field):
             if FieldDescriptorProto.TYPE_DOUBLE == _field.type:
                 return "0.0"
             elif FieldDescriptorProto.TYPE_FLOAT == _field.type:
@@ -201,6 +225,52 @@ class {{ msg.name }}: public ::EmbeddedProto::MessageInterface
                 # All other types are numbers with default zero.
                 return "0"
 
+        @staticmethod
+        def type_to_serialize(_field):
+            if FieldDescriptorProto.TYPE_DOUBLE == _field.type:
+                return "WriteDouble"
+            elif FieldDescriptorProto.TYPE_FLOAT == _field.type:
+                return "WriteFloat"
+            elif FieldDescriptorProto.TYPE_INT64 == _field.type:
+                return "WriteInt"
+            elif FieldDescriptorProto.TYPE_UINT64 == _field.type:
+                return "WriteUInt"
+            elif FieldDescriptorProto.TYPE_INT32 == _field.type:
+                return "WriteInt"
+            elif FieldDescriptorProto.TYPE_FIXED64 == _field.type:
+                return "WriteFixed"
+            elif FieldDescriptorProto.TYPE_FIXED32 == _field.type:
+                return "WriteFixed"
+            elif FieldDescriptorProto.TYPE_BOOL == _field.type:
+                return "WriteBool"
+            elif FieldDescriptorProto.TYPE_STRING == _field.type:
+                # TODO
+                pass
+            elif FieldDescriptorProto.TYPE_GROUP == _field.type:
+                # Deprecated
+                pass
+            elif FieldDescriptorProto.TYPE_MESSAGE == _field.type:
+                # TODO
+                pass
+            elif FieldDescriptorProto.TYPE_BYTES == _field.type:
+                # TODO
+                pass
+            elif FieldDescriptorProto.TYPE_UINT32 == _field.type:
+                return "WriteUInt"
+            elif FieldDescriptorProto.TYPE_ENUM == _field.type:
+                # TODO
+                pass
+            elif FieldDescriptorProto.TYPE_SFIXED32 == _field.type:
+                return "WriteSFixed"
+            elif FieldDescriptorProto.TYPE_SFIXED64 == _field.type:
+                return "WriteSFixed"
+            elif FieldDescriptorProto.TYPE_SINT32 == _field.type:
+                return "WriteSInt"
+            elif FieldDescriptorProto.TYPE_SINT64 == _field.type:
+                return "WriteSInt"
+            else:
+                pass
+
     # Split out the simple fields from the more complicated ones.
     single_fields = []
     for field in message.field:

+ 2 - 1
src/MessageInterface.h

@@ -4,6 +4,7 @@
 #define _MESSAGE_INTERFACE_H_
 
 #include <cstdint>
+#include <WireFormatter.h>
 
 namespace EmbeddedProto {
 
@@ -12,7 +13,7 @@ public:
     enum class Result {
         OK,
         ERROR_BUFFER_TO_SMALL,
-    }
+    };
 
     MessageInterface() = default;
 

+ 86 - 0
test/test_WireFormatter.cpp

@@ -6,6 +6,9 @@
 #include <cstdint>    
 #include <limits> 
 
+// EAMS message definitions
+#include <simple_types.h>
+
 namespace test_EmbeddedAMS_WireFormatter 
 {
 
@@ -71,4 +74,87 @@ TEST(WireFormatter, WriteVarint32ToArray)
 
 }
 
+TEST(WireFormatter, SimpleTypes_zero) 
+{
+  // Using a protobuf message and the google protobuf implementation test is serialization is 
+  // correct.
+  ::Test_Simple_Types msg;
+
+  uint8_t buffer[10];
+  msg.serialize(buffer, 10);
+}
+
+TEST(WireFormatter, SimpleTypes_one) 
+{
+  // Using a protobuf message and the google protobuf implementation test is serialization is 
+  // correct.
+  ::Test_Simple_Types msg;
+
+  msg.set_a_int32(1);   
+  msg.set_a_int64(1);     
+  msg.set_a_uint32(1);    
+  msg.set_a_uint64(1);
+  msg.set_a_sint32(1);
+  msg.set_a_sint64(1);
+  msg.set_a_bool(true);
+  msg.set_a_fixed64(1);
+  msg.set_a_sfixed64(1);
+  msg.set_a_double(1.0);
+  msg.set_a_fixed32(1);
+  msg.set_a_sfixed32(1); 
+  msg.set_a_float(1.0F);
+
+  uint8_t buffer[100] = {0};
+  msg.serialize(buffer, 100);
+
+  uint8_t expected[] = {0x08, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, 0x01, 0x28, 0x02, 0x30, 0x02, 0x38, 0x01, 0x49, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F, 0x65, 0x01, 0x00, 0x00, 0x00, 0x6D, 0x01, 0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x80, 0x3F};
+  uint8_t l = sizeof(expected);
+
+  // Check the serialized data
+  for(uint8_t i = 0; i < l; ++i) {
+    EXPECT_EQ(expected[i], buffer[i]);
+  }
+
+  // Check no additional data is generated.
+  for(uint8_t i = l; i < 100; ++i) {
+    EXPECT_EQ(0, buffer[i]);
+  }
+}
+
+TEST(WireFormatter, SimpleTypes_max) 
+{
+  // Using a protobuf message and the google protobuf implementation test is serialization is 
+  // correct.
+  ::Test_Simple_Types msg;
+
+  msg.set_a_int32(std::numeric_limits<int32_t>::max());   
+  msg.set_a_int64(std::numeric_limits<int64_t>::max());     
+  msg.set_a_uint32(std::numeric_limits<uint32_t>::max());    
+  msg.set_a_uint64(std::numeric_limits<uint64_t>::max());
+  msg.set_a_sint32(std::numeric_limits<int32_t>::max());
+  msg.set_a_sint64(std::numeric_limits<int64_t>::max());
+  msg.set_a_fixed64(std::numeric_limits<uint64_t>::max());
+  msg.set_a_sfixed64(std::numeric_limits<int64_t>::max());
+  msg.set_a_double(std::numeric_limits<double>::max());
+  msg.set_a_fixed32(std::numeric_limits<uint32_t>::max());
+  msg.set_a_sfixed32(std::numeric_limits<int32_t>::max()); 
+  msg.set_a_float(std::numeric_limits<float>::max());
+
+  uint8_t buffer[100] = {0};
+  msg.serialize(buffer, 100);
+
+  uint8_t expected[] = {0x08, 0xFF, 0xFF, 0xFF, 0xFF, 0x07, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x18, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F, 0x20, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x28, 0xFE, 0xFF, 0xFF, 0xFF, 0x0F, 0x30, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x49, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x51, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F, 0x65, 0xFF, 0xFF, 0xFF, 0xFF, 0x6D, 0xFF, 0xFF, 0xFF, 0x7F, 0x75, 0xFF, 0xFF, 0x7F, 0x7F};
+  uint8_t l = sizeof(expected);
+
+  // Check the serialized data
+  for(uint8_t i = 0; i < l; ++i) {
+    EXPECT_EQ(expected[i], buffer[i]);
+  }
+
+  // Check no additional data is generated.
+  for(uint8_t i = l; i < 100; ++i) {
+    EXPECT_EQ(0, buffer[i]);
+  }
+}
+
 } // End of namespace test_EmbeddedAMS_WireFormatter