Project import generated by Copybara.
PiperOrigin-RevId: 229942388
Change-Id: Ib5a23c152c95ed4294cece9f902227c21ce531ef
diff --git a/spdy/core/spdy_prefixed_buffer_reader.cc b/spdy/core/spdy_prefixed_buffer_reader.cc
new file mode 100644
index 0000000..9f1fa7f
--- /dev/null
+++ b/spdy/core/spdy_prefixed_buffer_reader.cc
@@ -0,0 +1,84 @@
+// Copyright 2014 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/core/spdy_prefixed_buffer_reader.h"
+
+#include <new>
+
+#include "base/logging.h"
+
+namespace spdy {
+
+SpdyPrefixedBufferReader::SpdyPrefixedBufferReader(const char* prefix,
+ size_t prefix_length,
+ const char* suffix,
+ size_t suffix_length)
+ : prefix_(prefix),
+ suffix_(suffix),
+ prefix_length_(prefix_length),
+ suffix_length_(suffix_length) {}
+
+size_t SpdyPrefixedBufferReader::Available() {
+ return prefix_length_ + suffix_length_;
+}
+
+bool SpdyPrefixedBufferReader::ReadN(size_t count, char* out) {
+ if (Available() < count) {
+ return false;
+ }
+
+ if (prefix_length_ >= count) {
+ // Read is fully satisfied by the prefix.
+ std::copy(prefix_, prefix_ + count, out);
+ prefix_ += count;
+ prefix_length_ -= count;
+ return true;
+ } else if (prefix_length_ != 0) {
+ // Read is partially satisfied by the prefix.
+ out = std::copy(prefix_, prefix_ + prefix_length_, out);
+ count -= prefix_length_;
+ prefix_length_ = 0;
+ // Fallthrough to suffix read.
+ }
+ DCHECK(suffix_length_ >= count);
+ // Read is satisfied by the suffix.
+ std::copy(suffix_, suffix_ + count, out);
+ suffix_ += count;
+ suffix_length_ -= count;
+ return true;
+}
+
+bool SpdyPrefixedBufferReader::ReadN(size_t count,
+ SpdyPinnableBufferPiece* out) {
+ if (Available() < count) {
+ return false;
+ }
+
+ out->storage_.reset();
+ out->length_ = count;
+
+ if (prefix_length_ >= count) {
+ // Read is fully satisfied by the prefix.
+ out->buffer_ = prefix_;
+ prefix_ += count;
+ prefix_length_ -= count;
+ return true;
+ } else if (prefix_length_ != 0) {
+ // Read is only partially satisfied by the prefix. We need to allocate
+ // contiguous storage as the read spans the prefix & suffix.
+ out->storage_.reset(new char[count]);
+ out->buffer_ = out->storage_.get();
+ ReadN(count, out->storage_.get());
+ return true;
+ } else {
+ DCHECK(suffix_length_ >= count);
+ // Read is fully satisfied by the suffix.
+ out->buffer_ = suffix_;
+ suffix_ += count;
+ suffix_length_ -= count;
+ return true;
+ }
+}
+
+} // namespace spdy