Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(633)

Side by Side Diff: net/filter/filter_source_stream.cc

Issue 2251853002: Add net::SourceStream and net::FilterSourceStream (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Same as PS#18 of old CL but with upstream/downstream name change Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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/filter/filter_source_stream.h"
6
7 #include "base/bind.h"
8 #include "base/callback_helpers.h"
9 #include "base/metrics/histogram_macros.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "base/strings/string_util.h"
12
13 namespace net {
14
15 namespace {
16
17 const size_t kBufferSize = 32 * 1024;
18
19 } // namespace
20
21 FilterSourceStream::FilterSourceStream(SourceType type,
22 std::unique_ptr<SourceStream> upstream)
23 : SourceStream(type),
24 upstream_(std::move(upstream)),
25 next_state_(STATE_NONE),
26 output_buffer_size_(0),
27 upstream_end_reached_(false) {
28 DCHECK(upstream_);
29 }
30
31 FilterSourceStream::~FilterSourceStream() {}
32
33 int FilterSourceStream::Read(IOBuffer* read_buffer,
34 size_t read_buffer_size,
35 const CompletionCallback& callback) {
mmenke 2016/08/17 19:01:55 DCHECK_EQ(STATE_NONE, next_state_);
mmenke 2016/08/17 19:01:56 Maybe also add: DCHECK(read_buffer); DCHECK_LT(0,
xunjieli 2016/08/17 20:00:19 Done.
xunjieli 2016/08/17 20:00:19 Done.
36 // Allocate a BlockBuffer during first Read().
37 if (!input_buffer_)
38 input_buffer_ = new IOBufferWithSize(kBufferSize);
mmenke 2016/08/17 19:01:55 Should we really be taking read_buffer_size as a s
xunjieli 2016/08/17 20:00:19 Done. I will keep it as int then to conform to the
39
40 // Start with filtering data, which tells us whether it needs input data.
mmenke 2016/08/17 19:01:56 it -> this filter?
xunjieli 2016/08/17 20:00:19 Done.
41 next_state_ = STATE_FILTER_DATA;
42
43 output_buffer_ = read_buffer;
44 output_buffer_size_ = read_buffer_size;
45 int rv = DoLoop(OK);
46 if (rv > OK) {
47 return rv;
48 } else if (rv == ERR_IO_PENDING) {
49 callback_ = callback;
50 }
51 return rv;
mmenke 2016/08/17 19:01:55 this could be simplified as: if (rv == ERR_IO_PEN
xunjieli 2016/08/17 20:00:19 Done.
52 }
53
54 std::string FilterSourceStream::OrderedTypeStringList() const {
55 std::string next_type_string = upstream_->OrderedTypeStringList();
56 if (next_type_string.empty())
57 return GetTypeAsString();
58 return next_type_string + "," + GetTypeAsString();
59 }
60
61 int FilterSourceStream::DoLoop(int result) {
62 DCHECK(this);
mmenke 2016/08/17 19:01:56 I don't think this is needed?
xunjieli 2016/08/17 20:00:19 Done. Sorry I put it there and forgot to remove it
63 DCHECK_NE(STATE_NONE, next_state_);
mmenke 2016/08/17 19:01:56 Suggest a blank line between initial-state DCHECKs
xunjieli 2016/08/17 20:00:19 Done.
64 int rv = result;
65 do {
66 State state = next_state_;
67 next_state_ = STATE_NONE;
68 switch (state) {
69 case STATE_READ_DATA:
70 rv = DoReadData();
71 break;
72 case STATE_READ_DATA_COMPLETE:
73 rv = DoReadDataComplete(rv);
74 break;
75 case STATE_FILTER_DATA:
76 rv = DoFilterData(rv);
77 break;
78 default:
79 NOTREACHED() << "bad state: " << state;
80 rv = ERR_UNEXPECTED;
81 break;
82 }
83 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
84 return rv;
85 }
86
87 int FilterSourceStream::DoReadData() {
88 // Read more data means subclasses have consumed all input or this is the
89 // first read in which case the |drainable_input_buffer_| is not initialized.
90 DCHECK(drainable_input_buffer_ == nullptr ||
91 0 == drainable_input_buffer_->BytesRemaining());
mmenke 2016/08/17 19:01:55 Suggest a blank line after the DCHECK.
xunjieli 2016/08/17 20:00:19 Done.
92 // Use base::Unretained here is safe because |this| owns |upstream_|.
93 int rv = upstream_->Read(input_buffer_.get(), kBufferSize,
94 base::Bind(&FilterSourceStream::OnNextReadCompleted,
95 base::Unretained(this)));
96
97 if (rv != ERR_IO_PENDING)
98 next_state_ = STATE_READ_DATA_COMPLETE;
99 return rv;
100 }
101
102 int FilterSourceStream::DoReadDataComplete(int result) {
103 DCHECK_NE(ERR_IO_PENDING, result);
104
105 // If EOF is read (result == OK), also pass that to the the filter.
106 if (result >= OK) {
107 drainable_input_buffer_ =
108 new DrainableIOBuffer(input_buffer_.get(), result);
109 next_state_ = STATE_FILTER_DATA;
110 }
111 if (result <= OK)
112 upstream_end_reached_ = true;
113 return result;
114 }
115
116 void FilterSourceStream::OnNextReadCompleted(int result) {
117 next_state_ = STATE_READ_DATA_COMPLETE;
118 int rv = DoLoop(result);
119 if (rv != ERR_IO_PENDING)
120 DoCallback(rv);
121 }
122
123 int FilterSourceStream::DoFilterData(int result) {
124 DCHECK(output_buffer_);
125 DCHECK_LE(0, result);
mmenke 2016/08/17 19:01:55 This method doesn't actually use result. Suggest
xunjieli 2016/08/17 20:00:19 Done.
126
127 // This is first Read(), short circuit it and go straight to read data from
128 // |upstream_|.
129 if (drainable_input_buffer_ == nullptr) {
mmenke 2016/08/17 19:01:55 Can we just get rid of this check? We have a chec
xunjieli 2016/08/17 20:00:19 Done.
130 next_state_ = STATE_READ_DATA;
131 return OK;
132 }
133
134 int bytes_output = FilterData(output_buffer_.get(), output_buffer_size_,
135 drainable_input_buffer_.get());
136 if (bytes_output == ERR_CONTENT_DECODING_FAILED) {
137 UMA_HISTOGRAM_ENUMERATION("Net.ContentDecodingFailed.FilterType", type(),
138 TYPE_MAX);
139 }
140 // FilterData() is not allowed to return ERR_IO_PENDING.
141 DCHECK_NE(ERR_IO_PENDING, bytes_output);
142
143 // If data can still be read from |upstream_| and filter did not return any
144 // data, it is likely that the filter needs more input.
145 if (bytes_output == OK && !upstream_end_reached_)
146 next_state_ = STATE_READ_DATA;
147 return bytes_output;
148 }
149
150 void FilterSourceStream::DoCallback(int result) {
mmenke 2016/08/17 19:01:55 Should we just inline this? We only call it in on
xunjieli 2016/08/17 20:00:19 Done.
151 DCHECK_NE(ERR_IO_PENDING, result);
152 DCHECK(!callback_.is_null());
153
154 output_buffer_ = nullptr;
155 output_buffer_size_ = 0;
156
157 base::ResetAndReturn(&callback_).Run(result);
158 }
159
160 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698