|  | // Copyright 2024 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "quiche/common/vectorized_io_utils.h" | 
|  |  | 
|  | #include <cstddef> | 
|  | #include <string> | 
|  | #include <vector> | 
|  |  | 
|  | #include "absl/strings/string_view.h" | 
|  | #include "absl/types/span.h" | 
|  | #include "quiche/common/platform/api/quiche_test.h" | 
|  |  | 
|  | namespace quiche { | 
|  | namespace { | 
|  |  | 
|  | using ::testing::ElementsAre; | 
|  |  | 
|  | TEST(VectorizedIoUtils, GatherStringViewSpanEmpty) { | 
|  | std::vector<absl::string_view> views = {"a", "b", "c"}; | 
|  | size_t bytes_copied = GatherStringViewSpan(views, absl::Span<char>()); | 
|  | EXPECT_EQ(bytes_copied, 0); | 
|  | } | 
|  |  | 
|  | TEST(VectorizedIoUtils, GatherStringViewSpanSingle) { | 
|  | std::vector<absl::string_view> views = {"test"}; | 
|  | char buffer_small[2]; | 
|  | size_t bytes_copied = | 
|  | GatherStringViewSpan(views, absl::MakeSpan(buffer_small)); | 
|  | EXPECT_EQ(bytes_copied, 2); | 
|  | EXPECT_THAT(buffer_small, ElementsAre('t', 'e')); | 
|  |  | 
|  | char buffer_exact[4]; | 
|  | bytes_copied = GatherStringViewSpan(views, absl::MakeSpan(buffer_exact)); | 
|  | EXPECT_EQ(bytes_copied, 4); | 
|  | EXPECT_THAT(buffer_exact, ElementsAre('t', 'e', 's', 't')); | 
|  |  | 
|  | char buffer_large[6] = {'\0'}; | 
|  | bytes_copied = GatherStringViewSpan(views, absl::MakeSpan(buffer_large)); | 
|  | EXPECT_EQ(bytes_copied, 4); | 
|  | EXPECT_THAT(buffer_large, ElementsAre('t', 'e', 's', 't', '\0', '\0')); | 
|  | } | 
|  |  | 
|  | TEST(VectorizedIoUtils, GatherStringViewSpanMultiple) { | 
|  | const std::vector<absl::string_view> views = {"foo", ",", "bar"}; | 
|  | constexpr absl::string_view kViewsJoined = "foo,bar"; | 
|  | char buffer[kViewsJoined.size()]; | 
|  | for (size_t i = 0; i < sizeof(buffer); ++i) { | 
|  | size_t bytes_copied = | 
|  | GatherStringViewSpan(views, absl::Span<char>(buffer, i)); | 
|  | absl::string_view result(buffer, bytes_copied); | 
|  | EXPECT_EQ(result, kViewsJoined.substr(0, i)); | 
|  | } | 
|  | } | 
|  |  | 
|  | TEST(VectorizedIoUtils, GatherStringViewSpanEmptyElement) { | 
|  | const std::vector<absl::string_view> views = {"foo", "", "bar"}; | 
|  | constexpr absl::string_view kViewsJoined = "foobar"; | 
|  | char buffer[kViewsJoined.size()]; | 
|  | size_t bytes_copied = GatherStringViewSpan(views, absl::MakeSpan(buffer)); | 
|  | absl::string_view result(buffer, bytes_copied); | 
|  | EXPECT_EQ(result, kViewsJoined); | 
|  | } | 
|  |  | 
|  | TEST(VectorizedIoUtils, GatherStringViewSpanLarge) { | 
|  | const std::string a(8192, 'a'); | 
|  | const std::string b(8192, 'b'); | 
|  | const std::vector<absl::string_view> views = {a, b}; | 
|  | const std::string joined = a + b; | 
|  | char buffer[8192 * 2]; | 
|  | size_t bytes_copied = GatherStringViewSpan(views, absl::MakeSpan(buffer)); | 
|  | EXPECT_EQ(bytes_copied, 8192 * 2); | 
|  | absl::string_view result(buffer, bytes_copied); | 
|  | EXPECT_EQ(result, joined); | 
|  | } | 
|  |  | 
|  | }  // namespace | 
|  | }  // namespace quiche |