1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
// 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
|