Project import generated by Copybara.

PiperOrigin-RevId: 229942388
Change-Id: Ib5a23c152c95ed4294cece9f902227c21ce531ef
diff --git a/spdy/platform/api/spdy_arraysize.h b/spdy/platform/api/spdy_arraysize.h
new file mode 100644
index 0000000..356051e
--- /dev/null
+++ b/spdy/platform/api/spdy_arraysize.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2018 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_ARRAYSIZE_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_ARRAYSIZE_H_
+
+#include "net/spdy/platform/impl/spdy_arraysize_impl.h"
+
+#define SPDY_ARRAYSIZE(x) SPDY_ARRAYSIZE_IMPL(x)
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_ARRAYSIZE_H_
diff --git a/spdy/platform/api/spdy_bug_tracker.h b/spdy/platform/api/spdy_bug_tracker.h
new file mode 100644
index 0000000..d750a21
--- /dev/null
+++ b/spdy/platform/api/spdy_bug_tracker.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_BUG_TRACKER_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_BUG_TRACKER_H_
+
+#include "net/spdy/platform/impl/spdy_bug_tracker_impl.h"
+
+#define SPDY_BUG SPDY_BUG_IMPL
+#define SPDY_BUG_IF(condition) SPDY_BUG_IF_IMPL(condition)
+#define FLAGS_spdy_always_log_bugs_for_tests \
+  FLAGS_spdy_always_log_bugs_for_tests_impl
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_BUG_TRACKER_H_
diff --git a/spdy/platform/api/spdy_containers.h b/spdy/platform/api/spdy_containers.h
new file mode 100644
index 0000000..e4f4c49
--- /dev/null
+++ b/spdy/platform/api/spdy_containers.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2018 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_CONTAINERS_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_CONTAINERS_H_
+
+#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_piece.h"
+#include "net/spdy/platform/impl/spdy_containers_impl.h"
+
+namespace spdy {
+
+template <typename KeyType>
+using SpdyHash = SpdyHashImpl<KeyType>;
+
+// SpdyHashMap does not guarantee pointer stability.
+template <typename KeyType,
+          typename ValueType,
+          typename Hash = SpdyHash<KeyType>>
+using SpdyHashMap = SpdyHashMapImpl<KeyType, ValueType, Hash>;
+
+// SpdyHashSet does not guarantee pointer stability.
+template <typename ElementType, typename Hasher, typename Eq>
+using SpdyHashSet = SpdyHashSetImpl<ElementType, Hasher, Eq>;
+
+// A map which offers insertion-ordered iteration.
+template <typename Key, typename Value, typename Hash = SpdyHash<Key>>
+using SpdyLinkedHashMap = SpdyLinkedHashMapImpl<Key, Value, Hash>;
+
+// A vector optimized for small sizes. Provides the same APIs as a std::vector.
+template <typename T, size_t N, typename A = std::allocator<T>>
+using SpdyInlinedVector = SpdyInlinedVectorImpl<T, N, A>;
+
+using SpdyStringPieceHash = SpdyStringPieceHashImpl;
+
+inline size_t SpdyHashStringPair(SpdyStringPiece a, SpdyStringPiece b) {
+  return SpdyHashStringPairImpl(a, b);
+}
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_CONTAINERS_H_
diff --git a/spdy/platform/api/spdy_endianness_util.h b/spdy/platform/api/spdy_endianness_util.h
new file mode 100644
index 0000000..e4074d7
--- /dev/null
+++ b/spdy/platform/api/spdy_endianness_util.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2018 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_ENDIANNESS_UTIL_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_ENDIANNESS_UTIL_H_
+
+#include <stdint.h>
+
+#include "net/spdy/platform/impl/spdy_endianness_util_impl.h"
+
+namespace spdy {
+
+// Converts the bytes in |x| from network to host order (endianness), and
+// returns the result.
+inline uint16_t SpdyNetToHost16(uint16_t x) {
+  return SpdyNetToHost16Impl(x);
+}
+
+inline uint32_t SpdyNetToHost32(uint32_t x) {
+  return SpdyNetToHost32Impl(x);
+}
+
+inline uint64_t SpdyNetToHost64(uint64_t x) {
+  return SpdyNetToHost64Impl(x);
+}
+
+// Converts the bytes in |x| from host to network order (endianness), and
+// returns the result.
+inline uint16_t SpdyHostToNet16(uint16_t x) {
+  return SpdyHostToNet16Impl(x);
+}
+
+inline uint32_t SpdyHostToNet32(uint32_t x) {
+  return SpdyHostToNet32Impl(x);
+}
+
+inline uint64_t SpdyHostToNet64(uint64_t x) {
+  return SpdyHostToNet64Impl(x);
+}
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_ENDIANNESS_UTIL_H_
diff --git a/spdy/platform/api/spdy_estimate_memory_usage.h b/spdy/platform/api/spdy_estimate_memory_usage.h
new file mode 100644
index 0000000..6aa53c3
--- /dev/null
+++ b/spdy/platform/api/spdy_estimate_memory_usage.h
@@ -0,0 +1,21 @@
+// Copyright 2017 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_ESTIMATE_MEMORY_USAGE_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_ESTIMATE_MEMORY_USAGE_H_
+
+#include <cstddef>
+
+#include "net/spdy/platform/impl/spdy_estimate_memory_usage_impl.h"
+
+namespace spdy {
+
+template <class T>
+size_t SpdyEstimateMemoryUsage(const T& object) {
+  return SpdyEstimateMemoryUsageImpl(object);
+}
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_ESTIMATE_MEMORY_USAGE_H_
diff --git a/spdy/platform/api/spdy_export.h b/spdy/platform/api/spdy_export.h
new file mode 100644
index 0000000..ba92f79
--- /dev/null
+++ b/spdy/platform/api/spdy_export.h
@@ -0,0 +1,10 @@
+// Copyright 2017 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_EXPORT_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_EXPORT_H_
+
+#include "net/spdy/platform/impl/spdy_export_impl.h"
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_EXPORT_H_
diff --git a/spdy/platform/api/spdy_flags.h b/spdy/platform/api/spdy_flags.h
new file mode 100644
index 0000000..f3446d9
--- /dev/null
+++ b/spdy/platform/api/spdy_flags.h
@@ -0,0 +1,13 @@
+// Copyright 2018 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_FLAGS_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_FLAGS_H_
+
+#include "net/spdy/platform/impl/spdy_flags_impl.h"
+
+#define GetSpdyReloadableFlag(flag) GetSpdyReloadableFlagImpl(flag)
+#define GetSpdyRestartFlag(flag) GetSpdyRestartFlagImpl(flag)
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_FLAGS_H_
diff --git a/spdy/platform/api/spdy_macros.h b/spdy/platform/api/spdy_macros.h
new file mode 100644
index 0000000..a75c957
--- /dev/null
+++ b/spdy/platform/api/spdy_macros.h
@@ -0,0 +1,15 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_MACROS_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_MACROS_H_
+
+#include "net/spdy/platform/impl/spdy_macros_impl.h"
+
+#define SPDY_MUST_USE_RESULT SPDY_MUST_USE_RESULT_IMPL
+#define SPDY_UNUSED SPDY_UNUSED_IMPL
+
+#define SPDY_DVLOG_IF SPDY_DVLOG_IF_IMPL
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_MACROS_H_
diff --git a/spdy/platform/api/spdy_mem_slice.h b/spdy/platform/api/spdy_mem_slice.h
new file mode 100644
index 0000000..0d67c00
--- /dev/null
+++ b/spdy/platform/api/spdy_mem_slice.h
@@ -0,0 +1,54 @@
+// Copyright 2017 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_MEM_SLICE_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_MEM_SLICE_H_
+
+#include <utility>
+
+#include "net/third_party/quiche/src/spdy/platform/api/spdy_export.h"
+#include "net/spdy/platform/impl/spdy_mem_slice_impl.h"
+
+namespace spdy {
+
+// SpdyMemSlice is an internally reference counted data buffer used as the
+// source buffers for write operations. SpdyMemSlice implicitly maintains a
+// reference count and will free the underlying data buffer when the reference
+// count reaches zero.
+class SPDY_EXPORT_PRIVATE SpdyMemSlice {
+ public:
+  // Constructs an empty SpdyMemSlice with no underlying data and 0 reference
+  // count.
+  SpdyMemSlice() = default;
+
+  // Constructs a SpdyMemSlice with reference count 1 to a newly allocated data
+  // buffer of |length| bytes.
+  explicit SpdyMemSlice(size_t length) : impl_(length) {}
+
+  // Constructs a SpdyMemSlice from |impl|. It takes the reference away from
+  // |impl|.
+  explicit SpdyMemSlice(SpdyMemSliceImpl impl) : impl_(std::move(impl)) {}
+
+  SpdyMemSlice(const SpdyMemSlice& other) = delete;
+  SpdyMemSlice& operator=(const SpdyMemSlice& other) = delete;
+
+  // Move constructors. |other| will not hold a reference to the data buffer
+  // after this call completes.
+  SpdyMemSlice(SpdyMemSlice&& other) = default;
+  SpdyMemSlice& operator=(SpdyMemSlice&& other) = default;
+
+  ~SpdyMemSlice() = default;
+
+  // Returns a char pointer to underlying data buffer.
+  const char* data() const { return impl_.data(); }
+  // Returns the length of underlying data buffer.
+  size_t length() const { return impl_.length(); }
+
+ private:
+  SpdyMemSliceImpl impl_;
+};
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_MEM_SLICE_H_
diff --git a/spdy/platform/api/spdy_mem_slice_test.cc b/spdy/platform/api/spdy_mem_slice_test.cc
new file mode 100644
index 0000000..af323f6
--- /dev/null
+++ b/spdy/platform/api/spdy_mem_slice_test.cc
@@ -0,0 +1,47 @@
+// Copyright 2017 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 "net/third_party/quiche/src/spdy/platform/api/spdy_mem_slice.h"
+
+#include <utility>
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace spdy {
+namespace test {
+namespace {
+
+class SpdyMemSliceTest : public ::testing::Test {
+ public:
+  SpdyMemSliceTest() {
+    slice_ = SpdyMemSlice(1024);
+    orig_data_ = slice_.data();
+    orig_length_ = slice_.length();
+  }
+
+  SpdyMemSlice slice_;
+  const char* orig_data_;
+  size_t orig_length_;
+};
+
+TEST_F(SpdyMemSliceTest, MoveConstruct) {
+  SpdyMemSlice moved(std::move(slice_));
+  EXPECT_EQ(moved.data(), orig_data_);
+  EXPECT_EQ(moved.length(), orig_length_);
+  EXPECT_EQ(nullptr, slice_.data());
+  EXPECT_EQ(0u, slice_.length());
+}
+
+TEST_F(SpdyMemSliceTest, MoveAssign) {
+  SpdyMemSlice moved;
+  moved = std::move(slice_);
+  EXPECT_EQ(moved.data(), orig_data_);
+  EXPECT_EQ(moved.length(), orig_length_);
+  EXPECT_EQ(nullptr, slice_.data());
+  EXPECT_EQ(0u, slice_.length());
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace spdy
diff --git a/spdy/platform/api/spdy_ptr_util.h b/spdy/platform/api/spdy_ptr_util.h
new file mode 100644
index 0000000..32b8515
--- /dev/null
+++ b/spdy/platform/api/spdy_ptr_util.h
@@ -0,0 +1,27 @@
+// Copyright 2017 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_PTR_UTIL_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_PTR_UTIL_H_
+
+#include <memory>
+#include <utility>
+
+#include "net/spdy/platform/impl/spdy_ptr_util_impl.h"
+
+namespace spdy {
+
+template <typename T, typename... Args>
+std::unique_ptr<T> SpdyMakeUnique(Args&&... args) {
+  return SpdyMakeUniqueImpl<T>(std::forward<Args>(args)...);
+}
+
+template <typename T>
+std::unique_ptr<T> SpdyWrapUnique(T* ptr) {
+  return SpdyWrapUniqueImpl<T>(ptr);
+}
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_PTR_UTIL_H_
diff --git a/spdy/platform/api/spdy_string.h b/spdy/platform/api/spdy_string.h
new file mode 100644
index 0000000..16eb9e5
--- /dev/null
+++ b/spdy/platform/api/spdy_string.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_STRING_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_STRING_H_
+
+#include "net/spdy/platform/impl/spdy_string_impl.h"
+
+namespace spdy {
+
+using SpdyString = SpdyStringImpl;
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_STRING_H_
diff --git a/spdy/platform/api/spdy_string_piece.h b/spdy/platform/api/spdy_string_piece.h
new file mode 100644
index 0000000..37eea70
--- /dev/null
+++ b/spdy/platform/api/spdy_string_piece.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2017 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_STRING_PIECE_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_STRING_PIECE_H_
+
+#include "net/spdy/platform/impl/spdy_string_piece_impl.h"
+
+namespace spdy {
+
+using SpdyStringPiece = SpdyStringPieceImpl;
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_STRING_PIECE_H_
diff --git a/spdy/platform/api/spdy_string_utils.h b/spdy/platform/api/spdy_string_utils.h
new file mode 100644
index 0000000..7554f79
--- /dev/null
+++ b/spdy/platform/api/spdy_string_utils.h
@@ -0,0 +1,58 @@
+// Copyright 2017 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_STRING_UTILS_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_STRING_UTILS_H_
+
+#include <utility>
+
+// The following header file has to be included from at least
+// non-test file in order to avoid strange linking errors.
+// TODO(bnc): Remove this include as soon as it is included elsewhere in
+// non-test code.
+#include "net/third_party/quiche/src/spdy/platform/api/spdy_mem_slice.h"
+
+#include "net/third_party/quiche/src/spdy/platform/api/spdy_string.h"
+#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_piece.h"
+#include "net/spdy/platform/impl/spdy_string_utils_impl.h"
+
+namespace spdy {
+
+template <typename... Args>
+inline SpdyString SpdyStrCat(const Args&... args) {
+  return SpdyStrCatImpl(std::forward<const Args&>(args)...);
+}
+
+template <typename... Args>
+inline void SpdyStrAppend(SpdyString* output, const Args&... args) {
+  SpdyStrAppendImpl(output, std::forward<const Args&>(args)...);
+}
+
+inline char SpdyHexDigitToInt(char c) {
+  return SpdyHexDigitToIntImpl(c);
+}
+
+inline SpdyString SpdyHexDecode(SpdyStringPiece data) {
+  return SpdyHexDecodeImpl(data);
+}
+
+inline bool SpdyHexDecodeToUInt32(SpdyStringPiece data, uint32_t* out) {
+  return SpdyHexDecodeToUInt32Impl(data, out);
+}
+
+inline SpdyString SpdyHexEncode(const char* bytes, size_t size) {
+  return SpdyHexEncodeImpl(bytes, size);
+}
+
+inline SpdyString SpdyHexEncodeUInt32AndTrim(uint32_t data) {
+  return SpdyHexEncodeUInt32AndTrimImpl(data);
+}
+
+inline SpdyString SpdyHexDump(SpdyStringPiece data) {
+  return SpdyHexDumpImpl(data);
+}
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_STRING_UTILS_H_
diff --git a/spdy/platform/api/spdy_string_utils_test.cc b/spdy/platform/api/spdy_string_utils_test.cc
new file mode 100644
index 0000000..3f7e6a1
--- /dev/null
+++ b/spdy/platform/api/spdy_string_utils_test.cc
@@ -0,0 +1,242 @@
+// Copyright 2017 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 "net/third_party/quiche/src/spdy/platform/api/spdy_string_utils.h"
+
+#include <cstdint>
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_piece.h"
+
+namespace spdy {
+namespace test {
+namespace {
+
+TEST(SpdyStringUtilsTest, SpdyStrCat) {
+  // No arguments.
+  EXPECT_EQ("", SpdyStrCat());
+
+  // Single string-like argument.
+  const char kFoo[] = "foo";
+  const SpdyString string_foo(kFoo);
+  const SpdyStringPiece stringpiece_foo(string_foo);
+  EXPECT_EQ("foo", SpdyStrCat(kFoo));
+  EXPECT_EQ("foo", SpdyStrCat(string_foo));
+  EXPECT_EQ("foo", SpdyStrCat(stringpiece_foo));
+
+  // Two string-like arguments.
+  const char kBar[] = "bar";
+  const SpdyStringPiece stringpiece_bar(kBar);
+  const SpdyString string_bar(kBar);
+  EXPECT_EQ("foobar", SpdyStrCat(kFoo, kBar));
+  EXPECT_EQ("foobar", SpdyStrCat(kFoo, string_bar));
+  EXPECT_EQ("foobar", SpdyStrCat(kFoo, stringpiece_bar));
+  EXPECT_EQ("foobar", SpdyStrCat(string_foo, kBar));
+  EXPECT_EQ("foobar", SpdyStrCat(string_foo, string_bar));
+  EXPECT_EQ("foobar", SpdyStrCat(string_foo, stringpiece_bar));
+  EXPECT_EQ("foobar", SpdyStrCat(stringpiece_foo, kBar));
+  EXPECT_EQ("foobar", SpdyStrCat(stringpiece_foo, string_bar));
+  EXPECT_EQ("foobar", SpdyStrCat(stringpiece_foo, stringpiece_bar));
+
+  // Many-many arguments.
+  EXPECT_EQ(
+      "foobarbazquxquuxquuzcorgegraultgarplywaldofredplughxyzzythud",
+      SpdyStrCat("foo", "bar", "baz", "qux", "quux", "quuz", "corge", "grault",
+                 "garply", "waldo", "fred", "plugh", "xyzzy", "thud"));
+
+  // Numerical arguments.
+  const int16_t i = 1;
+  const uint64_t u = 8;
+  const double d = 3.1415;
+
+  EXPECT_EQ("1 8", SpdyStrCat(i, " ", u));
+  EXPECT_EQ("3.14151181", SpdyStrCat(d, i, i, u, i));
+  EXPECT_EQ("i: 1, u: 8, d: 3.1415",
+            SpdyStrCat("i: ", i, ", u: ", u, ", d: ", d));
+
+  // Boolean arguments.
+  const bool t = true;
+  const bool f = false;
+
+  EXPECT_EQ("1", SpdyStrCat(t));
+  EXPECT_EQ("0", SpdyStrCat(f));
+  EXPECT_EQ("0110", SpdyStrCat(f, t, t, f));
+
+  // Mixed string-like, numerical, and Boolean arguments.
+  EXPECT_EQ("foo1foo081bar3.14151",
+            SpdyStrCat(kFoo, i, string_foo, f, u, t, stringpiece_bar, d, t));
+  EXPECT_EQ("3.141511bar18bar13.14150",
+            SpdyStrCat(d, t, t, string_bar, i, u, kBar, t, d, f));
+}
+
+TEST(SpdyStringUtilsTest, SpdyStrAppend) {
+  // No arguments on empty string.
+  SpdyString output;
+  SpdyStrAppend(&output);
+  EXPECT_TRUE(output.empty());
+
+  // Single string-like argument.
+  const char kFoo[] = "foo";
+  const SpdyString string_foo(kFoo);
+  const SpdyStringPiece stringpiece_foo(string_foo);
+  SpdyStrAppend(&output, kFoo);
+  EXPECT_EQ("foo", output);
+  SpdyStrAppend(&output, string_foo);
+  EXPECT_EQ("foofoo", output);
+  SpdyStrAppend(&output, stringpiece_foo);
+  EXPECT_EQ("foofoofoo", output);
+
+  // No arguments on non-empty string.
+  SpdyStrAppend(&output);
+  EXPECT_EQ("foofoofoo", output);
+
+  output.clear();
+
+  // Two string-like arguments.
+  const char kBar[] = "bar";
+  const SpdyStringPiece stringpiece_bar(kBar);
+  const SpdyString string_bar(kBar);
+  SpdyStrAppend(&output, kFoo, kBar);
+  EXPECT_EQ("foobar", output);
+  SpdyStrAppend(&output, kFoo, string_bar);
+  EXPECT_EQ("foobarfoobar", output);
+  SpdyStrAppend(&output, kFoo, stringpiece_bar);
+  EXPECT_EQ("foobarfoobarfoobar", output);
+  SpdyStrAppend(&output, string_foo, kBar);
+  EXPECT_EQ("foobarfoobarfoobarfoobar", output);
+
+  output.clear();
+
+  SpdyStrAppend(&output, string_foo, string_bar);
+  EXPECT_EQ("foobar", output);
+  SpdyStrAppend(&output, string_foo, stringpiece_bar);
+  EXPECT_EQ("foobarfoobar", output);
+  SpdyStrAppend(&output, stringpiece_foo, kBar);
+  EXPECT_EQ("foobarfoobarfoobar", output);
+  SpdyStrAppend(&output, stringpiece_foo, string_bar);
+  EXPECT_EQ("foobarfoobarfoobarfoobar", output);
+
+  output.clear();
+
+  SpdyStrAppend(&output, stringpiece_foo, stringpiece_bar);
+  EXPECT_EQ("foobar", output);
+
+  // Many-many arguments.
+  SpdyStrAppend(&output, "foo", "bar", "baz", "qux", "quux", "quuz", "corge",
+                "grault", "garply", "waldo", "fred", "plugh", "xyzzy", "thud");
+  EXPECT_EQ(
+      "foobarfoobarbazquxquuxquuzcorgegraultgarplywaldofredplughxyzzythud",
+      output);
+
+  output.clear();
+
+  // Numerical arguments.
+  const int16_t i = 1;
+  const uint64_t u = 8;
+  const double d = 3.1415;
+
+  SpdyStrAppend(&output, i, " ", u);
+  EXPECT_EQ("1 8", output);
+  SpdyStrAppend(&output, d, i, i, u, i);
+  EXPECT_EQ("1 83.14151181", output);
+  SpdyStrAppend(&output, "i: ", i, ", u: ", u, ", d: ", d);
+  EXPECT_EQ("1 83.14151181i: 1, u: 8, d: 3.1415", output);
+
+  output.clear();
+
+  // Boolean arguments.
+  const bool t = true;
+  const bool f = false;
+
+  SpdyStrAppend(&output, t);
+  EXPECT_EQ("1", output);
+  SpdyStrAppend(&output, f);
+  EXPECT_EQ("10", output);
+  SpdyStrAppend(&output, f, t, t, f);
+  EXPECT_EQ("100110", output);
+
+  output.clear();
+
+  // Mixed string-like, numerical, and Boolean arguments.
+  SpdyStrAppend(&output, kFoo, i, string_foo, f, u, t, stringpiece_bar, d, t);
+  EXPECT_EQ("foo1foo081bar3.14151", output);
+  SpdyStrAppend(&output, d, t, t, string_bar, i, u, kBar, t, d, f);
+  EXPECT_EQ("foo1foo081bar3.141513.141511bar18bar13.14150", output);
+}
+
+TEST(SpdyStringUtilsTest, SpdyHexDigitToInt) {
+  EXPECT_EQ(0, SpdyHexDigitToInt('0'));
+  EXPECT_EQ(1, SpdyHexDigitToInt('1'));
+  EXPECT_EQ(2, SpdyHexDigitToInt('2'));
+  EXPECT_EQ(3, SpdyHexDigitToInt('3'));
+  EXPECT_EQ(4, SpdyHexDigitToInt('4'));
+  EXPECT_EQ(5, SpdyHexDigitToInt('5'));
+  EXPECT_EQ(6, SpdyHexDigitToInt('6'));
+  EXPECT_EQ(7, SpdyHexDigitToInt('7'));
+  EXPECT_EQ(8, SpdyHexDigitToInt('8'));
+  EXPECT_EQ(9, SpdyHexDigitToInt('9'));
+
+  EXPECT_EQ(10, SpdyHexDigitToInt('a'));
+  EXPECT_EQ(11, SpdyHexDigitToInt('b'));
+  EXPECT_EQ(12, SpdyHexDigitToInt('c'));
+  EXPECT_EQ(13, SpdyHexDigitToInt('d'));
+  EXPECT_EQ(14, SpdyHexDigitToInt('e'));
+  EXPECT_EQ(15, SpdyHexDigitToInt('f'));
+
+  EXPECT_EQ(10, SpdyHexDigitToInt('A'));
+  EXPECT_EQ(11, SpdyHexDigitToInt('B'));
+  EXPECT_EQ(12, SpdyHexDigitToInt('C'));
+  EXPECT_EQ(13, SpdyHexDigitToInt('D'));
+  EXPECT_EQ(14, SpdyHexDigitToInt('E'));
+  EXPECT_EQ(15, SpdyHexDigitToInt('F'));
+}
+
+TEST(SpdyStringUtilsTest, SpdyHexDecodeToUInt32) {
+  uint32_t out;
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("0", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("00", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("0000000", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("00000000", &out));
+  EXPECT_EQ(0u, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("1", &out));
+  EXPECT_EQ(1u, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("ffffFFF", &out));
+  EXPECT_EQ(0xFFFFFFFu, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("fFfFffFf", &out));
+  EXPECT_EQ(0xFFFFFFFFu, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("01AEF", &out));
+  EXPECT_EQ(0x1AEFu, out);
+  EXPECT_TRUE(SpdyHexDecodeToUInt32("abcde", &out));
+  EXPECT_EQ(0xABCDEu, out);
+
+  EXPECT_FALSE(SpdyHexDecodeToUInt32("", &out));
+  EXPECT_FALSE(SpdyHexDecodeToUInt32("111111111", &out));
+  EXPECT_FALSE(SpdyHexDecodeToUInt32("1111111111", &out));
+  EXPECT_FALSE(SpdyHexDecodeToUInt32("0x1111", &out));
+}
+
+TEST(SpdyStringUtilsTest, SpdyHexEncode) {
+  unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81};
+  EXPECT_EQ("01ff02fe038081",
+            SpdyHexEncode(reinterpret_cast<char*>(bytes), sizeof(bytes)));
+}
+
+TEST(SpdyStringUtilsTest, SpdyHexEncodeUInt32AndTrim) {
+  EXPECT_EQ("0", SpdyHexEncodeUInt32AndTrim(0));
+  EXPECT_EQ("1", SpdyHexEncodeUInt32AndTrim(1));
+  EXPECT_EQ("a", SpdyHexEncodeUInt32AndTrim(0xA));
+  EXPECT_EQ("f", SpdyHexEncodeUInt32AndTrim(0xF));
+  EXPECT_EQ("a9", SpdyHexEncodeUInt32AndTrim(0xA9));
+  EXPECT_EQ("9abcdef", SpdyHexEncodeUInt32AndTrim(0x9ABCDEF));
+  EXPECT_EQ("12345678", SpdyHexEncodeUInt32AndTrim(0x12345678));
+  EXPECT_EQ("ffffffff", SpdyHexEncodeUInt32AndTrim(0xFFFFFFFF));
+  EXPECT_EQ("10000001", SpdyHexEncodeUInt32AndTrim(0x10000001));
+}
+
+}  // namespace
+}  // namespace test
+}  // namespace spdy
diff --git a/spdy/platform/api/spdy_test_helpers.h b/spdy/platform/api/spdy_test_helpers.h
new file mode 100644
index 0000000..367d330
--- /dev/null
+++ b/spdy/platform/api/spdy_test_helpers.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_TEST_HELPERS_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_TEST_HELPERS_H_
+
+#include "net/spdy/platform/impl/spdy_test_helpers_impl.h"
+
+#define EXPECT_SPDY_BUG EXPECT_SPDY_BUG_IMPL
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_TEST_HELPERS_H_
diff --git a/spdy/platform/api/spdy_test_utils_prod.h b/spdy/platform/api/spdy_test_utils_prod.h
new file mode 100644
index 0000000..1466770
--- /dev/null
+++ b/spdy/platform/api/spdy_test_utils_prod.h
@@ -0,0 +1,12 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_TEST_UTILS_PROD_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_TEST_UTILS_PROD_H_
+
+#include "net/spdy/platform/impl/spdy_test_utils_prod_impl.h"
+
+#define SPDY_FRIEND_TEST SPDY_FRIEND_TEST_IMPL
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_TEST_UTILS_PROD_H_
diff --git a/spdy/platform/api/spdy_unsafe_arena.h b/spdy/platform/api/spdy_unsafe_arena.h
new file mode 100644
index 0000000..77185e1
--- /dev/null
+++ b/spdy/platform/api/spdy_unsafe_arena.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2019 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.
+
+#ifndef QUICHE_SPDY_PLATFORM_API_SPDY_UNSAFE_ARENA_H_
+#define QUICHE_SPDY_PLATFORM_API_SPDY_UNSAFE_ARENA_H_
+
+#include "net/spdy/platform/impl/spdy_unsafe_arena_impl.h"
+
+namespace spdy {
+
+using SpdyUnsafeArena = SpdyUnsafeArenaImpl;
+
+}  // namespace spdy
+
+#endif  // QUICHE_SPDY_PLATFORM_API_SPDY_UNSAFE_ARENA_H_