Import Tint changes from Dawn
Changes:
- cbcc0ce28b0b9692eccd3ff1c58fcda79f2c8f53 [tint][utils] Flesh out bytes utilities by Ben Clayton <bclayton@google.com>
- 55dfb797443039e7858a3f0ecfa09e9cd823c058 clang-format by Ben Clayton <bclayton@google.com>
GitOrigin-RevId: cbcc0ce28b0b9692eccd3ff1c58fcda79f2c8f53
Change-Id: I9c926a6ef9dfb7c775292b7c089022b880ddf952
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/167860
Reviewed-by: Ben Clayton <bclayton@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
diff --git a/src/tint/utils/bytes/BUILD.bazel b/src/tint/utils/bytes/BUILD.bazel
index 2bfa708..3b0bb76 100644
--- a/src/tint/utils/bytes/BUILD.bazel
+++ b/src/tint/utils/bytes/BUILD.bazel
@@ -41,12 +41,15 @@
srcs = [
"bytes.cc",
"reader.cc",
+ "writer.cc",
],
hdrs = [
+ "buffer_writer.h",
"decoder.h",
"endianness.h",
"reader.h",
"swap.h",
+ "writer.h",
],
deps = [
"//src/tint/utils/containers",
@@ -68,6 +71,7 @@
name = "test",
alwayslink = True,
srcs = [
+ "buffer_writer_test.cc",
"decoder_test.cc",
"reader_test.cc",
"swap_test.cc",
diff --git a/src/tint/utils/bytes/BUILD.cmake b/src/tint/utils/bytes/BUILD.cmake
index a3997fd..6d919d3 100644
--- a/src/tint/utils/bytes/BUILD.cmake
+++ b/src/tint/utils/bytes/BUILD.cmake
@@ -39,12 +39,15 @@
# Kind: lib
################################################################################
tint_add_target(tint_utils_bytes lib
+ utils/bytes/buffer_writer.h
utils/bytes/bytes.cc
utils/bytes/decoder.h
utils/bytes/endianness.h
utils/bytes/reader.cc
utils/bytes/reader.h
utils/bytes/swap.h
+ utils/bytes/writer.cc
+ utils/bytes/writer.h
)
tint_target_add_dependencies(tint_utils_bytes lib
@@ -66,6 +69,7 @@
# Kind: test
################################################################################
tint_add_target(tint_utils_bytes_test test
+ utils/bytes/buffer_writer_test.cc
utils/bytes/decoder_test.cc
utils/bytes/reader_test.cc
utils/bytes/swap_test.cc
diff --git a/src/tint/utils/bytes/BUILD.gn b/src/tint/utils/bytes/BUILD.gn
index c10512f..d3babe2 100644
--- a/src/tint/utils/bytes/BUILD.gn
+++ b/src/tint/utils/bytes/BUILD.gn
@@ -44,12 +44,15 @@
libtint_source_set("bytes") {
sources = [
+ "buffer_writer.h",
"bytes.cc",
"decoder.h",
"endianness.h",
"reader.cc",
"reader.h",
"swap.h",
+ "writer.cc",
+ "writer.h",
]
deps = [
"${tint_src_dir}/utils/containers",
@@ -68,6 +71,7 @@
if (tint_build_unittests) {
tint_unittests_source_set("unittests") {
sources = [
+ "buffer_writer_test.cc",
"decoder_test.cc",
"reader_test.cc",
"swap_test.cc",
diff --git a/src/tint/utils/bytes/buffer_writer.h b/src/tint/utils/bytes/buffer_writer.h
new file mode 100644
index 0000000..8ba37dc
--- /dev/null
+++ b/src/tint/utils/bytes/buffer_writer.h
@@ -0,0 +1,68 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_UTILS_BYTES_BUFFER_WRITER_H_
+#define SRC_TINT_UTILS_BYTES_BUFFER_WRITER_H_
+
+#include <stdint.h>
+
+#include "src/tint/utils/bytes/writer.h"
+
+namespace tint::bytes {
+
+/// BufferWriter is an implementation of the Writer interface backed by a buffer.
+template <size_t N>
+class BufferWriter final : public Writer {
+ public:
+ /// @copydoc Writer::Write
+ Result<SuccessType> Write(const std::byte* in, size_t count) override {
+ size_t at = buffer.Length();
+ buffer.Resize(at + count);
+ memcpy(&buffer[at], in, count);
+ return Success;
+ }
+
+ /// @returns the buffer content as a string view
+ std::string_view BufferString() const {
+ if (buffer.IsEmpty()) {
+ return "";
+ }
+ auto* data = reinterpret_cast<const char*>(&buffer[0]);
+ static_assert(sizeof(std::byte) == sizeof(char), "length needs calculation");
+ return std::string_view(data, buffer.Length());
+ }
+
+ /// The buffer holding the written data
+ Vector<std::byte, N> buffer;
+};
+
+/// Deduction guide for BufferWriter
+BufferWriter() -> BufferWriter<32>;
+
+} // namespace tint::bytes
+
+#endif // SRC_TINT_UTILS_BYTES_BUFFER_WRITER_H_
diff --git a/src/tint/utils/bytes/buffer_writer_test.cc b/src/tint/utils/bytes/buffer_writer_test.cc
new file mode 100644
index 0000000..7862e28
--- /dev/null
+++ b/src/tint/utils/bytes/buffer_writer_test.cc
@@ -0,0 +1,66 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/utils/bytes/buffer_writer.h"
+
+#include "gmock/gmock.h"
+#include "src/tint/utils/containers/transform.h"
+
+namespace tint::bytes {
+namespace {
+
+template <typename T, typename U, size_t N>
+Vector<T, N> Cast(const Vector<U, N>& in) {
+ return Transform(in, [](auto el) { return static_cast<T>(el); });
+}
+
+TEST(BufferWriterTest, IntegerBigEndian) {
+ BufferWriter<16> writer;
+ EXPECT_TRUE(writer.Int(0x10203040u, Endianness::kBig));
+ EXPECT_THAT(Cast<int>(writer.buffer), testing::ElementsAre(0x10, 0x20, 0x30, 0x40));
+}
+
+TEST(BufferWriterTest, IntegerLittleEndian) {
+ BufferWriter<16> writer;
+ EXPECT_TRUE(writer.Int(0x10203040u, Endianness::kLittle));
+ EXPECT_THAT(Cast<int>(writer.buffer), testing::ElementsAre(0x40, 0x30, 0x20, 0x10));
+}
+
+TEST(BufferWriterTest, Float) {
+ BufferWriter<16> writer;
+ EXPECT_TRUE(writer.Float<float>(8.5f));
+ EXPECT_THAT(Cast<int>(writer.buffer), testing::ElementsAre(0x00, 0x00, 0x08, 0x41));
+}
+
+TEST(BufferWriterTest, Bool) {
+ BufferWriter<16> writer;
+ EXPECT_TRUE(writer.Bool(true));
+ EXPECT_THAT(Cast<int>(writer.buffer), testing::ElementsAre(0x01));
+}
+
+} // namespace
+} // namespace tint::bytes
diff --git a/src/tint/utils/bytes/decoder.h b/src/tint/utils/bytes/decoder.h
index 4496ad9..b107497 100644
--- a/src/tint/utils/bytes/decoder.h
+++ b/src/tint/utils/bytes/decoder.h
@@ -34,6 +34,7 @@
#include <utility>
#include "src/tint/utils/bytes/reader.h"
+#include "src/tint/utils/reflection/reflection.h"
namespace tint::bytes {
diff --git a/src/tint/utils/bytes/reader.cc b/src/tint/utils/bytes/reader.cc
index 42e0176..9c28d1d 100644
--- a/src/tint/utils/bytes/reader.cc
+++ b/src/tint/utils/bytes/reader.cc
@@ -30,6 +30,15 @@
namespace tint::bytes {
Reader::~Reader() = default;
+
BufferReader::~BufferReader() = default;
+size_t BufferReader::Read(std::byte* out, size_t count) {
+ size_t n = std::min(count, bytes_remaining_);
+ memcpy(out, data_, n);
+ data_ += n;
+ bytes_remaining_ -= n;
+ return n;
+}
+
} // namespace tint::bytes
diff --git a/src/tint/utils/bytes/reader.h b/src/tint/utils/bytes/reader.h
index 9e58c15..59e1864 100644
--- a/src/tint/utils/bytes/reader.h
+++ b/src/tint/utils/bytes/reader.h
@@ -35,7 +35,6 @@
#include "src/tint/utils/bytes/endianness.h"
#include "src/tint/utils/bytes/swap.h"
#include "src/tint/utils/containers/slice.h"
-#include "src/tint/utils/reflection/reflection.h"
#include "src/tint/utils/result/result.h"
namespace tint::bytes {
@@ -43,6 +42,9 @@
/// A binary stream reader interface
class Reader {
public:
+ /// Destructor
+ virtual ~Reader();
+
/// Read reads bytes from the stream, blocking until there are @p count bytes available, or the
/// end of the stream has been reached.
/// @param out a pointer to the byte buffer that will be filled with the read data. Must be at
@@ -52,9 +54,6 @@
/// then the end of the stream has been reached.
virtual size_t Read(std::byte* out, size_t count) = 0;
- // Destructor
- virtual ~Reader();
-
/// Reads an integer from the stream, performing byte swapping if the stream's endianness
/// differs from the native endianness.
/// If there are too few bytes remaining in the stream, then a failure is returned.
@@ -126,6 +125,12 @@
}
/// Constructor
+ /// @param string the string to read from
+ explicit BufferReader(std::string_view string)
+ : data_(reinterpret_cast<const std::byte*>(string.data())),
+ bytes_remaining_(string.length()) {}
+
+ /// Constructor
/// @param slice the byte slice to read from
explicit BufferReader(Slice<const std::byte> slice)
: data_(slice.data), bytes_remaining_(slice.len) {
@@ -133,13 +138,7 @@
}
/// @copydoc Reader::Read
- size_t Read(std::byte* out, size_t count) override {
- size_t n = std::min(count, bytes_remaining_);
- memcpy(out, data_, n);
- data_ += n;
- bytes_remaining_ -= n;
- return n;
- }
+ size_t Read(std::byte* out, size_t count) override;
private:
/// The data to read from
diff --git a/src/tint/utils/bytes/writer.cc b/src/tint/utils/bytes/writer.cc
new file mode 100644
index 0000000..005c5fc
--- /dev/null
+++ b/src/tint/utils/bytes/writer.cc
@@ -0,0 +1,34 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "src/tint/utils/bytes/writer.h"
+
+namespace tint::bytes {
+
+Writer::~Writer() = default;
+
+}
diff --git a/src/tint/utils/bytes/writer.h b/src/tint/utils/bytes/writer.h
new file mode 100644
index 0000000..3f9ce97
--- /dev/null
+++ b/src/tint/utils/bytes/writer.h
@@ -0,0 +1,96 @@
+// Copyright 2024 The Dawn & Tint Authors
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this
+// list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SRC_TINT_UTILS_BYTES_WRITER_H_
+#define SRC_TINT_UTILS_BYTES_WRITER_H_
+
+#include <algorithm>
+#include <cstdint>
+#include <string>
+
+#include "src/tint/utils/bytes/endianness.h"
+#include "src/tint/utils/bytes/swap.h"
+#include "src/tint/utils/containers/slice.h"
+#include "src/tint/utils/result/result.h"
+
+namespace tint::bytes {
+
+/// A binary stream writer interface
+class Writer {
+ public:
+ /// Destructor
+ virtual ~Writer();
+
+ /// Write writes bytes to the stream, blocking until the write has finished.
+ /// @param in the byte data to write to the stream
+ /// @param count the number of bytes to write. Must be greater than 0
+ /// @returns the result of the write
+ virtual Result<SuccessType> Write(const std::byte* in, size_t count) = 0;
+
+ /// Writes an integer to the stream, performing byte swapping if the stream's endianness
+ /// differs from the native endianness.
+ /// @param value the integer value to write
+ /// @param endianness the endianness of the integer in the stream
+ /// @returns the result of the write
+ template <typename T>
+ Result<SuccessType> Int(T value, Endianness endianness = Endianness::kLittle) {
+ static_assert(std::is_integral_v<T>);
+ if (NativeEndianness() != endianness) {
+ value = Swap(value);
+ }
+ return Write(reinterpret_cast<const std::byte*>(&value), sizeof(T));
+ }
+
+ /// Writes a float to the stream.
+ /// @param value the float value to write
+ /// @returns the result of the write
+ template <typename T>
+ Result<SuccessType> Float(T value) {
+ static_assert(std::is_floating_point_v<T>);
+ return Write(reinterpret_cast<const std::byte*>(&value), sizeof(T));
+ }
+
+ /// Writes a boolean to the stream
+ /// @param value the boolean value to write
+ /// @returns the result of the write
+ Result<SuccessType> Bool(bool value) {
+ auto b = value ? std::byte{1} : std::byte{0};
+ return Write(&b, 1);
+ }
+
+ /// Writes a string of @p len bytes to the stream.
+ /// @param value the string to write
+ /// @returns the result of the write
+ Result<SuccessType> String(std::string_view value) {
+ static_assert(sizeof(std::byte) == sizeof(char), "length needs calculation");
+ return Write(reinterpret_cast<const std::byte*>(value.data()), value.length());
+ }
+};
+
+} // namespace tint::bytes
+
+#endif // SRC_TINT_UTILS_BYTES_WRITER_H_
diff --git a/src/tint/utils/macros/compiler.h b/src/tint/utils/macros/compiler.h
index 623e4c4..dd56cde 100644
--- a/src/tint/utils/macros/compiler.h
+++ b/src/tint/utils/macros/compiler.h
@@ -99,8 +99,8 @@
_Pragma("clang diagnostic ignored \"-Wextra-semi-stmt\"")
#define TINT_DISABLE_WARNING_ZERO_AS_NULLPTR \
_Pragma("clang diagnostic ignored \"-Wzero-as-null-pointer-constant\"")
-#define TINT_DISABLE_WARNING_MISSING_DESTRUCTOR_OVERRIDE \
- _Pragma("clang diagnostic ignored \"-Wsuggest-destructor-override\"") \
+#define TINT_DISABLE_WARNING_MISSING_DESTRUCTOR_OVERRIDE \
+ _Pragma("clang diagnostic ignored \"-Wsuggest-destructor-override\"") \
_Pragma("clang diagnostic ignored \"-Winconsistent-missing-destructor-override\"")
// clang-format off
diff --git a/src/tint/utils/traits/traits.h b/src/tint/utils/traits/traits.h
index b28cbf1..669a254 100644
--- a/src/tint/utils/traits/traits.h
+++ b/src/tint/utils/traits/traits.h
@@ -190,11 +190,12 @@
template <typename T>
using PtrElTy = Decay<std::remove_pointer_t<Decay<T>>>;
-/// Evaluates to true if `T` decayed is a `std::string`, `std::string_view` or `const char*`
+/// Evaluates to true if `T` decayed is a `std::string`, `std::string_view`, `const char*` or
+/// `char*`
template <typename T>
static constexpr bool IsStringLike =
std::is_same_v<Decay<T>, std::string> || std::is_same_v<Decay<T>, std::string_view> ||
- std::is_same_v<Decay<T>, const char*>;
+ std::is_same_v<Decay<T>, const char*> || std::is_same_v<Decay<T>, char*>;
namespace detail {
/// Helper for CharArrayToCharPtr