Add Vector to byte decoder.

Add support for `std::vector` to the tint bytes decoder.

Change-Id: I335d1659df0b62fa1663ef85883cfcccc811e74c
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/168683
Commit-Queue: dan sinclair <dsinclair@chromium.org>
Reviewed-by: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/utils/bytes/decoder.h b/src/tint/utils/bytes/decoder.h
index 95e9f8f..6901f7c 100644
--- a/src/tint/utils/bytes/decoder.h
+++ b/src/tint/utils/bytes/decoder.h
@@ -35,6 +35,7 @@
 #include <tuple>
 #include <unordered_map>
 #include <utility>
+#include <vector>
 
 #include "src/tint/utils/bytes/reader.h"
 #include "src/tint/utils/reflection/reflection.h"
@@ -154,6 +155,34 @@
     }
 };
 
+/// Decoder specialization for std::vector
+template <typename V>
+struct Decoder<std::vector<V>, void> {
+    /// Decode decodes the vector from @p reader.
+    /// @param reader the reader to decode from
+    /// @returns the decoded vector, or an error if the stream is too short.
+    static Result<std::vector<V>> Decode(Reader& reader) {
+        std::vector<V> out;
+
+        while (true) {
+            auto stop = bytes::Decode<bool>(reader);
+            if (stop != Success) {
+                return stop.Failure();
+            }
+            if (stop.Get()) {
+                break;
+            }
+            auto val = bytes::Decode<V>(reader);
+            if (val != Success) {
+                return val.Failure();
+            }
+            out.emplace_back(std::move(val.Get()));
+        }
+
+        return out;
+    }
+};
+
 /// Decoder specialization for std::optional
 template <typename T>
 struct Decoder<std::optional<T>, void> {
diff --git a/src/tint/utils/bytes/decoder_test.cc b/src/tint/utils/bytes/decoder_test.cc
index 9bae945..3535298 100644
--- a/src/tint/utils/bytes/decoder_test.cc
+++ b/src/tint/utils/bytes/decoder_test.cc
@@ -154,6 +154,24 @@
     EXPECT_NE(Decode<M>(reader), Success);
 }
 
+TEST(BytesDecoderTest, Vector) {
+    using M = std::vector<uint8_t>;
+    auto data = Data(0x00, 0x10,  //
+                     0x00, 0x30,  //
+                     0x00, 0x50,  //
+                     0x00, 0x70,  //
+                     0x01);
+    auto reader = BufferReader{Slice{data}};
+    auto got = Decode<M>(reader);
+    EXPECT_THAT(got.Get(), testing::ContainerEq(M{
+                               0x10u,
+                               0x30u,
+                               0x50u,
+                               0x70u,
+                           }));
+    EXPECT_NE(Decode<M>(reader), Success);
+}
+
 TEST(BytesDecoderTest, Optional) {
     auto data = Data(0x00,  //
                      0x01, 0x42);