| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/file_stream.h" | 5 #include "net/base/file_stream.h" | 
| 6 | 6 | 
| 7 #include <windows.h> | 7 #include <windows.h> | 
| 8 | 8 | 
| 9 #include "base/file_path.h" | 9 #include "base/file_path.h" | 
| 10 #include "base/logging.h" | 10 #include "base/logging.h" | 
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 45     default: | 45     default: | 
| 46       LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; | 46       LOG(WARNING) << "Unknown error " << err << " mapped to net::ERR_FAILED"; | 
| 47       return ERR_FAILED; | 47       return ERR_FAILED; | 
| 48   } | 48   } | 
| 49 } | 49 } | 
| 50 | 50 | 
| 51 // FileStream::AsyncContext ---------------------------------------------- | 51 // FileStream::AsyncContext ---------------------------------------------- | 
| 52 | 52 | 
| 53 class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { | 53 class FileStream::AsyncContext : public MessageLoopForIO::IOHandler { | 
| 54  public: | 54  public: | 
| 55   AsyncContext(FileStream* owner) | 55   AsyncContext(FileStream* owner, int class_flags) | 
| 56       : owner_(owner), context_(), callback_(NULL), is_closing_(false) { | 56       : owner_(owner), context_(), callback_(NULL), is_closing_(false), | 
|  | 57         class_flags_(class_flags) { | 
| 57     context_.handler = this; | 58     context_.handler = this; | 
| 58   } | 59   } | 
| 59   ~AsyncContext(); | 60   ~AsyncContext(); | 
| 60 | 61 | 
| 61   void IOCompletionIsPending(CompletionCallback* callback); | 62   void IOCompletionIsPending(CompletionCallback* callback); | 
| 62 | 63 | 
| 63   OVERLAPPED* overlapped() { return &context_.overlapped; } | 64   OVERLAPPED* overlapped() { return &context_.overlapped; } | 
| 64   CompletionCallback* callback() const { return callback_; } | 65   CompletionCallback* callback() const { return callback_; } | 
| 65 | 66 | 
|  | 67   void EnableRecording(bool enable, int class_flags) { | 
|  | 68     if (enable) | 
|  | 69       class_flags_ |= class_flags; | 
|  | 70     else | 
|  | 71       class_flags_ &= ~class_flags; | 
|  | 72   } | 
|  | 73 | 
| 66  private: | 74  private: | 
| 67   virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, | 75   virtual void OnIOCompleted(MessageLoopForIO::IOContext* context, | 
| 68                              DWORD bytes_read, DWORD error); | 76                              DWORD bytes_read, DWORD error); | 
| 69 | 77 | 
| 70   FileStream* owner_; | 78   FileStream* owner_; | 
| 71   MessageLoopForIO::IOContext context_; | 79   MessageLoopForIO::IOContext context_; | 
| 72   CompletionCallback* callback_; | 80   CompletionCallback* callback_; | 
| 73   bool is_closing_; | 81   bool is_closing_; | 
|  | 82   int class_flags_; | 
| 74 }; | 83 }; | 
| 75 | 84 | 
| 76 FileStream::AsyncContext::~AsyncContext() { | 85 FileStream::AsyncContext::~AsyncContext() { | 
| 77   is_closing_ = true; | 86   is_closing_ = true; | 
| 78   bool waited = false; | 87   bool waited = false; | 
| 79   base::TimeTicks start = base::TimeTicks::Now(); | 88   base::TimeTicks start = base::TimeTicks::Now(); | 
| 80   while (callback_) { | 89   while (callback_) { | 
| 81     waited = true; | 90     waited = true; | 
| 82     MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); | 91     MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); | 
| 83   } | 92   } | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 98     MessageLoopForIO::IOContext* context, DWORD bytes_read, DWORD error) { | 107     MessageLoopForIO::IOContext* context, DWORD bytes_read, DWORD error) { | 
| 99   DCHECK_EQ(&context_, context); | 108   DCHECK_EQ(&context_, context); | 
| 100   DCHECK(callback_); | 109   DCHECK(callback_); | 
| 101 | 110 | 
| 102   if (is_closing_) { | 111   if (is_closing_) { | 
| 103     callback_ = NULL; | 112     callback_ = NULL; | 
| 104     return; | 113     return; | 
| 105   } | 114   } | 
| 106 | 115 | 
| 107   int result = static_cast<int>(bytes_read); | 116   int result = static_cast<int>(bytes_read); | 
| 108   if (error && error != ERROR_HANDLE_EOF) | 117   if (error && error != ERROR_HANDLE_EOF) { | 
|  | 118     RecordFileError(error, FILE_ERROR_TYPES_READ, class_flags_); | 
| 109     result = MapErrorCode(error); | 119     result = MapErrorCode(error); | 
|  | 120   } | 
| 110 | 121 | 
| 111   if (bytes_read) | 122   if (bytes_read) | 
| 112     IncrementOffset(&context->overlapped, bytes_read); | 123     IncrementOffset(&context->overlapped, bytes_read); | 
| 113 | 124 | 
| 114   CompletionCallback* temp = NULL; | 125   CompletionCallback* temp = NULL; | 
| 115   std::swap(temp, callback_); | 126   std::swap(temp, callback_); | 
| 116   temp->Run(result); | 127   temp->Run(result); | 
| 117 } | 128 } | 
| 118 | 129 | 
| 119 // FileStream ------------------------------------------------------------ | 130 // FileStream ------------------------------------------------------------ | 
| 120 | 131 | 
| 121 FileStream::FileStream() | 132 FileStream::FileStream() | 
| 122     : file_(INVALID_HANDLE_VALUE), | 133     : file_(INVALID_HANDLE_VALUE), | 
| 123       open_flags_(0), | 134       open_flags_(0), | 
| 124       auto_closed_(true) { | 135       auto_closed_(true), | 
|  | 136       class_flags_(0) { | 
|  | 137 } | 
|  | 138 | 
|  | 139 FileStream::FileStream(int class_flags) | 
|  | 140     : file_(INVALID_HANDLE_VALUE), | 
|  | 141       open_flags_(0), | 
|  | 142       auto_closed_(true), | 
|  | 143       class_flags_(class_flags) { | 
| 125 } | 144 } | 
| 126 | 145 | 
| 127 FileStream::FileStream(base::PlatformFile file, int flags) | 146 FileStream::FileStream(base::PlatformFile file, int flags) | 
| 128     : file_(file), | 147     : file_(file), | 
| 129       open_flags_(flags), | 148       open_flags_(flags), | 
| 130       auto_closed_(false) { | 149       auto_closed_(false), | 
|  | 150       class_flags_(0) { | 
| 131   // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to | 151   // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to | 
| 132   // make sure we will perform asynchronous File IO to it. | 152   // make sure we will perform asynchronous File IO to it. | 
| 133   if (flags & base::PLATFORM_FILE_ASYNC) { | 153   if (flags & base::PLATFORM_FILE_ASYNC) { | 
| 134     async_context_.reset(new AsyncContext(this)); | 154     async_context_.reset(new AsyncContext(this, class_flags_)); | 
| 135     MessageLoopForIO::current()->RegisterIOHandler(file_, | 155     MessageLoopForIO::current()->RegisterIOHandler(file_, | 
| 136                                                    async_context_.get()); | 156                                                    async_context_.get()); | 
| 137   } | 157   } | 
|  | 158 } | 
|  | 159 | 
|  | 160 FileStream::FileStream(base::PlatformFile file, int flags, int class_flags) | 
|  | 161     : file_(file), | 
|  | 162       open_flags_(flags), | 
|  | 163       auto_closed_(false), | 
|  | 164       class_flags_(class_flags) { | 
|  | 165   // If the file handle is opened with base::PLATFORM_FILE_ASYNC, we need to | 
|  | 166   // make sure we will perform asynchronous File IO to it. | 
|  | 167   if (flags & base::PLATFORM_FILE_ASYNC) { | 
|  | 168     async_context_.reset(new AsyncContext(this, class_flags_)); | 
|  | 169     MessageLoopForIO::current()->RegisterIOHandler(file_, | 
|  | 170                                                    async_context_.get()); | 
|  | 171   } | 
| 138 } | 172 } | 
| 139 | 173 | 
| 140 FileStream::~FileStream() { | 174 FileStream::~FileStream() { | 
| 141   if (auto_closed_) | 175   if (auto_closed_) | 
| 142     Close(); | 176     Close(); | 
| 143 } | 177 } | 
| 144 | 178 | 
| 145 void FileStream::Close() { | 179 void FileStream::Close() { | 
| 146   if (file_ != INVALID_HANDLE_VALUE) | 180   if (file_ != INVALID_HANDLE_VALUE) | 
| 147     CancelIo(file_); | 181     CancelIo(file_); | 
| 148 | 182 | 
| 149   async_context_.reset(); | 183   async_context_.reset(); | 
| 150   if (file_ != INVALID_HANDLE_VALUE) { | 184   if (file_ != INVALID_HANDLE_VALUE) { | 
| 151     CloseHandle(file_); | 185     CloseHandle(file_); | 
| 152     file_ = INVALID_HANDLE_VALUE; | 186     file_ = INVALID_HANDLE_VALUE; | 
| 153   } | 187   } | 
| 154 } | 188 } | 
| 155 | 189 | 
| 156 int FileStream::Open(const FilePath& path, int open_flags) { | 190 int FileStream::Open(const FilePath& path, int open_flags) { | 
| 157   if (IsOpen()) { | 191   if (IsOpen()) { | 
| 158     DLOG(FATAL) << "File is already open!"; | 192     DLOG(FATAL) << "File is already open!"; | 
| 159     return ERR_UNEXPECTED; | 193     return ERR_UNEXPECTED; | 
| 160   } | 194   } | 
| 161 | 195 | 
| 162   open_flags_ = open_flags; | 196   open_flags_ = open_flags; | 
| 163   file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL); | 197   file_ = base::CreatePlatformFile(path, open_flags_, NULL, NULL); | 
| 164   if (file_ == INVALID_HANDLE_VALUE) { | 198   if (file_ == INVALID_HANDLE_VALUE) { | 
| 165     DWORD error = GetLastError(); | 199     DWORD error = GetLastError(); | 
| 166     LOG(WARNING) << "Failed to open file: " << error; | 200     LOG(WARNING) << "Failed to open file: " << error; | 
|  | 201     RecordFileError(error, FILE_ERROR_TYPES_OPEN, class_flags_); | 
| 167     return MapErrorCode(error); | 202     return MapErrorCode(error); | 
| 168   } | 203   } | 
| 169 | 204 | 
| 170   if (open_flags_ & base::PLATFORM_FILE_ASYNC) { | 205   if (open_flags_ & base::PLATFORM_FILE_ASYNC) { | 
| 171     async_context_.reset(new AsyncContext(this)); | 206     async_context_.reset(new AsyncContext(this, class_flags_)); | 
| 172     MessageLoopForIO::current()->RegisterIOHandler(file_, | 207     MessageLoopForIO::current()->RegisterIOHandler(file_, | 
| 173                                                    async_context_.get()); | 208                                                    async_context_.get()); | 
| 174   } | 209   } | 
| 175 | 210 | 
| 176   return OK; | 211   return OK; | 
| 177 } | 212 } | 
| 178 | 213 | 
| 179 bool FileStream::IsOpen() const { | 214 bool FileStream::IsOpen() const { | 
| 180   return file_ != INVALID_HANDLE_VALUE; | 215   return file_ != INVALID_HANDLE_VALUE; | 
| 181 } | 216 } | 
| 182 | 217 | 
| 183 int64 FileStream::Seek(Whence whence, int64 offset) { | 218 int64 FileStream::Seek(Whence whence, int64 offset) { | 
| 184   if (!IsOpen()) | 219   if (!IsOpen()) { | 
|  | 220     RecordFileError(ERROR_INVALID_HANDLE, FILE_ERROR_TYPES_IS_NOT_OPEN, | 
|  | 221                     class_flags_); | 
| 185     return ERR_UNEXPECTED; | 222     return ERR_UNEXPECTED; | 
|  | 223   } | 
|  | 224 | 
| 186   DCHECK(!async_context_.get() || !async_context_->callback()); | 225   DCHECK(!async_context_.get() || !async_context_->callback()); | 
| 187 | 226 | 
| 188   LARGE_INTEGER distance, result; | 227   LARGE_INTEGER distance, result; | 
| 189   distance.QuadPart = offset; | 228   distance.QuadPart = offset; | 
| 190   DWORD move_method = static_cast<DWORD>(whence); | 229   DWORD move_method = static_cast<DWORD>(whence); | 
| 191   if (!SetFilePointerEx(file_, distance, &result, move_method)) { | 230   if (!SetFilePointerEx(file_, distance, &result, move_method)) { | 
| 192     DWORD error = GetLastError(); | 231     DWORD error = GetLastError(); | 
| 193     LOG(WARNING) << "SetFilePointerEx failed: " << error; | 232     LOG(WARNING) << "SetFilePointerEx failed: " << error; | 
|  | 233     RecordFileError(error, FILE_ERROR_TYPES_SEEK, class_flags_); | 
| 194     return MapErrorCode(error); | 234     return MapErrorCode(error); | 
| 195   } | 235   } | 
| 196   if (async_context_.get()) | 236   if (async_context_.get()) | 
| 197     SetOffset(async_context_->overlapped(), result); | 237     SetOffset(async_context_->overlapped(), result); | 
| 198   return result.QuadPart; | 238   return result.QuadPart; | 
| 199 } | 239 } | 
| 200 | 240 | 
| 201 int64 FileStream::Available() { | 241 int64 FileStream::Available() { | 
| 202   base::ThreadRestrictions::AssertIOAllowed(); | 242   base::ThreadRestrictions::AssertIOAllowed(); | 
| 203 | 243 | 
| 204   if (!IsOpen()) | 244   if (!IsOpen()) { | 
|  | 245     RecordFileError(ERROR_INVALID_HANDLE, FILE_ERROR_TYPES_IS_NOT_OPEN, | 
|  | 246                     class_flags_); | 
| 205     return ERR_UNEXPECTED; | 247     return ERR_UNEXPECTED; | 
|  | 248   } | 
| 206 | 249 | 
| 207   int64 cur_pos = Seek(FROM_CURRENT, 0); | 250   int64 cur_pos = Seek(FROM_CURRENT, 0); | 
| 208   if (cur_pos < 0) | 251   if (cur_pos < 0) | 
| 209     return cur_pos; | 252     return cur_pos; | 
| 210 | 253 | 
| 211   LARGE_INTEGER file_size; | 254   LARGE_INTEGER file_size; | 
| 212   if (!GetFileSizeEx(file_, &file_size)) { | 255   if (!GetFileSizeEx(file_, &file_size)) { | 
| 213     DWORD error = GetLastError(); | 256     DWORD error = GetLastError(); | 
| 214     LOG(WARNING) << "GetFileSizeEx failed: " << error; | 257     LOG(WARNING) << "GetFileSizeEx failed: " << error; | 
|  | 258     RecordFileError(error, FILE_ERROR_TYPES_GET_SIZE, class_flags_); | 
| 215     return MapErrorCode(error); | 259     return MapErrorCode(error); | 
| 216   } | 260   } | 
| 217 | 261 | 
| 218   return file_size.QuadPart - cur_pos; | 262   return file_size.QuadPart - cur_pos; | 
| 219 } | 263 } | 
| 220 | 264 | 
| 221 int FileStream::Read( | 265 int FileStream::Read( | 
| 222     char* buf, int buf_len, CompletionCallback* callback) { | 266     char* buf, int buf_len, CompletionCallback* callback) { | 
| 223   if (!IsOpen()) | 267   if (!IsOpen()) { | 
|  | 268     RecordFileError(ERROR_INVALID_HANDLE, FILE_ERROR_TYPES_IS_NOT_OPEN, | 
|  | 269                     class_flags_); | 
| 224     return ERR_UNEXPECTED; | 270     return ERR_UNEXPECTED; | 
|  | 271   } | 
|  | 272 | 
| 225   DCHECK(open_flags_ & base::PLATFORM_FILE_READ); | 273   DCHECK(open_flags_ & base::PLATFORM_FILE_READ); | 
| 226 | 274 | 
| 227   OVERLAPPED* overlapped = NULL; | 275   OVERLAPPED* overlapped = NULL; | 
| 228   if (async_context_.get()) { | 276   if (async_context_.get()) { | 
| 229     DCHECK(callback); | 277     DCHECK(callback); | 
| 230     DCHECK(!async_context_->callback()); | 278     DCHECK(!async_context_->callback()); | 
| 231     overlapped = async_context_->overlapped(); | 279     overlapped = async_context_->overlapped(); | 
| 232   } else { | 280   } else { | 
| 233     DCHECK(!callback); | 281     DCHECK(!callback); | 
| 234     base::ThreadRestrictions::AssertIOAllowed(); | 282     base::ThreadRestrictions::AssertIOAllowed(); | 
| 235   } | 283   } | 
| 236 | 284 | 
| 237   int rv; | 285   int rv; | 
| 238 | 286 | 
| 239   DWORD bytes_read; | 287   DWORD bytes_read; | 
| 240   if (!ReadFile(file_, buf, buf_len, &bytes_read, overlapped)) { | 288   if (!ReadFile(file_, buf, buf_len, &bytes_read, overlapped)) { | 
| 241     DWORD error = GetLastError(); | 289     DWORD error = GetLastError(); | 
| 242     if (async_context_.get() && error == ERROR_IO_PENDING) { | 290     if (async_context_.get() && error == ERROR_IO_PENDING) { | 
| 243       async_context_->IOCompletionIsPending(callback); | 291       async_context_->IOCompletionIsPending(callback); | 
| 244       rv = ERR_IO_PENDING; | 292       rv = ERR_IO_PENDING; | 
| 245     } else if (error == ERROR_HANDLE_EOF) { | 293     } else if (error == ERROR_HANDLE_EOF) { | 
| 246       rv = 0;  // Report EOF by returning 0 bytes read. | 294       rv = 0;  // Report EOF by returning 0 bytes read. | 
| 247     } else { | 295     } else { | 
| 248       LOG(WARNING) << "ReadFile failed: " << error; | 296       LOG(WARNING) << "ReadFile failed: " << error; | 
|  | 297       RecordFileError(error, FILE_ERROR_TYPES_READ, class_flags_); | 
| 249       rv = MapErrorCode(error); | 298       rv = MapErrorCode(error); | 
| 250     } | 299     } | 
| 251   } else if (overlapped) { | 300   } else if (overlapped) { | 
| 252     async_context_->IOCompletionIsPending(callback); | 301     async_context_->IOCompletionIsPending(callback); | 
| 253     rv = ERR_IO_PENDING; | 302     rv = ERR_IO_PENDING; | 
| 254   } else { | 303   } else { | 
| 255     rv = static_cast<int>(bytes_read); | 304     rv = static_cast<int>(bytes_read); | 
| 256   } | 305   } | 
| 257   return rv; | 306   return rv; | 
| 258 } | 307 } | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 273     bytes_total += bytes_read; | 322     bytes_total += bytes_read; | 
| 274     buf += bytes_read; | 323     buf += bytes_read; | 
| 275     to_read -= bytes_read; | 324     to_read -= bytes_read; | 
| 276   } while (bytes_total < buf_len); | 325   } while (bytes_total < buf_len); | 
| 277 | 326 | 
| 278   return bytes_total; | 327   return bytes_total; | 
| 279 } | 328 } | 
| 280 | 329 | 
| 281 int FileStream::Write( | 330 int FileStream::Write( | 
| 282     const char* buf, int buf_len, CompletionCallback* callback) { | 331     const char* buf, int buf_len, CompletionCallback* callback) { | 
| 283   if (!IsOpen()) | 332   if (!IsOpen()) { | 
|  | 333     RecordFileError(ERROR_INVALID_HANDLE, FILE_ERROR_TYPES_IS_NOT_OPEN, | 
|  | 334                     class_flags_); | 
| 284     return ERR_UNEXPECTED; | 335     return ERR_UNEXPECTED; | 
|  | 336   } | 
| 285   DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); | 337   DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); | 
| 286 | 338 | 
| 287   OVERLAPPED* overlapped = NULL; | 339   OVERLAPPED* overlapped = NULL; | 
| 288   if (async_context_.get()) { | 340   if (async_context_.get()) { | 
| 289     DCHECK(callback); | 341     DCHECK(callback); | 
| 290     DCHECK(!async_context_->callback()); | 342     DCHECK(!async_context_->callback()); | 
| 291     overlapped = async_context_->overlapped(); | 343     overlapped = async_context_->overlapped(); | 
| 292   } else { | 344   } else { | 
| 293     DCHECK(!callback); | 345     DCHECK(!callback); | 
| 294     base::ThreadRestrictions::AssertIOAllowed(); | 346     base::ThreadRestrictions::AssertIOAllowed(); | 
| 295   } | 347   } | 
| 296 | 348 | 
| 297   int rv; | 349   int rv; | 
| 298   DWORD bytes_written; | 350   DWORD bytes_written; | 
| 299   if (!WriteFile(file_, buf, buf_len, &bytes_written, overlapped)) { | 351   if (!WriteFile(file_, buf, buf_len, &bytes_written, overlapped)) { | 
| 300     DWORD error = GetLastError(); | 352     DWORD error = GetLastError(); | 
| 301     if (async_context_.get() && error == ERROR_IO_PENDING) { | 353     if (async_context_.get() && error == ERROR_IO_PENDING) { | 
| 302       async_context_->IOCompletionIsPending(callback); | 354       async_context_->IOCompletionIsPending(callback); | 
| 303       rv = ERR_IO_PENDING; | 355       rv = ERR_IO_PENDING; | 
| 304     } else { | 356     } else { | 
| 305       LOG(WARNING) << "WriteFile failed: " << error; | 357       LOG(WARNING) << "WriteFile failed: " << error; | 
|  | 358       RecordFileError(error, FILE_ERROR_TYPES_WRITE, class_flags_); | 
| 306       rv = MapErrorCode(error); | 359       rv = MapErrorCode(error); | 
| 307     } | 360     } | 
| 308   } else if (overlapped) { | 361   } else if (overlapped) { | 
| 309     async_context_->IOCompletionIsPending(callback); | 362     async_context_->IOCompletionIsPending(callback); | 
| 310     rv = ERR_IO_PENDING; | 363     rv = ERR_IO_PENDING; | 
| 311   } else { | 364   } else { | 
| 312     rv = static_cast<int>(bytes_written); | 365     rv = static_cast<int>(bytes_written); | 
| 313   } | 366   } | 
| 314   return rv; | 367   return rv; | 
| 315 } | 368 } | 
| 316 | 369 | 
| 317 int FileStream::Flush() { | 370 int FileStream::Flush() { | 
| 318   base::ThreadRestrictions::AssertIOAllowed(); | 371   base::ThreadRestrictions::AssertIOAllowed(); | 
| 319 | 372 | 
| 320   if (!IsOpen()) | 373   if (!IsOpen()) { | 
|  | 374     RecordFileError(ERROR_INVALID_HANDLE, FILE_ERROR_TYPES_IS_NOT_OPEN, | 
|  | 375                     class_flags_); | 
| 321     return ERR_UNEXPECTED; | 376     return ERR_UNEXPECTED; | 
|  | 377   } | 
| 322 | 378 | 
| 323   DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); | 379   DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); | 
| 324   if (FlushFileBuffers(file_)) { | 380   if (FlushFileBuffers(file_)) { | 
| 325     return OK; | 381     return OK; | 
| 326   } | 382   } | 
| 327 | 383 | 
| 328   int rv; | 384   int rv; | 
| 329   DWORD error = GetLastError(); | 385   DWORD error = GetLastError(); | 
|  | 386   RecordFileError(error, FILE_ERROR_TYPES_FLUSH, class_flags_); | 
| 330   rv = MapErrorCode(error); | 387   rv = MapErrorCode(error); | 
| 331   return rv; | 388   return rv; | 
| 332 } | 389 } | 
| 333 | 390 | 
| 334 int64 FileStream::Truncate(int64 bytes) { | 391 int64 FileStream::Truncate(int64 bytes) { | 
| 335   base::ThreadRestrictions::AssertIOAllowed(); | 392   base::ThreadRestrictions::AssertIOAllowed(); | 
| 336 | 393 | 
| 337   if (!IsOpen()) | 394   if (!IsOpen()) { | 
|  | 395     RecordFileError(ERROR_INVALID_HANDLE, FILE_ERROR_TYPES_IS_NOT_OPEN, | 
|  | 396                     class_flags_); | 
| 338     return ERR_UNEXPECTED; | 397     return ERR_UNEXPECTED; | 
|  | 398   } | 
| 339 | 399 | 
| 340   // We better be open for reading. | 400   // We better be open for reading. | 
| 341   DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); | 401   DCHECK(open_flags_ & base::PLATFORM_FILE_WRITE); | 
| 342 | 402 | 
| 343   // Seek to the position to truncate from. | 403   // Seek to the position to truncate from. | 
| 344   int64 seek_position = Seek(FROM_BEGIN, bytes); | 404   int64 seek_position = Seek(FROM_BEGIN, bytes); | 
| 345   if (seek_position != bytes) | 405   if (seek_position != bytes) | 
| 346     return ERR_UNEXPECTED; | 406     return ERR_UNEXPECTED; | 
| 347 | 407 | 
| 348   // And truncate the file. | 408   // And truncate the file. | 
| 349   BOOL result = SetEndOfFile(file_); | 409   BOOL result = SetEndOfFile(file_); | 
| 350   if (!result) { | 410   if (!result) { | 
| 351     DWORD error = GetLastError(); | 411     DWORD error = GetLastError(); | 
| 352     LOG(WARNING) << "SetEndOfFile failed: " << error; | 412     LOG(WARNING) << "SetEndOfFile failed: " << error; | 
|  | 413     RecordFileError(error, FILE_ERROR_TYPES_SET_EOF, class_flags_); | 
| 353     return MapErrorCode(error); | 414     return MapErrorCode(error); | 
| 354   } | 415   } | 
| 355 | 416 | 
| 356   // Success. | 417   // Success. | 
| 357   return seek_position; | 418   return seek_position; | 
| 358 } | 419 } | 
| 359 | 420 | 
|  | 421 void FileStream::EnableRecording(bool enable, int class_flags) { | 
|  | 422   if (enable) | 
|  | 423     class_flags_ |= class_flags; | 
|  | 424   else | 
|  | 425     class_flags_ &= ~class_flags; | 
|  | 426 | 
|  | 427   if (async_context_.get()) | 
|  | 428     async_context_->EnableRecording(enable, class_flags); | 
|  | 429 } | 
|  | 430 | 
| 360 }  // namespace net | 431 }  // namespace net | 
| OLD | NEW | 
|---|