// 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/spdy/spdy_prefixed_buffer_reader.h" #include "base/logging.h" namespace net { 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 net