cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / net / base / file_stream.cc
blob85adaece3cd404aaf703330c1be77863e503e749
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.
5 #include "net/base/file_stream.h"
7 #include "base/location.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "base/task_runner_util.h"
10 #include "base/threading/thread_restrictions.h"
11 #include "base/threading/worker_pool.h"
12 #include "net/base/file_stream_context.h"
13 #include "net/base/file_stream_net_log_parameters.h"
14 #include "net/base/net_errors.h"
16 namespace net {
18 FileStream::FileStream(NetLog* net_log,
19 const scoped_refptr<base::TaskRunner>& task_runner)
20 /* To allow never opened stream to be destroyed on any thread we set flags
21 as if stream was opened asynchronously. */
22 : open_flags_(base::PLATFORM_FILE_ASYNC),
23 bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
24 context_(new Context(bound_net_log_, task_runner)) {
25 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
28 FileStream::FileStream(NetLog* net_log)
29 /* To allow never opened stream to be destroyed on any thread we set flags
30 as if stream was opened asynchronously. */
31 : open_flags_(base::PLATFORM_FILE_ASYNC),
32 bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
33 context_(new Context(bound_net_log_,
34 base::WorkerPool::GetTaskRunner(true /* slow */))) {
35 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
38 FileStream::FileStream(base::PlatformFile file,
39 int flags,
40 NetLog* net_log,
41 const scoped_refptr<base::TaskRunner>& task_runner)
42 : open_flags_(flags),
43 bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
44 context_(new Context(file, bound_net_log_, open_flags_, task_runner)) {
45 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
48 FileStream::FileStream(base::PlatformFile file, int flags, NetLog* net_log)
49 : open_flags_(flags),
50 bound_net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_FILESTREAM)),
51 context_(new Context(file,
52 bound_net_log_,
53 open_flags_,
54 base::WorkerPool::GetTaskRunner(true /* slow */))) {
55 bound_net_log_.BeginEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
58 FileStream::~FileStream() {
59 if (!is_async()) {
60 base::ThreadRestrictions::AssertIOAllowed();
61 context_->CloseSync();
62 context_.reset();
63 } else {
64 context_.release()->Orphan();
67 bound_net_log_.EndEvent(NetLog::TYPE_FILE_STREAM_ALIVE);
70 int FileStream::Open(const base::FilePath& path, int open_flags,
71 const CompletionCallback& callback) {
72 if (IsOpen()) {
73 DLOG(FATAL) << "File is already open!";
74 return ERR_UNEXPECTED;
77 open_flags_ = open_flags;
78 DCHECK(is_async());
79 context_->OpenAsync(path, open_flags, callback);
80 return ERR_IO_PENDING;
83 int FileStream::OpenSync(const base::FilePath& path, int open_flags) {
84 base::ThreadRestrictions::AssertIOAllowed();
86 if (IsOpen()) {
87 DLOG(FATAL) << "File is already open!";
88 return ERR_UNEXPECTED;
91 open_flags_ = open_flags;
92 DCHECK(!is_async());
93 return context_->OpenSync(path, open_flags_);
96 bool FileStream::IsOpen() const {
97 return context_->file() != base::kInvalidPlatformFileValue;
100 int FileStream::Seek(Whence whence,
101 int64 offset,
102 const Int64CompletionCallback& callback) {
103 if (!IsOpen())
104 return ERR_UNEXPECTED;
106 // Make sure we're async.
107 DCHECK(is_async());
108 context_->SeekAsync(whence, offset, callback);
109 return ERR_IO_PENDING;
112 int64 FileStream::SeekSync(Whence whence, int64 offset) {
113 base::ThreadRestrictions::AssertIOAllowed();
115 if (!IsOpen())
116 return ERR_UNEXPECTED;
118 // If we're in async, make sure we don't have a request in flight.
119 DCHECK(!is_async() || !context_->async_in_progress());
120 return context_->SeekSync(whence, offset);
123 int64 FileStream::Available() {
124 base::ThreadRestrictions::AssertIOAllowed();
126 if (!IsOpen())
127 return ERR_UNEXPECTED;
129 int64 cur_pos = SeekSync(FROM_CURRENT, 0);
130 if (cur_pos < 0)
131 return cur_pos;
133 int64 size = context_->GetFileSize();
134 if (size < 0)
135 return size;
137 DCHECK_GE(size, cur_pos);
138 return size - cur_pos;
141 int FileStream::Read(IOBuffer* buf,
142 int buf_len,
143 const CompletionCallback& callback) {
144 if (!IsOpen())
145 return ERR_UNEXPECTED;
147 // read(..., 0) will return 0, which indicates end-of-file.
148 DCHECK_GT(buf_len, 0);
149 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
150 DCHECK(is_async());
152 return context_->ReadAsync(buf, buf_len, callback);
155 int FileStream::ReadSync(char* buf, int buf_len) {
156 base::ThreadRestrictions::AssertIOAllowed();
158 if (!IsOpen())
159 return ERR_UNEXPECTED;
161 DCHECK(!is_async());
162 // read(..., 0) will return 0, which indicates end-of-file.
163 DCHECK_GT(buf_len, 0);
164 DCHECK(open_flags_ & base::PLATFORM_FILE_READ);
166 return context_->ReadSync(buf, buf_len);
169 int FileStream::ReadUntilComplete(char *buf, int buf_len) {
170 base::ThreadRestrictions::AssertIOAllowed();
172 int to_read = buf_len;
173 int bytes_total = 0;
175 do {
176 int bytes_read = ReadSync(buf, to_read);
177 if (bytes_read <= 0) {
178 if (bytes_total == 0)
179 return bytes_read;
181 return bytes_total;
184 bytes_total += bytes_read;
185 buf += bytes_read;
186 to_read -= bytes_read;
187 } while (bytes_total < buf_len);
189 return bytes_total;
192 int FileStream::Write(IOBuffer* buf,
193 int buf_len,
194 const CompletionCallback& callback) {
195 if (!IsOpen())
196 return ERR_UNEXPECTED;
198 DCHECK(is_async());
199 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
200 // write(..., 0) will return 0, which indicates end-of-file.
201 DCHECK_GT(buf_len, 0);
203 return context_->WriteAsync(buf, buf_len, callback);
206 int FileStream::WriteSync(const char* buf, int buf_len) {
207 base::ThreadRestrictions::AssertIOAllowed();
209 if (!IsOpen())
210 return ERR_UNEXPECTED;
212 DCHECK(!is_async());
213 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
214 // write(..., 0) will return 0, which indicates end-of-file.
215 DCHECK_GT(buf_len, 0);
217 return context_->WriteSync(buf, buf_len);
220 int64 FileStream::Truncate(int64 bytes) {
221 base::ThreadRestrictions::AssertIOAllowed();
223 if (!IsOpen())
224 return ERR_UNEXPECTED;
226 // We'd better be open for writing.
227 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
229 // Seek to the position to truncate from.
230 int64 seek_position = SeekSync(FROM_BEGIN, bytes);
231 if (seek_position != bytes)
232 return ERR_UNEXPECTED;
234 // And truncate the file.
235 return context_->Truncate(bytes);
238 int FileStream::Flush(const CompletionCallback& callback) {
239 if (!IsOpen())
240 return ERR_UNEXPECTED;
242 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
243 // Make sure we're async.
244 DCHECK(is_async());
246 context_->FlushAsync(callback);
247 return ERR_IO_PENDING;
250 int FileStream::FlushSync() {
251 base::ThreadRestrictions::AssertIOAllowed();
253 if (!IsOpen())
254 return ERR_UNEXPECTED;
256 DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE);
257 return context_->FlushSync();
260 void FileStream::EnableErrorStatistics() {
261 context_->set_record_uma(true);
264 void FileStream::SetBoundNetLogSource(const BoundNetLog& owner_bound_net_log) {
265 if ((owner_bound_net_log.source().id == NetLog::Source::kInvalidId) &&
266 (bound_net_log_.source().id == NetLog::Source::kInvalidId)) {
267 // Both |BoundNetLog|s are invalid.
268 return;
271 // Should never connect to itself.
272 DCHECK_NE(bound_net_log_.source().id, owner_bound_net_log.source().id);
274 bound_net_log_.AddEvent(NetLog::TYPE_FILE_STREAM_BOUND_TO_OWNER,
275 owner_bound_net_log.source().ToEventParametersCallback());
277 owner_bound_net_log.AddEvent(NetLog::TYPE_FILE_STREAM_SOURCE,
278 bound_net_log_.source().ToEventParametersCallback());
281 base::PlatformFile FileStream::GetPlatformFileForTesting() {
282 return context_->file();
285 } // namespace net