| // 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 "spdy/core/spdy_prefixed_buffer_reader.h" |
| |
| #include <new> |
| |
| #include "common/platform/api/quiche_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. |
| } |
| QUICHE_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 { |
| QUICHE_DCHECK(suffix_length_ >= count); |
| // Read is fully satisfied by the suffix. |
| out->buffer_ = suffix_; |
| suffix_ += count; |
| suffix_length_ -= count; |
| return true; |
| } |
| } |
| |
| } // namespace spdy |