1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "net/spdy/spdy_prefixed_buffer_reader.h" 6 7#include "base/logging.h" 8 9namespace net { 10 11SpdyPrefixedBufferReader::SpdyPrefixedBufferReader( 12 const char* prefix, 13 size_t prefix_length, 14 const char* suffix, 15 size_t suffix_length) 16 : prefix_(prefix), 17 suffix_(suffix), 18 prefix_length_(prefix_length), 19 suffix_length_(suffix_length) {} 20 21size_t SpdyPrefixedBufferReader::Available() { 22 return prefix_length_ + suffix_length_; 23} 24 25bool SpdyPrefixedBufferReader::ReadN(size_t count, char* out) { 26 if (Available() < count) 27 return false; 28 29 if (prefix_length_ >= count) { 30 // Read is fully satisfied by the prefix. 31 std::copy(prefix_, prefix_ + count, out); 32 prefix_ += count; 33 prefix_length_ -= count; 34 return true; 35 } else if (prefix_length_ != 0) { 36 // Read is partially satisfied by the prefix. 37 out = std::copy(prefix_, prefix_ + prefix_length_, out); 38 count -= prefix_length_; 39 prefix_length_ = 0; 40 // Fallthrough to suffix read. 41 } 42 DCHECK(suffix_length_ >= count); 43 // Read is satisfied by the suffix. 44 std::copy(suffix_, suffix_ + count, out); 45 suffix_ += count; 46 suffix_length_ -= count; 47 return true; 48} 49 50bool SpdyPrefixedBufferReader::ReadN(size_t count, 51 SpdyPinnableBufferPiece* out) { 52 if (Available() < count) 53 return false; 54 55 out->storage_.reset(); 56 out->length_ = count; 57 58 if (prefix_length_ >= count) { 59 // Read is fully satisfied by the prefix. 60 out->buffer_ = prefix_; 61 prefix_ += count; 62 prefix_length_ -= count; 63 return true; 64 } else if (prefix_length_ != 0) { 65 // Read is only partially satisfied by the prefix. We need to allocate 66 // contiguous storage as the read spans the prefix & suffix. 67 out->storage_.reset(new char[count]); 68 out->buffer_ = out->storage_.get(); 69 ReadN(count, out->storage_.get()); 70 return true; 71 } else { 72 DCHECK(suffix_length_ >= count); 73 // Read is fully satisfied by the suffix. 74 out->buffer_ = suffix_; 75 suffix_ += count; 76 suffix_length_ -= count; 77 return true; 78 } 79} 80 81} // namespace net 82