Adds a new SpdySerializedFrame constructor that makes memory ownership clear.
Also migrates all uses of the old constructor.
A future change will remove the old constructor along with the `owns_buffer_` member.
Protected by refactoring, not protected.
PiperOrigin-RevId: 623626698
diff --git a/quiche/spdy/core/spdy_frame_builder.h b/quiche/spdy/core/spdy_frame_builder.h
index 69cf352..52cb1b0 100644
--- a/quiche/spdy/core/spdy_frame_builder.h
+++ b/quiche/spdy/core/spdy_frame_builder.h
@@ -68,7 +68,7 @@
QUICHE_BUG_IF(spdy_bug_39_2, kMaxFrameSizeLimit < length_)
<< "Frame length " << length_
<< " is longer than the maximum possible allowed length.";
- SpdySerializedFrame rv(buffer_.release(), length(), true);
+ SpdySerializedFrame rv(std::move(buffer_), length());
capacity_ = 0;
length_ = 0;
offset_ = 0;
diff --git a/quiche/spdy/core/spdy_frame_builder_test.cc b/quiche/spdy/core/spdy_frame_builder_test.cc
index 60e12c8..647d084 100644
--- a/quiche/spdy/core/spdy_frame_builder_test.cc
+++ b/quiche/spdy/core/spdy_frame_builder_test.cc
@@ -13,6 +13,7 @@
#include "quiche/common/platform/api/quiche_test.h"
#include "quiche/spdy/core/array_output_buffer.h"
#include "quiche/spdy/core/spdy_protocol.h"
+#include "quiche/spdy/test_tools/spdy_test_utils.h"
namespace spdy {
@@ -49,8 +50,7 @@
SpdySerializedFrame frame(builder.take());
char expected[kBuilderSize];
memset(expected, ~1, kBuilderSize);
- EXPECT_EQ(absl::string_view(expected, kBuilderSize),
- absl::string_view(frame.data(), kBuilderSize));
+ EXPECT_EQ(absl::string_view(expected, kBuilderSize), frame);
}
// Verifies that SpdyFrameBuilder::GetWritableBuffer() can be used to build a
@@ -64,11 +64,10 @@
&builder, kBuilderSize, &actual_size);
memset(writable_buffer, ~1, kBuilderSize);
EXPECT_TRUE(builder.Seek(kBuilderSize));
- SpdySerializedFrame frame(output.Begin(), kBuilderSize, false);
+ SpdySerializedFrame frame = MakeSerializedFrame(output.Begin(), kBuilderSize);
char expected[kBuilderSize];
memset(expected, ~1, kBuilderSize);
- EXPECT_EQ(absl::string_view(expected, kBuilderSize),
- absl::string_view(frame.data(), kBuilderSize));
+ EXPECT_EQ(absl::string_view(expected, kBuilderSize), frame);
}
// Verifies the case that the buffer's capacity is too small.
diff --git a/quiche/spdy/core/spdy_framer_test.cc b/quiche/spdy/core/spdy_framer_test.cc
index 56d0207..d9283de 100644
--- a/quiche/spdy/core/spdy_framer_test.cc
+++ b/quiche/spdy/core/spdy_framer_test.cc
@@ -119,8 +119,8 @@
size_t size_before = frame_list_buffer.Size();
EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
frame_list.emplace_back(
- SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
- frame_list_buffer.Size() - size_before, false));
+ MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
+ frame_list_buffer.Size() - size_before));
}
framer->debug_visitor_ = saved_debug_visitor;
@@ -136,8 +136,8 @@
}
output->Reset();
EXPECT_TRUE(framer->SerializeHeaders(headers, output));
- SpdySerializedFrame serialized_headers_old_version(output->Begin(),
- output->Size(), false);
+ SpdySerializedFrame serialized_headers_old_version =
+ MakeSerializedFrame(output->Begin(), output->Size());
framer->hpack_encoder_.reset(nullptr);
auto* saved_debug_visitor = framer->debug_visitor_;
framer->debug_visitor_ = nullptr;
@@ -149,8 +149,8 @@
size_t size_before = frame_list_buffer.Size();
EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
frame_list.emplace_back(
- SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
- frame_list_buffer.Size() - size_before, false));
+ MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
+ frame_list_buffer.Size() - size_before));
}
framer->debug_visitor_ = saved_debug_visitor;
@@ -187,8 +187,8 @@
size_t size_before = frame_list_buffer.Size();
EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
frame_list.emplace_back(
- SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
- frame_list_buffer.Size() - size_before, false));
+ MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
+ frame_list_buffer.Size() - size_before));
}
framer->debug_visitor_ = saved_debug_visitor;
@@ -219,8 +219,8 @@
size_t size_before = frame_list_buffer.Size();
EXPECT_GT(it.NextFrame(&frame_list_buffer), 0u);
frame_list.emplace_back(
- SpdySerializedFrame(frame_list_buffer.Begin() + size_before,
- frame_list_buffer.Size() - size_before, false));
+ MakeSerializedFrame(frame_list_buffer.Begin() + size_before,
+ frame_list_buffer.Size() - size_before));
}
framer->debug_visitor_ = saved_debug_visitor;
@@ -983,7 +983,7 @@
SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
if (use_output_) {
EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
// We shouldn't have to read the whole frame before we signal an error.
@@ -1008,7 +1008,7 @@
SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream_ir));
if (use_output_) {
EXPECT_TRUE(framer_.SerializeRstStream(rst_stream_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
// We shouldn't have to read the whole frame before we signal an error.
@@ -1097,7 +1097,7 @@
SpdySerializedFrame frame(framer_.SerializeContinuation(continuation));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeContinuation(continuation, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
// We shouldn't have to read the whole frame before we signal an error.
@@ -1498,7 +1498,7 @@
SpdySerializedFrame frame(framer_.SerializeWindowUpdate(window_update));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeWindowUpdate(window_update, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
const char kDescription[] = "WINDOW_UPDATE frame, stream 1, delta 0x12345678";
@@ -1738,7 +1738,7 @@
SpdySerializedFrame frame(framer_.SerializeRstStream(rst_stream));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -1759,7 +1759,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -1780,7 +1780,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -1808,7 +1808,7 @@
SpdySerializedFrame frame(framer_.SerializeSettings(settings_ir));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -1843,7 +1843,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
@@ -1863,7 +1863,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
@@ -1897,7 +1897,7 @@
SpdySerializedFrame frame(framer_.SerializePing(ping_ir));
if (use_output_) {
ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -1908,7 +1908,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializePing(ping_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameDataWithAck,
ABSL_ARRAYSIZE(kH2FrameDataWithAck));
@@ -1932,7 +1932,7 @@
SpdySerializedFrame frame(framer_.SerializeGoAway(goaway_ir));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -1955,7 +1955,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -2232,7 +2232,7 @@
output_.Reset();
ASSERT_TRUE(framer_.SerializeWindowUpdate(
SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 1), &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -2254,7 +2254,7 @@
ASSERT_TRUE(framer_.SerializeWindowUpdate(
SpdyWindowUpdateIR(/* stream_id = */ 0x7FFFFFFF, /* delta = */ 1),
&output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -2276,7 +2276,7 @@
ASSERT_TRUE(framer_.SerializeWindowUpdate(
SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 0x7FFFFFFF),
&output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kH2FrameData,
ABSL_ARRAYSIZE(kH2FrameData));
@@ -2468,7 +2468,7 @@
SpdySerializedFrame frame(framer.SerializeContinuation(continuation));
if (use_output_) {
ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
}
@@ -2637,7 +2637,7 @@
SpdySerializedFrame frame(framer_.SerializeFrame(altsvc_ir));
if (use_output_) {
EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
}
@@ -2659,7 +2659,7 @@
SpdySerializedFrame frame(framer_.SerializeFrame(priority_ir));
if (use_output_) {
EXPECT_EQ(framer_.SerializeFrame(priority_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
}
@@ -2682,7 +2682,7 @@
if (use_output_) {
EXPECT_EQ(framer_.SerializeFrame(priority_update_ir, &output_),
frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
}
@@ -2712,7 +2712,7 @@
SpdySerializedFrame frame(framer_.SerializeFrame(accept_ch_ir));
if (use_output_) {
EXPECT_EQ(framer_.SerializeFrame(accept_ch_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
}
@@ -2739,7 +2739,7 @@
SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
if (use_output_) {
EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
}
@@ -2771,7 +2771,7 @@
SpdySerializedFrame frame(framer_.SerializeFrame(unknown_ir));
if (use_output_) {
EXPECT_EQ(framer_.SerializeFrame(unknown_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
CompareFrame(kDescription, frame, kFrameData, ABSL_ARRAYSIZE(kFrameData));
}
@@ -3120,7 +3120,7 @@
SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
SetFrameLength(&control_frame, 0);
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
@@ -3143,7 +3143,7 @@
SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
const size_t kNewLength = 8;
SetFrameLength(&control_frame, kNewLength);
@@ -3170,7 +3170,7 @@
SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
@@ -3398,7 +3398,7 @@
if (use_output_) {
ASSERT_TRUE(framer_.SerializeWindowUpdate(
SpdyWindowUpdateIR(/* stream_id = */ 1, /* delta = */ 2), &output_));
- control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
TestSpdyVisitor visitor(SpdyFramer::DISABLE_COMPRESSION);
visitor.SimulateInFramer(
@@ -3840,7 +3840,7 @@
SpdySerializedFrame control_frame(framer_.SerializeSettings(settings_ir));
if (use_output_) {
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- control_frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ control_frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
visitor.SimulateInFramer(
reinterpret_cast<unsigned char*>(control_frame.data()),
@@ -4091,7 +4091,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeRstStream(rst_stream, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
SetFrameFlags(&frame, flags);
@@ -4123,7 +4123,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeSettings(settings_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
SetFrameFlags(&frame, flags);
@@ -4171,7 +4171,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializeGoAway(goaway_ir, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
SetFrameFlags(&frame, flags);
@@ -4379,7 +4379,7 @@
SpdySerializedFrame frame0;
if (use_output_) {
EXPECT_TRUE(framer.SerializeHeaders(headers_ir, &output_));
- frame0 = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame0 = MakeSerializedFrame(output_.Begin(), output_.Size());
} else {
frame0 = framer.SerializeHeaders(headers_ir);
}
@@ -4390,8 +4390,7 @@
if (use_output_) {
char* begin = output_.Begin() + output_.Size();
ASSERT_TRUE(framer.SerializeContinuation(continuation, &output_));
- frame1 =
- SpdySerializedFrame(begin, output_.Size() - frame0.size(), false);
+ frame1 = MakeSerializedFrame(begin, output_.Size() - frame0.size());
} else {
frame1 = framer.SerializeContinuation(continuation);
}
@@ -4537,7 +4536,7 @@
if (use_output_) {
output_.Reset();
EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
deframer_->ProcessInput(frame.data(), frame.size());
@@ -4598,7 +4597,7 @@
if (use_output_) {
output_.Reset();
EXPECT_EQ(framer_.SerializeFrame(altsvc_ir, &output_), frame.size());
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
deframer_->ProcessInput(frame.data(), frame.size());
@@ -4842,7 +4841,7 @@
if (use_output_) {
output_.Reset();
ASSERT_TRUE(framer_.SerializePriority(priority, &output_));
- frame = SpdySerializedFrame(output_.Begin(), output_.Size(), false);
+ frame = MakeSerializedFrame(output_.Begin(), output_.Size());
}
testing::StrictMock<test::MockSpdyFramerVisitor> visitor;
deframer_->set_visitor(&visitor);
diff --git a/quiche/spdy/core/spdy_protocol.h b/quiche/spdy/core/spdy_protocol.h
index 3e9dd34..ebcb21a 100644
--- a/quiche/spdy/core/spdy_protocol.h
+++ b/quiche/spdy/core/spdy_protocol.h
@@ -996,6 +996,10 @@
SpdySerializedFrame()
: frame_(const_cast<char*>("")), size_(0), owns_buffer_(false) {}
+ // Creates a valid SpdySerializedFrame using a pre-created buffer.
+ SpdySerializedFrame(std::unique_ptr<char[]> data, size_t size)
+ : frame_(data.release()), size_(size), owns_buffer_(true) {}
+
// Create a valid SpdySerializedFrame using a pre-created buffer.
// If |owns_buffer| is true, this class takes ownership of the buffer and will
// delete it on cleanup. The buffer must have been created using new char[].
@@ -1063,10 +1067,8 @@
return buffer;
}
- protected:
- char* frame_;
-
private:
+ char* frame_;
size_t size_;
bool owns_buffer_;
};
diff --git a/quiche/spdy/test_tools/spdy_test_utils.cc b/quiche/spdy/test_tools/spdy_test_utils.cc
index 43d97d0..fed9c16 100644
--- a/quiche/spdy/test_tools/spdy_test_utils.cc
+++ b/quiche/spdy/test_tools/spdy_test_utils.cc
@@ -97,5 +97,11 @@
}
}
+SpdySerializedFrame MakeSerializedFrame(const char* data, size_t length) {
+ std::unique_ptr<char[]> copy = std::make_unique<char[]>(length);
+ std::copy(data, data + length, copy.get());
+ return SpdySerializedFrame(std::move(copy), length);
+}
+
} // namespace test
} // namespace spdy
diff --git a/quiche/spdy/test_tools/spdy_test_utils.h b/quiche/spdy/test_tools/spdy_test_utils.h
index 366f249..5cf40cf 100644
--- a/quiche/spdy/test_tools/spdy_test_utils.h
+++ b/quiche/spdy/test_tools/spdy_test_utils.h
@@ -35,6 +35,10 @@
void SetFrameLength(SpdySerializedFrame* frame, size_t length);
+// Makes a SpdySerializedFrame by copying the memory identified by `data` and
+// `length`.
+SpdySerializedFrame MakeSerializedFrame(const char* data, size_t length);
+
} // namespace test
} // namespace spdy