1 // Copyright 2012 The Chromium Authors
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/base/file_stream_context.h"
6
7 #include <errno.h>
8 #include <utility>
9
10 #include "base/check.h"
11 #include "base/files/file_path.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/functional/callback_helpers.h"
15 #include "base/location.h"
16 #include "base/posix/eintr_wrapper.h"
17 #include "base/task/task_runner.h"
18 #include "net/base/io_buffer.h"
19 #include "net/base/net_errors.h"
20
21 namespace net {
22
Context(scoped_refptr<base::TaskRunner> task_runner)23 FileStream::Context::Context(scoped_refptr<base::TaskRunner> task_runner)
24 : Context(base::File(), std::move(task_runner)) {}
25
Context(base::File file,scoped_refptr<base::TaskRunner> task_runner)26 FileStream::Context::Context(base::File file,
27 scoped_refptr<base::TaskRunner> task_runner)
28 : file_(std::move(file)), task_runner_(std::move(task_runner)) {}
29
30 FileStream::Context::~Context() = default;
31
Read(IOBuffer * in_buf,int buf_len,CompletionOnceCallback callback)32 int FileStream::Context::Read(IOBuffer* in_buf,
33 int buf_len,
34 CompletionOnceCallback callback) {
35 DCHECK(!async_in_progress_);
36
37 scoped_refptr<IOBuffer> buf = in_buf;
38 const bool posted = task_runner_->PostTaskAndReplyWithResult(
39 FROM_HERE,
40 base::BindOnce(&Context::ReadFileImpl, base::Unretained(this), buf,
41 buf_len),
42 base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
43 IntToInt64(std::move(callback))));
44 DCHECK(posted);
45
46 async_in_progress_ = true;
47 return ERR_IO_PENDING;
48 }
49
Write(IOBuffer * in_buf,int buf_len,CompletionOnceCallback callback)50 int FileStream::Context::Write(IOBuffer* in_buf,
51 int buf_len,
52 CompletionOnceCallback callback) {
53 DCHECK(!async_in_progress_);
54
55 scoped_refptr<IOBuffer> buf = in_buf;
56 const bool posted = task_runner_->PostTaskAndReplyWithResult(
57 FROM_HERE,
58 base::BindOnce(&Context::WriteFileImpl, base::Unretained(this), buf,
59 buf_len),
60 base::BindOnce(&Context::OnAsyncCompleted, base::Unretained(this),
61 IntToInt64(std::move(callback))));
62 DCHECK(posted);
63
64 async_in_progress_ = true;
65 return ERR_IO_PENDING;
66 }
67
SeekFileImpl(int64_t offset)68 FileStream::Context::IOResult FileStream::Context::SeekFileImpl(
69 int64_t offset) {
70 int64_t res = file_.Seek(base::File::FROM_BEGIN, offset);
71 if (res == -1)
72 return IOResult::FromOSError(errno);
73
74 return IOResult(res, 0);
75 }
76
OnFileOpened()77 void FileStream::Context::OnFileOpened() {
78 }
79
ReadFileImpl(scoped_refptr<IOBuffer> buf,int buf_len)80 FileStream::Context::IOResult FileStream::Context::ReadFileImpl(
81 scoped_refptr<IOBuffer> buf,
82 int buf_len) {
83 int res = file_.ReadAtCurrentPosNoBestEffort(buf->data(), buf_len);
84 if (res == -1)
85 return IOResult::FromOSError(errno);
86
87 return IOResult(res, 0);
88 }
89
WriteFileImpl(scoped_refptr<IOBuffer> buf,int buf_len)90 FileStream::Context::IOResult FileStream::Context::WriteFileImpl(
91 scoped_refptr<IOBuffer> buf,
92 int buf_len) {
93 int res = file_.WriteAtCurrentPosNoBestEffort(buf->data(), buf_len);
94 if (res == -1)
95 return IOResult::FromOSError(errno);
96
97 return IOResult(res, 0);
98 }
99
100 } // namespace net
101