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

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

Issue 8843: Add write and read/write support to FileStream (renamed from FileInputStream)... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month 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
« no previous file with comments | « net/base/file_stream.h ('k') | net/base/file_stream_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:mergeinfo
Merged /branches/chrome_webkit_merge_branch/net/base/file_input_stream_posix.cc:r69-2775
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. Use of this
2 // source code is governed by a BSD-style license that can be found in the 2 // source code is governed by a BSD-style license that can be found in the
3 // LICENSE file. 3 // LICENSE file.
4 4
5 // For 64-bit file access (off_t = off64_t, lseek64, etc). 5 // For 64-bit file access (off_t = off64_t, lseek64, etc).
6 #define _FILE_OFFSET_BITS 64 6 #define _FILE_OFFSET_BITS 64
7 7
8 #include "net/base/file_input_stream.h" 8 #include "net/base/file_stream.h"
9 9
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <sys/stat.h> 11 #include <sys/stat.h>
12 #include <fcntl.h> 12 #include <fcntl.h>
13 #include <unistd.h> 13 #include <unistd.h>
14 #include <errno.h> 14 #include <errno.h>
15 15
16 #include "base/basictypes.h" 16 #include "base/basictypes.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/message_loop.h" 18 #include "base/message_loop.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "net/base/net_errors.h" 20 #include "net/base/net_errors.h"
21 21
22 // We cast back and forth, so make sure it's the size we're expecting. 22 // We cast back and forth, so make sure it's the size we're expecting.
23 COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit); 23 COMPILE_ASSERT(sizeof(int64) == sizeof(off_t), off_t_64_bit);
24 24
25 // Make sure our Whence mappings match the system headers. 25 // Make sure our Whence mappings match the system headers.
26 COMPILE_ASSERT(net::FROM_BEGIN == SEEK_SET && 26 COMPILE_ASSERT(net::FROM_BEGIN == SEEK_SET &&
27 net::FROM_CURRENT == SEEK_CUR && 27 net::FROM_CURRENT == SEEK_CUR &&
28 net::FROM_END == SEEK_END, whence_matches_system); 28 net::FROM_END == SEEK_END, whence_matches_system);
29 29
30 namespace net { 30 namespace net {
31 31
32 // FileInputStream::AsyncContext ---------------------------------------------- 32 // FileStream::AsyncContext ----------------------------------------------
33 33
34 // TODO(deanm): Figure out how to best do async IO. 34 // TODO(deanm): Figure out how to best do async IO.
35 class FileInputStream::AsyncContext { 35 class FileStream::AsyncContext {
36 public: 36 public:
37 37
38 CompletionCallback* callback() const { return NULL; } 38 CompletionCallback* callback() const { return NULL; }
39 private: 39 private:
40 40
41 DISALLOW_COPY_AND_ASSIGN(AsyncContext); 41 DISALLOW_COPY_AND_ASSIGN(AsyncContext);
42 }; 42 };
43 43
44 // FileInputStream ------------------------------------------------------------ 44 // FileStream ------------------------------------------------------------
45 45
46 FileInputStream::FileInputStream() : fd_(-1) { 46 FileStream::FileStream() : file_(base::kInvalidPlatformFileValue) {
47 DCHECK(!IsOpen()); 47 DCHECK(!IsOpen());
48 } 48 }
49 49
50 FileInputStream::~FileInputStream() { 50 FileStream::~FileStream() {
51 Close(); 51 Close();
52 } 52 }
53 53
54 void FileInputStream::Close() { 54 void FileStream::Close() {
55 if (fd_ != -1) { 55 if (file_ != base::kInvalidPlatformFileValue) {
56 if (close(fd_) != 0) { 56 if (close(file_) != 0) {
57 NOTREACHED(); 57 NOTREACHED();
58 } 58 }
59 fd_ = -1; 59 file_ = base::kInvalidPlatformFileValue;
60 } 60 }
61 async_context_.reset(); 61 async_context_.reset();
62 } 62 }
63 63
64 // Map from errno to net error codes. 64 // Map from errno to net error codes.
65 static int64 MapErrorCode(int err) { 65 static int64 MapErrorCode(int err) {
66 switch(err) { 66 switch(err) {
67 case ENOENT: 67 case ENOENT:
68 return ERR_FILE_NOT_FOUND; 68 return ERR_FILE_NOT_FOUND;
69 case EACCES: 69 case EACCES:
70 return ERR_ACCESS_DENIED; 70 return ERR_ACCESS_DENIED;
71 default: 71 default:
72 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; 72 LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED";
73 return ERR_FAILED; 73 return ERR_FAILED;
74 } 74 }
75 } 75 }
76 76
77 int FileInputStream::Open(const std::wstring& path, bool asynchronous_mode) { 77 int FileStream::Open(const std::wstring& path, int open_flags) {
78 // We don't need O_LARGEFILE here since we set the 64-bit off_t feature. 78 if (IsOpen()) {
79 fd_ = open(WideToUTF8(path).c_str(), 0, O_RDONLY); 79 DLOG(FATAL) << "File is already open!";
80 if (fd_ == -1) 80 return ERR_UNEXPECTED;
81 }
82
83 open_flags_ = open_flags;
84 file_ = base::CreatePlatformFile(path, open_flags_, NULL);
85 if (file_ == base::kInvalidPlatformFileValue) {
86 LOG(WARNING) << "Failed to open file: " << errno;
81 return MapErrorCode(errno); 87 return MapErrorCode(errno);
88 }
82 89
83 return OK; 90 return OK;
84 } 91 }
85 92
86 bool FileInputStream::IsOpen() const { 93 bool FileStream::IsOpen() const {
87 return fd_ != -1; 94 return file_ != base::kInvalidPlatformFileValue;
88 } 95 }
89 96
90 int64 FileInputStream::Seek(Whence whence, int64 offset) { 97 int64 FileStream::Seek(Whence whence, int64 offset) {
91 if (!IsOpen()) 98 if (!IsOpen())
92 return ERR_UNEXPECTED; 99 return ERR_UNEXPECTED;
93 100
94 // If we're in async, make sure we don't have a request in flight. 101 // If we're in async, make sure we don't have a request in flight.
95 DCHECK(!async_context_.get() || !async_context_->callback()); 102 DCHECK(!async_context_.get() || !async_context_->callback());
96 103
97 off_t res = lseek(fd_, static_cast<off_t>(offset), static_cast<int>(whence)); 104 off_t res = lseek(file_, static_cast<off_t>(offset),
105 static_cast<int>(whence));
98 if (res == static_cast<off_t>(-1)) 106 if (res == static_cast<off_t>(-1))
99 return MapErrorCode(errno); 107 return MapErrorCode(errno);
100 108
101 return res; 109 return res;
102 } 110 }
103 111
104 int64 FileInputStream::Available() { 112 int64 FileStream::Available() {
105 if (!IsOpen()) 113 if (!IsOpen())
106 return ERR_UNEXPECTED; 114 return ERR_UNEXPECTED;
107 115
108 int64 cur_pos = Seek(FROM_CURRENT, 0); 116 int64 cur_pos = Seek(FROM_CURRENT, 0);
109 if (cur_pos < 0) 117 if (cur_pos < 0)
110 return cur_pos; 118 return cur_pos;
111 119
112 struct stat info; 120 struct stat info;
113 if (fstat(fd_, &info) != 0) 121 if (fstat(file_, &info) != 0)
114 return MapErrorCode(errno); 122 return MapErrorCode(errno);
115 123
116 int64 size = static_cast<int64>(info.st_size); 124 int64 size = static_cast<int64>(info.st_size);
117 DCHECK(size >= cur_pos); 125 DCHECK(size >= cur_pos);
118 126
119 return size - cur_pos; 127 return size - cur_pos;
120 } 128 }
121 129
122 // TODO(deanm): async. 130 // TODO(deanm): async.
123 int FileInputStream::Read( 131 int FileStream::Read(
124 char* buf, int buf_len, CompletionCallback* callback) { 132 char* buf, int buf_len, CompletionCallback* callback) {
125 // read(..., 0) will return 0, which indicates end-of-file. 133 // read(..., 0) will return 0, which indicates end-of-file.
126 DCHECK(buf_len > 0 && buf_len <= SSIZE_MAX); 134 DCHECK(buf_len > 0 && buf_len <= SSIZE_MAX);
127 135
128 if (!IsOpen()) 136 if (!IsOpen())
129 return ERR_UNEXPECTED; 137 return ERR_UNEXPECTED;
130 138
131 // Loop in the case of getting interrupted by a signal. 139 // Loop in the case of getting interrupted by a signal.
132 for (;;) { 140 for (;;) {
133 ssize_t res = read(fd_, buf, static_cast<size_t>(buf_len)); 141 ssize_t res = read(file_, buf, static_cast<size_t>(buf_len));
134 if (res == static_cast<ssize_t>(-1)) { 142 if (res == static_cast<ssize_t>(-1)) {
135 if (errno == EINTR) 143 if (errno == EINTR)
136 continue; 144 continue;
137 return MapErrorCode(errno); 145 return MapErrorCode(errno);
138 } 146 }
139 return static_cast<int>(res); 147 return static_cast<int>(res);
140 } 148 }
141 } 149 }
142 150
151 // TODO(deanm): async.
152 int FileStream::Write(
153 const char* buf, int buf_len, CompletionCallback* callback) {
154
155 // read(..., 0) will return 0, which indicates end-of-file.
156 DCHECK(buf_len > 0 && buf_len <= SSIZE_MAX);
157
158 if (!IsOpen())
159 return ERR_UNEXPECTED;
160
161 int total_bytes_written = 0;
162 size_t len = static_cast<size_t>(buf_len);
163 while (total_bytes_written < buf_len) {
164 ssize_t res = write(file_, buf, len);
165 if (res == static_cast<ssize_t>(-1)) {
166 if (errno == EINTR)
167 continue;
168 return MapErrorCode(errno);
169 }
170 total_bytes_written += res;
171 buf += res;
172 len -= res;
173 }
174 return total_bytes_written;
175 }
176
143 } // namespace net 177 } // namespace net
OLDNEW
« no previous file with comments | « net/base/file_stream.h ('k') | net/base/file_stream_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698