Procházet zdrojové kódy

Test and fix for deserializing repeated strings.

Bart Hertog před 5 roky
rodič
revize
8bddfc3b9b
2 změnil soubory, kde provedl 107 přidání a 32 odebrání
  1. 62 32
      src/RepeatedField.h
  2. 45 0
      test/test_string_bytes.cpp

+ 62 - 32
src/RepeatedField.h

@@ -191,41 +191,11 @@ namespace EmbeddedProto
         Error return_value = Error::NO_ERRORS;
         if(REPEATED_FIELD_IS_PACKED)
         {              
-          uint32_t size;
-          return_value = WireFormatter::DeserializeVarint(buffer, size);
-          ReadBufferSection bufferSection(buffer, size);
-          DATA_TYPE x;
-          
-          return_value = x.deserialize(bufferSection);
-          while(Error::NO_ERRORS == return_value)
-          {
-            return_value = this->add(x);
-            if(Error::NO_ERRORS == return_value)
-            {
-              return_value = x.deserialize(bufferSection);
-            }
-          }
-
-          // We expect the buffersection to be empty, in that case everything is fine..
-          if(Error::END_OF_BUFFER == return_value)
-          {
-            return_value = Error::NO_ERRORS;
-          }
+          return_value = deserialize_packed(buffer);
         }
         else 
         {
-          uint32_t size;
-          return_value = WireFormatter::DeserializeVarint(buffer, size);
-          if(Error::NO_ERRORS == return_value) 
-          {
-            ReadBufferSection bufferSection(buffer, size);
-            DATA_TYPE x;
-            return_value = x.deserialize(bufferSection);
-            if(Error::NO_ERRORS == return_value)
-            {
-              return_value = this->add(x);
-            }
-          }
+          return_value = deserialize_unpacked(buffer);
         }
         return return_value;
       }
@@ -286,6 +256,66 @@ namespace EmbeddedProto
         return return_value;
       }
 
+      Error deserialize_packed(ReadBufferInterface& buffer)
+      {
+        uint32_t size;
+        Error return_value = WireFormatter::DeserializeVarint(buffer, size);
+        ReadBufferSection bufferSection(buffer, size);
+        DATA_TYPE x;
+        
+        return_value = x.deserialize(bufferSection);
+        while(Error::NO_ERRORS == return_value)
+        {
+          return_value = this->add(x);
+          if(Error::NO_ERRORS == return_value)
+          {
+            return_value = x.deserialize(bufferSection);
+          }
+        }
+
+        // We expect the buffersection to be empty, in that case everything is fine..
+        if(Error::END_OF_BUFFER == return_value)
+        {
+          return_value = Error::NO_ERRORS;
+        }
+
+        return return_value;
+      }
+
+      Error deserialize_unpacked(ReadBufferInterface& buffer)
+      {
+        Error return_value = Error::NO_ERRORS;
+
+        // For repeated messages, strings or bytes
+        // First allocate an element in the array.
+        const uint32_t index = this->get_length();
+        if(this->get_max_length() > index)
+        {
+          // For messages read the size here, with strings and byte arrays this is include in 
+          // deserialize.
+          if(std::is_base_of<MessageInterface, DATA_TYPE>::value)
+          {
+            uint32_t size;
+            return_value = WireFormatter::DeserializeVarint(buffer, size);
+            if(Error::NO_ERRORS == return_value) 
+            {
+              ReadBufferSection bufferSection(buffer, size);
+              return_value = this->get(index).deserialize(bufferSection);
+            }
+          }
+          else 
+          {
+            return_value = this->get(index).deserialize(buffer);
+          }
+        }
+        else 
+        {
+          return_value = Error::ARRAY_FULL;
+        }
+
+        return return_value;
+      }
+
   };
 
 

+ 45 - 0
test/test_string_bytes.cpp

@@ -432,4 +432,49 @@ TEST(RepeatedStringBytes, serialize)
   EXPECT_EQ(::EmbeddedProto::Error::NO_ERRORS, msg.serialize(buffer));
 }
 
+TEST(RepeatedStringBytes, deserialize) 
+{ 
+  InSequence s;
+
+  repeated_string_bytes<3, 15, 3, 15> msg;
+  Mocks::ReadBufferMock buffer;
+
+  // Pop the tag and size of the first string
+  EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(0x0a), Return(true)));
+  EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(0x09), Return(true)));
+
+  uint8_t referee_str1[] = {0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72, 0x20, 0x31};
+
+  for(auto r: referee_str1) 
+  {
+    EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(r), Return(true)));
+  }
+
+  // Pop the tag and size of the second string
+  EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(0x0a), Return(true)));
+  EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(0x00), Return(true)));
+
+  // Pop the tag and size of the third string
+  EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(0x0a), Return(true)));
+  EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(0x09), Return(true)));
+
+  uint8_t referee_str3[] = {0x46, 0x6f, 0x6f, 0x20, 0x62, 0x61, 0x72, 0x20, 0x33};
+
+  for(auto r: referee_str3) 
+  {
+    EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(DoAll(SetArgReferee<0>(r), Return(true)));
+  }
+
+  EXPECT_CALL(buffer, pop(_)).Times(1).WillOnce(Return(false));
+
+  EXPECT_EQ(::EmbeddedProto::Error::NO_ERRORS, msg.deserialize(buffer));
+  EXPECT_EQ(3, msg.array_of_txt().get_length());
+  EXPECT_EQ(0, msg.array_of_bytes().get_length());
+  EXPECT_STREQ(msg.array_of_txt(0).get_const(), "Foo bar 1");
+  EXPECT_STREQ(msg.array_of_txt(1).get_const(), "");
+  EXPECT_STREQ(msg.array_of_txt(2).get_const(), "Foo bar 3"); 
+}
+
+
+
 } // End of namespace test_EmbeddedAMS_string_bytes