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

Side by Side Diff: net/base/upload_element_reader.cc

Issue 10868064: net: Move data reading functionalities from UploadElement to UploadElementReader (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 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 | Annotate | Revision Log
OLDNEW
(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 "net/base/upload_element_reader.h"
6
7 #include "base/file_util.h"
8 #include "net/base/file_stream.h"
9 #include "net/base/net_errors.h"
10 #include "net/base/upload_element.h"
11
12 namespace net {
13
14 namespace {
15
16 // In tests, this value is used to override the return value of
17 // UploadFileElementReader::GetContentLength() when set to non-zero.
18 uint64 overriding_content_length = 0;
19
20 } // namespace
21
22 // static
23 UploadElementReader* UploadElementReader::Create(const UploadElement& element) {
24 UploadElementReader* reader = NULL;
25 switch (element.type()) {
26 case UploadElement::TYPE_BYTES:
27 reader = new UploadBytesElementReader(element.bytes(),
28 element.bytes_length());
29 break;
30 case UploadElement::TYPE_FILE:
31 reader = new UploadFileElementReader(
32 element.file_path(),
33 element.file_range_offset(),
34 element.file_range_length(),
35 element.expected_file_modification_time());
36 break;
37 }
38 DCHECK(reader);
39 return reader;
40 }
41
42 bool UploadElementReader::IsInMemory() const {
43 return false;
44 }
45
46 UploadBytesElementReader::UploadBytesElementReader(const char* bytes,
47 int bytes_length)
48 : bytes_(bytes),
49 bytes_length_(bytes_length),
50 offset_(0) {
51 }
52
53 UploadBytesElementReader::~UploadBytesElementReader() {
54 }
55
56 int UploadBytesElementReader::InitSync() {
57 return OK;
58 }
59
60 uint64 UploadBytesElementReader::GetContentLength() const {
61 return bytes_length_;
62 }
63
64 uint64 UploadBytesElementReader::BytesRemaining() const {
65 return bytes_length_ - offset_;
66 }
67
68 int UploadBytesElementReader::ReadSync(char* buf, int buf_length) {
69 DCHECK_LT(0, buf_length);
70
71 const size_t num_bytes_to_read =
72 std::min(BytesRemaining(), static_cast<uint64>(buf_length));
73
74 // Check if we have anything to copy first, because we are getting
75 // the address of an element in |bytes_| and that will throw an
76 // exception if |bytes_| is an empty vector.
77 if (num_bytes_to_read > 0)
78 memcpy(buf, bytes_ + offset_, num_bytes_to_read);
79
80 offset_ += num_bytes_to_read;
81 return num_bytes_to_read;
82 }
83
84 bool UploadBytesElementReader::IsInMemory() const {
85 return true;
86 }
87
88 UploadFileElementReader::UploadFileElementReader(
89 const FilePath& path,
90 uint64 range_offset,
91 uint64 range_length,
92 const base::Time& expected_modification_time)
93 : path_(path),
94 range_offset_(range_offset),
95 range_length_(range_length),
96 expected_modification_time_(expected_modification_time),
97 content_length_(0),
98 bytes_remaining_(0) {
99 }
100
101 UploadFileElementReader::~UploadFileElementReader() {
102 if (file_stream_.get())
103 file_stream_->CloseSync();
104 }
105
106 int UploadFileElementReader::InitSync() {
107 scoped_ptr<FileStream> file_stream(new FileStream(NULL));
108 int64 rv = file_stream->OpenSync(
109 path_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
110 if (rv != OK) {
111 // If the file can't be opened, we'll just upload an empty file.
112 DLOG(WARNING) << "Failed to open \"" << path_.value()
113 << "\" for reading: " << rv;
114 file_stream.reset();
115 }
116 if (file_stream.get() && range_offset_) {
117 rv = file_stream->SeekSync(FROM_BEGIN, range_offset_);
118 if (rv < 0) {
119 DLOG(WARNING) << "Failed to seek \"" << path_.value()
120 << "\" to offset: " << range_offset_ << " (" << rv
121 << ")";
122 file_stream->CloseSync();
123 file_stream.reset();
124 }
125 }
126 file_stream_.reset(file_stream.release());
127
128 int64 length = 0;
129 if (file_stream_.get() &&
130 file_util::GetFileSize(path_, &length) &&
131 range_offset_ < static_cast<uint64>(length)) {
132 // Compensate for the offset.
133 length = std::min(length - range_offset_, range_length_);
134 }
135 content_length_ = length;
136 bytes_remaining_ = GetContentLength();
137
138 // If the underlying file has been changed and the expected file
139 // modification time is set, treat it as error. Note that the expected
140 // modification time from WebKit is based on time_t precision. So we
141 // have to convert both to time_t to compare. This check is used for
142 // sliced files.
143 if (!expected_modification_time_.is_null()) {
144 base::PlatformFileInfo info;
145 if (file_util::GetFileInfo(path_, &info) &&
146 expected_modification_time_.ToTimeT() !=
147 info.last_modified.ToTimeT()) {
148 return ERR_UPLOAD_FILE_CHANGED;
149 }
150 }
151
152 return OK;
153 }
154
155 uint64 UploadFileElementReader::GetContentLength() const {
156 if (overriding_content_length)
157 return overriding_content_length;
158 return content_length_;
159 }
160
161 uint64 UploadFileElementReader::BytesRemaining() const {
162 return bytes_remaining_;
163 }
164
165 int UploadFileElementReader::ReadSync(char* buf, int buf_length) {
166 DCHECK_LT(0, buf_length);
167
168 const uint64 num_bytes_to_read =
169 static_cast<int>(std::min(BytesRemaining(),
170 static_cast<uint64>(buf_length)));
171 if (num_bytes_to_read > 0) {
172 int num_bytes_consumed = 0;
173 // file_stream_ is NULL if the target file is
174 // missing or not readable.
175 if (file_stream_.get()) {
176 num_bytes_consumed =
177 file_stream_->ReadSync(buf, num_bytes_to_read);
178 }
179 if (num_bytes_consumed <= 0) {
180 // If there's less data to read than we initially observed, then
181 // pad with zero. Otherwise the server will hang waiting for the
182 // rest of the data.
183 memset(buf, 0, num_bytes_to_read);
184 }
185 }
186 DCHECK_GE(bytes_remaining_, num_bytes_to_read);
187 bytes_remaining_ -= num_bytes_to_read;
188 return num_bytes_to_read;
189 }
190
191 UploadFileElementReader::ScopedOverridingContentLengthForTests::
192 ScopedOverridingContentLengthForTests(uint64 value) {
193 overriding_content_length = value;
194 }
195
196 UploadFileElementReader::ScopedOverridingContentLengthForTests::
197 ~ScopedOverridingContentLengthForTests() {
198 overriding_content_length = 0;
199 }
200
201 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698