OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 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 "content/browser/download/byte_stream.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/location.h" | |
9 | |
10 namespace content { | |
11 | |
12 ByteStream::ByteStream() | |
13 : buffer_size_(kDefaultBufferSize), | |
14 data_size_(0), | |
15 is_complete_(false), | |
16 source_status_(DOWNLOAD_INTERRUPT_REASON_NONE) { } | |
17 | |
18 void ByteStream::SetBufferSize(size_t buffer_size) { | |
19 buffer_size_ = buffer_size; | |
20 } | |
21 | |
22 bool ByteStream::AddData(scoped_refptr<net::IOBuffer> buffer, | |
23 size_t byte_count) { | |
24 base::AutoLock auto_lock(lock_); | |
25 | |
26 if (data_size_ == 0 && byte_count > 0 && sink_task_runner_.get() != NULL) | |
ahendrickson
2012/04/16 15:14:27
Nit: Add braces for multi-line 'if' bodies.
Randy Smith (Not in Mondays)
2012/04/18 19:10:38
Ooops. But already done in a later PS.
| |
27 // Nothing actually touches the data on this object can be | |
ahendrickson
2012/04/16 15:14:27
*Nothing that
Randy Smith (Not in Mondays)
2012/04/18 19:10:38
Done.
| |
28 // executed until we drop the lock, so it's ok to | |
29 // dispatch this before we actually add the data. | |
30 sink_task_runner_->PostTask( | |
31 FROM_HERE, base::Bind(&content::ByteStream::RunSinkCallback, | |
32 this, sink_task_runner_)); | |
33 | |
34 // Take manual (not enforced by compiler via scoped_*) ownership of data. | |
35 contents_.push_back(std::make_pair(buffer, byte_count)); | |
36 data_size_ += byte_count; | |
37 return (data_size_ < buffer_size_); | |
38 } | |
39 | |
40 void ByteStream::SourceComplete(DownloadInterruptReason status) { | |
41 base::AutoLock auto_lock(lock_); | |
42 | |
43 is_complete_ = true; | |
44 source_status_ = status; | |
45 // If contents_ is non-empty, a callback has already been posted. | |
46 if (contents_.empty() && sink_task_runner_.get() != NULL) | |
ahendrickson
2012/04/16 15:14:27
Nit: Add braces.
Randy Smith (Not in Mondays)
2012/04/18 19:10:38
Done.
| |
47 sink_task_runner_->PostTask( | |
48 FROM_HERE, base::Bind(&content::ByteStream::RunSinkCallback, | |
49 this, sink_task_runner_)); | |
50 } | |
51 | |
52 bool ByteStream::IsFull() { | |
53 base::AutoLock auto_lock(lock_); | |
54 | |
55 return (data_size_ >= buffer_size_); | |
56 } | |
57 | |
58 void ByteStream::RegisterSourceCallback( | |
59 scoped_refptr<base::TaskRunner> source_task_runner, | |
60 ByteStreamCallback source_callback) { | |
61 base::AutoLock auto_lock(lock_); | |
62 | |
63 source_task_runner_ = source_task_runner; | |
64 source_callback_ = source_callback; | |
65 } | |
66 | |
67 ByteStream::StreamState ByteStream::GetData(scoped_refptr<net::IOBuffer>* data, | |
68 size_t* length) { | |
69 base::AutoLock auto_lock(lock_); | |
70 | |
71 if (contents_.empty()) { | |
72 if (is_complete_) | |
73 return STREAM_COMPLETE; | |
74 return STREAM_EMPTY; | |
75 } | |
76 | |
77 if (data_size_ >= buffer_size_ && | |
78 data_size_ - contents_.front().second < buffer_size_ && | |
79 source_task_runner_.get() != NULL) | |
ahendrickson
2012/04/16 15:14:27
Nit: Add braces.
Randy Smith (Not in Mondays)
2012/04/18 19:10:38
Done.
| |
80 // Nothing actually touches the data on this object can be | |
ahendrickson
2012/04/16 15:14:27
*Nothing that
Randy Smith (Not in Mondays)
2012/04/18 19:10:38
Done.
| |
81 // executed until we drop the lock, so it's ok to | |
82 // dispatch this before we actually take the data. | |
83 source_task_runner_->PostTask(FROM_HERE, base::Bind( | |
84 &content::ByteStream::RunSourceCallback, this, source_task_runner_)); | |
85 | |
86 *data = contents_.front().first; | |
87 *length = contents_.front().second; | |
88 contents_.pop_front(); | |
89 data_size_ -= *length; | |
90 return STREAM_NON_EMPTY; | |
91 } | |
92 | |
93 DownloadInterruptReason ByteStream::GetSourceResult () { | |
94 base::AutoLock auto_lock(lock_); | |
95 | |
96 return source_status_; | |
97 } | |
98 | |
99 void ByteStream::RegisterSinkCallback( | |
100 scoped_refptr<base::TaskRunner> sink_task_runner, | |
101 ByteStreamCallback sink_callback) { | |
102 base::AutoLock auto_lock(lock_); | |
103 | |
104 sink_task_runner_ = sink_task_runner; | |
105 sink_callback_ = sink_callback; | |
106 } | |
107 | |
108 ByteStream::~ByteStream() { | |
109 } | |
110 | |
111 void ByteStream::RunSourceCallback( | |
112 scoped_refptr<base::TaskRunner> target_runner) { | |
113 base::Closure callback; | |
114 { | |
115 base::AutoLock auto_lock(lock_); | |
116 | |
117 // If the target_runner has been updated, that implies an access to | |
118 // the class, so we can drop this request on the floor. (The | |
119 // alternative would be to forward it on to the new task runner.) | |
120 if (target_runner.get() != source_task_runner_.get()) | |
121 return; | |
122 | |
123 if (source_callback_.is_null()) | |
124 return; | |
125 | |
126 callback = source_callback_; | |
127 } | |
128 | |
129 // Run unlocked to allow caller to call back into us. | |
130 callback.Run(); | |
131 } | |
132 | |
133 void ByteStream::RunSinkCallback( | |
134 scoped_refptr<base::TaskRunner> target_runner) { | |
135 base::Closure callback; | |
136 { | |
137 base::AutoLock auto_lock(lock_); | |
138 | |
139 // If the target_runner has been updated, that implies an access to | |
140 // the class, so we can drop this request on the floor. (The | |
141 // alternative would be to forward it on to the new task runner.) | |
142 if (target_runner.get() != sink_task_runner_.get()) | |
143 return; | |
144 | |
145 if (sink_callback_.is_null()) | |
146 return; | |
147 | |
148 callback = sink_callback_; | |
149 } | |
150 | |
151 // Run unlocked to allow caller to call back into us. | |
152 callback.Run(); | |
153 } | |
154 | |
155 } // namespace content | |
OLD | NEW |