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

Side by Side Diff: chrome/browser/chromeos/file_system_provider/fileapi/buffering_file_stream_writer.cc

Issue 502973005: [fsp] Buffer consecutive Write() calls. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 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 2014 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 "chrome/browser/chromeos/file_system_provider/fileapi/buffering_file_st ream_writer.h"
6
7 #include <algorithm>
8
9 #include "net/base/io_buffer.h"
10 #include "net/base/net_errors.h"
11
12 namespace chromeos {
13 namespace file_system_provider {
14
15 BufferingFileStreamWriter::BufferingFileStreamWriter(
16 scoped_ptr<storage::FileStreamWriter> file_stream_writer,
17 int intermediate_buffer_length)
18 : file_stream_writer_(file_stream_writer.Pass()),
19 intermediate_buffer_length_(intermediate_buffer_length),
20 intermediate_buffer_(new net::IOBuffer(intermediate_buffer_length_)),
21 buffered_bytes_(0),
22 weak_ptr_factory_(this) {
23 }
24
25 BufferingFileStreamWriter::~BufferingFileStreamWriter() {
26 }
27
28 int BufferingFileStreamWriter::Write(net::IOBuffer* buffer,
29 int buffer_length,
30 const net::CompletionCallback& callback) {
31 // If |buffer_length| is larger than the intermediate buffer, then call the
32 // internal file stream writer directly. Note, that the intermediate buffer
33 // (used for buffering) must be flushed first.
34 if (buffer_length > intermediate_buffer_length_) {
35 if (buffered_bytes_) {
36 FlushIntermediateBuffer(
37 base::Bind(&BufferingFileStreamWriter::
38 OnFlushIntermediateBufferForDirectWriteCompleted,
39 weak_ptr_factory_.GetWeakPtr(),
40 make_scoped_refptr(buffer),
41 buffer_length,
42 callback));
43 } else {
44 // Nothing to flush, so skip it.
45 OnFlushIntermediateBufferForDirectWriteCompleted(
46 make_scoped_refptr(buffer), buffer_length, callback, net::OK);
47 }
48 return net::ERR_IO_PENDING;
49 }
50
51 // Buffer consecutive writes to larger chunks.
52 const int buffer_bytes =
53 std::min(intermediate_buffer_length_ - buffered_bytes_, buffer_length);
54
55 CopyToIntermediateBuffer(
56 make_scoped_refptr(buffer), 0 /* offset */, buffer_bytes);
57 const int bytes_left = buffer_length - buffer_bytes;
58
59 if (buffered_bytes_ == intermediate_buffer_length_) {
60 FlushIntermediateBuffer(
61 base::Bind(&BufferingFileStreamWriter::
62 OnFlushIntermediateBufferForBufferedWriteCompleted,
63 weak_ptr_factory_.GetWeakPtr(),
64 make_scoped_refptr(buffer),
65 buffer_bytes,
66 bytes_left,
67 callback));
68 return net::ERR_IO_PENDING;
69 }
70
71 // Optimistically return a success.
72 return buffer_length;
73 }
74
75 int BufferingFileStreamWriter::Cancel(const net::CompletionCallback& callback) {
76 return file_stream_writer_->Cancel(callback);
77 }
78
79 int BufferingFileStreamWriter::Flush(const net::CompletionCallback& callback) {
80 // Flush all the buffered bytes first, then invoke Flush() on the inner file
81 // stream writer.
82 FlushIntermediateBuffer(base::Bind(
83 &BufferingFileStreamWriter::OnFlushIntermediateBufferForFlushCompleted,
84 weak_ptr_factory_.GetWeakPtr(),
85 callback));
86 return net::ERR_IO_PENDING;
87 }
88
89 void BufferingFileStreamWriter::CopyToIntermediateBuffer(
90 scoped_refptr<net::IOBuffer> buffer,
91 int offset,
92 int length) {
93 DCHECK_GE(intermediate_buffer_length_, offset + length + buffered_bytes_);
94 memcpy(intermediate_buffer_->data() + buffered_bytes_,
95 buffer->data() + offset,
96 length);
97 buffered_bytes_ += length;
98 }
99
100 void BufferingFileStreamWriter::FlushIntermediateBuffer(
101 const net::CompletionCallback& callback) {
102 const int result = file_stream_writer_->Write(
103 intermediate_buffer_,
104 buffered_bytes_,
105 base::Bind(&BufferingFileStreamWriter::OnFlushIntermediateBufferCompleted,
106 weak_ptr_factory_.GetWeakPtr(),
107 buffered_bytes_,
108 callback));
109 DCHECK_EQ(net::ERR_IO_PENDING, result);
110 }
111
112 void BufferingFileStreamWriter::OnFlushIntermediateBufferCompleted(
113 int length,
114 const net::CompletionCallback& callback,
115 int result) {
116 if (result < 0) {
117 callback.Run(result);
118 return;
119 }
120
121 DCHECK_EQ(length, result) << "Partial reads are not supported.";
122 buffered_bytes_ = 0;
123 callback.Run(net::OK);
124 }
125
126 void
127 BufferingFileStreamWriter::OnFlushIntermediateBufferForDirectWriteCompleted(
128 scoped_refptr<net::IOBuffer> buffer,
129 int length,
130 const net::CompletionCallback& callback,
131 int result) {
132 if (result < 0) {
133 callback.Run(result);
134 return;
135 }
136
137 // Write all bytes directly.
138 DCHECK_EQ(net::OK, result);
139 DCHECK_EQ(0, buffered_bytes_);
140 const int write_result = file_stream_writer_->Write(buffer, length, callback);
141 DCHECK_EQ(net::ERR_IO_PENDING, write_result);
142 }
143
144 void
145 BufferingFileStreamWriter::OnFlushIntermediateBufferForBufferedWriteCompleted(
146 scoped_refptr<net::IOBuffer> buffer,
147 int buffered_bytes,
148 int bytes_left,
149 const net::CompletionCallback& callback,
150 int result) {
151 if (result < 0) {
152 callback.Run(result);
153 return;
154 }
155
156 // Copy the rest of bytes to the buffer.
157 DCHECK_EQ(net::OK, result);
158 DCHECK_EQ(0, buffered_bytes_);
159 DCHECK_GE(intermediate_buffer_length_, bytes_left);
160 CopyToIntermediateBuffer(buffer, buffered_bytes, bytes_left);
161
162 callback.Run(buffered_bytes + bytes_left);
163 }
164
165 void BufferingFileStreamWriter::OnFlushIntermediateBufferForFlushCompleted(
166 const net::CompletionCallback& callback,
167 int result) {
168 if (result < 0) {
169 callback.Run(result);
170 return;
171 }
172
173 const int flush_result = file_stream_writer_->Flush(callback);
174 DCHECK_EQ(net::ERR_IO_PENDING, flush_result);
hashimoto 2014/08/28 08:32:17 It seems FileStreamWriter::Flush doesn't return ER
mtomasz 2014/08/29 02:49:00 Done.
175 }
176
177 } // namespace file_system_provider
178 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698