• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "quiche/spdy/core/spdy_prefixed_buffer_reader.h"
6 
7 #include <algorithm>
8 #include <cstddef>
9 
10 #include "quiche/common/platform/api/quiche_logging.h"
11 #include "quiche/spdy/core/spdy_pinnable_buffer_piece.h"
12 
13 namespace spdy {
14 
SpdyPrefixedBufferReader(const char * prefix,size_t prefix_length,const char * suffix,size_t suffix_length)15 SpdyPrefixedBufferReader::SpdyPrefixedBufferReader(const char* prefix,
16                                                    size_t prefix_length,
17                                                    const char* suffix,
18                                                    size_t suffix_length)
19     : prefix_(prefix),
20       suffix_(suffix),
21       prefix_length_(prefix_length),
22       suffix_length_(suffix_length) {}
23 
Available()24 size_t SpdyPrefixedBufferReader::Available() {
25   return prefix_length_ + suffix_length_;
26 }
27 
ReadN(size_t count,char * out)28 bool SpdyPrefixedBufferReader::ReadN(size_t count, char* out) {
29   if (Available() < count) {
30     return false;
31   }
32 
33   if (prefix_length_ >= count) {
34     // Read is fully satisfied by the prefix.
35     std::copy(prefix_, prefix_ + count, out);
36     prefix_ += count;
37     prefix_length_ -= count;
38     return true;
39   } else if (prefix_length_ != 0) {
40     // Read is partially satisfied by the prefix.
41     out = std::copy(prefix_, prefix_ + prefix_length_, out);
42     count -= prefix_length_;
43     prefix_length_ = 0;
44     // Fallthrough to suffix read.
45   }
46   QUICHE_DCHECK(suffix_length_ >= count);
47   // Read is satisfied by the suffix.
48   std::copy(suffix_, suffix_ + count, out);
49   suffix_ += count;
50   suffix_length_ -= count;
51   return true;
52 }
53 
ReadN(size_t count,SpdyPinnableBufferPiece * out)54 bool SpdyPrefixedBufferReader::ReadN(size_t count,
55                                      SpdyPinnableBufferPiece* out) {
56   if (Available() < count) {
57     return false;
58   }
59 
60   out->storage_.reset();
61   out->length_ = count;
62 
63   if (prefix_length_ >= count) {
64     // Read is fully satisfied by the prefix.
65     out->buffer_ = prefix_;
66     prefix_ += count;
67     prefix_length_ -= count;
68     return true;
69   } else if (prefix_length_ != 0) {
70     // Read is only partially satisfied by the prefix. We need to allocate
71     // contiguous storage as the read spans the prefix & suffix.
72     out->storage_.reset(new char[count]);
73     out->buffer_ = out->storage_.get();
74     ReadN(count, out->storage_.get());
75     return true;
76   } else {
77     QUICHE_DCHECK(suffix_length_ >= count);
78     // Read is fully satisfied by the suffix.
79     out->buffer_ = suffix_;
80     suffix_ += count;
81     suffix_length_ -= count;
82     return true;
83   }
84 }
85 
86 }  // namespace spdy
87