OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/upload_data.h" | 5 #include "net/base/upload_data.h" |
6 | 6 |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "net/base/net_errors.h" |
9 | 10 |
10 namespace net { | 11 namespace net { |
11 | 12 |
12 uint64 UploadData::GetContentLength() const { | 13 uint64 UploadData::GetContentLength() { |
13 uint64 len = 0; | 14 uint64 len = 0; |
14 std::vector<Element>::const_iterator it = elements_.begin(); | 15 std::vector<Element>::iterator it = elements_.begin(); |
15 for (; it != elements_.end(); ++it) | 16 for (; it != elements_.end(); ++it) |
16 len += (*it).GetContentLength(); | 17 len += (*it).GetContentLength(); |
17 return len; | 18 return len; |
18 } | 19 } |
19 | 20 |
20 uint64 UploadData::Element::GetContentLength() const { | 21 uint64 UploadData::Element::GetContentLength() { |
21 if (override_content_length_) | 22 if (override_content_length_ || content_length_computed_) |
22 return content_length_; | 23 return content_length_; |
23 | 24 |
24 if (type_ == TYPE_BYTES) | 25 if (type_ == TYPE_BYTES) |
25 return static_cast<uint64>(bytes_.size()); | 26 return static_cast<uint64>(bytes_.size()); |
26 | 27 |
27 DCHECK(type_ == TYPE_FILE); | 28 DCHECK_EQ(TYPE_FILE, type_); |
| 29 DCHECK(!file_stream_); |
28 | 30 |
29 // TODO(darin): This size calculation could be out of sync with the state of | 31 // TODO(darin): This size calculation could be out of sync with the state of |
30 // the file when we get around to reading it. We should probably find a way | 32 // the file when we get around to reading it. We should probably find a way |
31 // to lock the file or somehow protect against this error condition. | 33 // to lock the file or somehow protect against this error condition. |
32 | 34 |
| 35 content_length_computed_ = true; |
| 36 content_length_ = 0; |
| 37 |
| 38 // We need to open the file here to decide if we should report the file's |
| 39 // size or zero. We cache the open file, so that we can still read it when |
| 40 // it comes time to. |
| 41 file_stream_ = NewFileStreamForReading(); |
| 42 if (!file_stream_) |
| 43 return 0; |
| 44 |
33 int64 length = 0; | 45 int64 length = 0; |
34 if (!file_util::GetFileSize(file_path_, &length)) | 46 if (!file_util::GetFileSize(file_path_, &length)) |
35 return 0; | 47 return 0; |
36 | 48 |
37 if (file_range_offset_ >= static_cast<uint64>(length)) | 49 if (file_range_offset_ >= static_cast<uint64>(length)) |
38 return 0; // range is beyond eof | 50 return 0; // range is beyond eof |
39 | 51 |
40 // compensate for the offset and clip file_range_length_ to eof | 52 // compensate for the offset and clip file_range_length_ to eof |
41 return std::min(length - file_range_offset_, file_range_length_); | 53 content_length_ = std::min(length - file_range_offset_, file_range_length_); |
| 54 return content_length_; |
| 55 } |
| 56 |
| 57 FileStream* UploadData::Element::NewFileStreamForReading() { |
| 58 // In common usage GetContentLength() will call this first and store the |
| 59 // result into |file_| and a subsequent call (from UploadDataStream) will |
| 60 // get the cached open FileStream. |
| 61 if (file_stream_) { |
| 62 FileStream* file = file_stream_; |
| 63 file_stream_ = NULL; |
| 64 return file; |
| 65 } |
| 66 |
| 67 scoped_ptr<FileStream> file(new FileStream()); |
| 68 int64 rv = file->Open(file_path_, |
| 69 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ); |
| 70 if (rv != OK) { |
| 71 // If the file can't be opened, we'll just upload an empty file. |
| 72 DLOG(WARNING) << "Failed to open \"" << file_path_.value() |
| 73 << "\" for reading: " << rv; |
| 74 return NULL; |
| 75 } |
| 76 if (file_range_offset_) { |
| 77 rv = file->Seek(FROM_BEGIN, file_range_offset_); |
| 78 if (rv < 0) { |
| 79 DLOG(WARNING) << "Failed to seek \"" << file_path_.value() |
| 80 << "\" to offset: " << file_range_offset_ << " (" << rv |
| 81 << ")"; |
| 82 return NULL; |
| 83 } |
| 84 } |
| 85 |
| 86 return file.release(); |
42 } | 87 } |
43 | 88 |
44 } // namespace net | 89 } // namespace net |
OLD | NEW |