| OLD | NEW | 
|    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |    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 |    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 "base/files/file.h" |    5 #include "base/files/file.h" | 
|    6  |    6  | 
|    7 #include <io.h> |    7 #include <io.h> | 
|    8  |    8  | 
|    9 #include "base/files/file_path.h" |    9 #include "base/files/file_path.h" | 
|   10 #include "base/logging.h" |   10 #include "base/logging.h" | 
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  100   } else { |  100   } else { | 
|  101     error_details_ = OSErrorToFileError(GetLastError()); |  101     error_details_ = OSErrorToFileError(GetLastError()); | 
|  102   } |  102   } | 
|  103 } |  103 } | 
|  104  |  104  | 
|  105 bool File::IsValid() const { |  105 bool File::IsValid() const { | 
|  106   return file_.IsValid(); |  106   return file_.IsValid(); | 
|  107 } |  107 } | 
|  108  |  108  | 
|  109 PlatformFile File::GetPlatformFile() const { |  109 PlatformFile File::GetPlatformFile() const { | 
|  110   return file_; |  110   return file_.Get(); | 
|  111 } |  111 } | 
|  112  |  112  | 
|  113 PlatformFile File::TakePlatformFile() { |  113 PlatformFile File::TakePlatformFile() { | 
|  114   return file_.Take(); |  114   return file_.Take(); | 
|  115 } |  115 } | 
|  116  |  116  | 
|  117 void File::Close() { |  117 void File::Close() { | 
|  118   if (file_.IsValid()) { |  118   if (file_.IsValid()) { | 
|  119     base::ThreadRestrictions::AssertIOAllowed(); |  119     base::ThreadRestrictions::AssertIOAllowed(); | 
|  120     file_.Close(); |  120     file_.Close(); | 
|  121   } |  121   } | 
|  122 } |  122 } | 
|  123  |  123  | 
|  124 int64 File::Seek(Whence whence, int64 offset) { |  124 int64 File::Seek(Whence whence, int64 offset) { | 
|  125   base::ThreadRestrictions::AssertIOAllowed(); |  125   base::ThreadRestrictions::AssertIOAllowed(); | 
|  126   DCHECK(IsValid()); |  126   DCHECK(IsValid()); | 
|  127  |  127  | 
|  128   LARGE_INTEGER distance, res; |  128   LARGE_INTEGER distance, res; | 
|  129   distance.QuadPart = offset; |  129   distance.QuadPart = offset; | 
|  130   DWORD move_method = static_cast<DWORD>(whence); |  130   DWORD move_method = static_cast<DWORD>(whence); | 
|  131   if (!SetFilePointerEx(file_, distance, &res, move_method)) |  131   if (!SetFilePointerEx(file_.Get(), distance, &res, move_method)) | 
|  132     return -1; |  132     return -1; | 
|  133   return res.QuadPart; |  133   return res.QuadPart; | 
|  134 } |  134 } | 
|  135  |  135  | 
|  136 int File::Read(int64 offset, char* data, int size) { |  136 int File::Read(int64 offset, char* data, int size) { | 
|  137   base::ThreadRestrictions::AssertIOAllowed(); |  137   base::ThreadRestrictions::AssertIOAllowed(); | 
|  138   DCHECK(IsValid()); |  138   DCHECK(IsValid()); | 
|  139   DCHECK(!async_); |  139   DCHECK(!async_); | 
|  140   if (size < 0) |  140   if (size < 0) | 
|  141     return -1; |  141     return -1; | 
|  142  |  142  | 
|  143   LARGE_INTEGER offset_li; |  143   LARGE_INTEGER offset_li; | 
|  144   offset_li.QuadPart = offset; |  144   offset_li.QuadPart = offset; | 
|  145  |  145  | 
|  146   OVERLAPPED overlapped = {0}; |  146   OVERLAPPED overlapped = {0}; | 
|  147   overlapped.Offset = offset_li.LowPart; |  147   overlapped.Offset = offset_li.LowPart; | 
|  148   overlapped.OffsetHigh = offset_li.HighPart; |  148   overlapped.OffsetHigh = offset_li.HighPart; | 
|  149  |  149  | 
|  150   DWORD bytes_read; |  150   DWORD bytes_read; | 
|  151   if (::ReadFile(file_, data, size, &bytes_read, &overlapped)) |  151   if (::ReadFile(file_.Get(), data, size, &bytes_read, &overlapped)) | 
|  152     return bytes_read; |  152     return bytes_read; | 
|  153   if (ERROR_HANDLE_EOF == GetLastError()) |  153   if (ERROR_HANDLE_EOF == GetLastError()) | 
|  154     return 0; |  154     return 0; | 
|  155  |  155  | 
|  156   return -1; |  156   return -1; | 
|  157 } |  157 } | 
|  158  |  158  | 
|  159 int File::ReadAtCurrentPos(char* data, int size) { |  159 int File::ReadAtCurrentPos(char* data, int size) { | 
|  160   base::ThreadRestrictions::AssertIOAllowed(); |  160   base::ThreadRestrictions::AssertIOAllowed(); | 
|  161   DCHECK(IsValid()); |  161   DCHECK(IsValid()); | 
|  162   DCHECK(!async_); |  162   DCHECK(!async_); | 
|  163   if (size < 0) |  163   if (size < 0) | 
|  164     return -1; |  164     return -1; | 
|  165  |  165  | 
|  166   DWORD bytes_read; |  166   DWORD bytes_read; | 
|  167   if (::ReadFile(file_, data, size, &bytes_read, NULL)) |  167   if (::ReadFile(file_.Get(), data, size, &bytes_read, NULL)) | 
|  168     return bytes_read; |  168     return bytes_read; | 
|  169   if (ERROR_HANDLE_EOF == GetLastError()) |  169   if (ERROR_HANDLE_EOF == GetLastError()) | 
|  170     return 0; |  170     return 0; | 
|  171  |  171  | 
|  172   return -1; |  172   return -1; | 
|  173 } |  173 } | 
|  174  |  174  | 
|  175 int File::ReadNoBestEffort(int64 offset, char* data, int size) { |  175 int File::ReadNoBestEffort(int64 offset, char* data, int size) { | 
|  176   return Read(offset, data, size); |  176   return Read(offset, data, size); | 
|  177 } |  177 } | 
|  178  |  178  | 
|  179 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { |  179 int File::ReadAtCurrentPosNoBestEffort(char* data, int size) { | 
|  180   return ReadAtCurrentPos(data, size); |  180   return ReadAtCurrentPos(data, size); | 
|  181 } |  181 } | 
|  182  |  182  | 
|  183 int File::Write(int64 offset, const char* data, int size) { |  183 int File::Write(int64 offset, const char* data, int size) { | 
|  184   base::ThreadRestrictions::AssertIOAllowed(); |  184   base::ThreadRestrictions::AssertIOAllowed(); | 
|  185   DCHECK(IsValid()); |  185   DCHECK(IsValid()); | 
|  186   DCHECK(!async_); |  186   DCHECK(!async_); | 
|  187  |  187  | 
|  188   LARGE_INTEGER offset_li; |  188   LARGE_INTEGER offset_li; | 
|  189   offset_li.QuadPart = offset; |  189   offset_li.QuadPart = offset; | 
|  190  |  190  | 
|  191   OVERLAPPED overlapped = {0}; |  191   OVERLAPPED overlapped = {0}; | 
|  192   overlapped.Offset = offset_li.LowPart; |  192   overlapped.Offset = offset_li.LowPart; | 
|  193   overlapped.OffsetHigh = offset_li.HighPart; |  193   overlapped.OffsetHigh = offset_li.HighPart; | 
|  194  |  194  | 
|  195   DWORD bytes_written; |  195   DWORD bytes_written; | 
|  196   if (::WriteFile(file_, data, size, &bytes_written, &overlapped)) |  196   if (::WriteFile(file_.Get(), data, size, &bytes_written, &overlapped)) | 
|  197     return bytes_written; |  197     return bytes_written; | 
|  198  |  198  | 
|  199   return -1; |  199   return -1; | 
|  200 } |  200 } | 
|  201  |  201  | 
|  202 int File::WriteAtCurrentPos(const char* data, int size) { |  202 int File::WriteAtCurrentPos(const char* data, int size) { | 
|  203   base::ThreadRestrictions::AssertIOAllowed(); |  203   base::ThreadRestrictions::AssertIOAllowed(); | 
|  204   DCHECK(IsValid()); |  204   DCHECK(IsValid()); | 
|  205   DCHECK(!async_); |  205   DCHECK(!async_); | 
|  206   if (size < 0) |  206   if (size < 0) | 
|  207     return -1; |  207     return -1; | 
|  208  |  208  | 
|  209   DWORD bytes_written; |  209   DWORD bytes_written; | 
|  210   if (::WriteFile(file_, data, size, &bytes_written, NULL)) |  210   if (::WriteFile(file_.Get(), data, size, &bytes_written, NULL)) | 
|  211     return bytes_written; |  211     return bytes_written; | 
|  212  |  212  | 
|  213   return -1; |  213   return -1; | 
|  214 } |  214 } | 
|  215  |  215  | 
|  216 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { |  216 int File::WriteAtCurrentPosNoBestEffort(const char* data, int size) { | 
|  217   return WriteAtCurrentPos(data, size); |  217   return WriteAtCurrentPos(data, size); | 
|  218 } |  218 } | 
|  219  |  219  | 
|  220 int64 File::GetLength() { |  220 int64 File::GetLength() { | 
|  221   base::ThreadRestrictions::AssertIOAllowed(); |  221   base::ThreadRestrictions::AssertIOAllowed(); | 
|  222   DCHECK(IsValid()); |  222   DCHECK(IsValid()); | 
|  223   LARGE_INTEGER size; |  223   LARGE_INTEGER size; | 
|  224   if (!::GetFileSizeEx(file_.Get(), &size)) |  224   if (!::GetFileSizeEx(file_.Get(), &size)) | 
|  225     return -1; |  225     return -1; | 
|  226  |  226  | 
|  227   return static_cast<int64>(size.QuadPart); |  227   return static_cast<int64>(size.QuadPart); | 
|  228 } |  228 } | 
|  229  |  229  | 
|  230 bool File::SetLength(int64 length) { |  230 bool File::SetLength(int64 length) { | 
|  231   base::ThreadRestrictions::AssertIOAllowed(); |  231   base::ThreadRestrictions::AssertIOAllowed(); | 
|  232   DCHECK(IsValid()); |  232   DCHECK(IsValid()); | 
|  233  |  233  | 
|  234   // Get the current file pointer. |  234   // Get the current file pointer. | 
|  235   LARGE_INTEGER file_pointer; |  235   LARGE_INTEGER file_pointer; | 
|  236   LARGE_INTEGER zero; |  236   LARGE_INTEGER zero; | 
|  237   zero.QuadPart = 0; |  237   zero.QuadPart = 0; | 
|  238   if (!::SetFilePointerEx(file_, zero, &file_pointer, FILE_CURRENT)) |  238   if (!::SetFilePointerEx(file_.Get(), zero, &file_pointer, FILE_CURRENT)) | 
|  239     return false; |  239     return false; | 
|  240  |  240  | 
|  241   LARGE_INTEGER length_li; |  241   LARGE_INTEGER length_li; | 
|  242   length_li.QuadPart = length; |  242   length_li.QuadPart = length; | 
|  243   // If length > file size, SetFilePointerEx() should extend the file |  243   // If length > file size, SetFilePointerEx() should extend the file | 
|  244   // with zeroes on all Windows standard file systems (NTFS, FATxx). |  244   // with zeroes on all Windows standard file systems (NTFS, FATxx). | 
|  245   if (!::SetFilePointerEx(file_, length_li, NULL, FILE_BEGIN)) |  245   if (!::SetFilePointerEx(file_.Get(), length_li, NULL, FILE_BEGIN)) | 
|  246     return false; |  246     return false; | 
|  247  |  247  | 
|  248   // Set the new file length and move the file pointer to its old position. |  248   // Set the new file length and move the file pointer to its old position. | 
|  249   // This is consistent with ftruncate()'s behavior, even when the file |  249   // This is consistent with ftruncate()'s behavior, even when the file | 
|  250   // pointer points to a location beyond the end of the file. |  250   // pointer points to a location beyond the end of the file. | 
|  251   // TODO(rvargas): Emulating ftruncate details seem suspicious and it is not |  251   // TODO(rvargas): Emulating ftruncate details seem suspicious and it is not | 
|  252   // promised by the interface (nor was promised by PlatformFile). See if this |  252   // promised by the interface (nor was promised by PlatformFile). See if this | 
|  253   // implementation detail can be removed. |  253   // implementation detail can be removed. | 
|  254   return ((::SetEndOfFile(file_) != FALSE) && |  254   return ((::SetEndOfFile(file_.Get()) != FALSE) && | 
|  255           (::SetFilePointerEx(file_, file_pointer, NULL, FILE_BEGIN) != FALSE)); |  255           (::SetFilePointerEx(file_.Get(), file_pointer, NULL, FILE_BEGIN) != | 
 |  256            FALSE)); | 
|  256 } |  257 } | 
|  257  |  258  | 
|  258 bool File::Flush() { |  259 bool File::Flush() { | 
|  259   base::ThreadRestrictions::AssertIOAllowed(); |  260   base::ThreadRestrictions::AssertIOAllowed(); | 
|  260   DCHECK(IsValid()); |  261   DCHECK(IsValid()); | 
|  261   return ::FlushFileBuffers(file_) != FALSE; |  262   return ::FlushFileBuffers(file_.Get()) != FALSE; | 
|  262 } |  263 } | 
|  263  |  264  | 
|  264 bool File::SetTimes(Time last_access_time, Time last_modified_time) { |  265 bool File::SetTimes(Time last_access_time, Time last_modified_time) { | 
|  265   base::ThreadRestrictions::AssertIOAllowed(); |  266   base::ThreadRestrictions::AssertIOAllowed(); | 
|  266   DCHECK(IsValid()); |  267   DCHECK(IsValid()); | 
|  267  |  268  | 
|  268   FILETIME last_access_filetime = last_access_time.ToFileTime(); |  269   FILETIME last_access_filetime = last_access_time.ToFileTime(); | 
|  269   FILETIME last_modified_filetime = last_modified_time.ToFileTime(); |  270   FILETIME last_modified_filetime = last_modified_time.ToFileTime(); | 
|  270   return (::SetFileTime(file_, NULL, &last_access_filetime, |  271   return (::SetFileTime(file_.Get(), NULL, &last_access_filetime, | 
|  271                         &last_modified_filetime) != FALSE); |  272                         &last_modified_filetime) != FALSE); | 
|  272 } |  273 } | 
|  273  |  274  | 
|  274 bool File::GetInfo(Info* info) { |  275 bool File::GetInfo(Info* info) { | 
|  275   base::ThreadRestrictions::AssertIOAllowed(); |  276   base::ThreadRestrictions::AssertIOAllowed(); | 
|  276   DCHECK(IsValid()); |  277   DCHECK(IsValid()); | 
|  277  |  278  | 
|  278   BY_HANDLE_FILE_INFORMATION file_info; |  279   BY_HANDLE_FILE_INFORMATION file_info; | 
|  279   if (!GetFileInformationByHandle(file_, &file_info)) |  280   if (!GetFileInformationByHandle(file_.Get(), &file_info)) | 
|  280     return false; |  281     return false; | 
|  281  |  282  | 
|  282   LARGE_INTEGER size; |  283   LARGE_INTEGER size; | 
|  283   size.HighPart = file_info.nFileSizeHigh; |  284   size.HighPart = file_info.nFileSizeHigh; | 
|  284   size.LowPart = file_info.nFileSizeLow; |  285   size.LowPart = file_info.nFileSizeLow; | 
|  285   info->size = size.QuadPart; |  286   info->size = size.QuadPart; | 
|  286   info->is_directory = |  287   info->is_directory = | 
|  287       (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; |  288       (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; | 
|  288   info->is_symbolic_link = false;  // Windows doesn't have symbolic links. |  289   info->is_symbolic_link = false;  // Windows doesn't have symbolic links. | 
|  289   info->last_modified = base::Time::FromFileTime(file_info.ftLastWriteTime); |  290   info->last_modified = base::Time::FromFileTime(file_info.ftLastWriteTime); | 
|  290   info->last_accessed = base::Time::FromFileTime(file_info.ftLastAccessTime); |  291   info->last_accessed = base::Time::FromFileTime(file_info.ftLastAccessTime); | 
|  291   info->creation_time = base::Time::FromFileTime(file_info.ftCreationTime); |  292   info->creation_time = base::Time::FromFileTime(file_info.ftCreationTime); | 
|  292   return true; |  293   return true; | 
|  293 } |  294 } | 
|  294  |  295  | 
|  295 File::Error base::File::Lock() { |  296 File::Error base::File::Lock() { | 
|  296   DCHECK(IsValid()); |  297   DCHECK(IsValid()); | 
|  297   BOOL result = LockFile(file_, 0, 0, MAXDWORD, MAXDWORD); |  298   BOOL result = LockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD); | 
|  298   if (!result) |  299   if (!result) | 
|  299     return OSErrorToFileError(GetLastError()); |  300     return OSErrorToFileError(GetLastError()); | 
|  300   return FILE_OK; |  301   return FILE_OK; | 
|  301 } |  302 } | 
|  302  |  303  | 
|  303 File::Error File::Unlock() { |  304 File::Error File::Unlock() { | 
|  304   DCHECK(IsValid()); |  305   DCHECK(IsValid()); | 
|  305   BOOL result = UnlockFile(file_, 0, 0, MAXDWORD, MAXDWORD); |  306   BOOL result = UnlockFile(file_.Get(), 0, 0, MAXDWORD, MAXDWORD); | 
|  306   if (!result) |  307   if (!result) | 
|  307     return OSErrorToFileError(GetLastError()); |  308     return OSErrorToFileError(GetLastError()); | 
|  308   return FILE_OK; |  309   return FILE_OK; | 
|  309 } |  310 } | 
|  310  |  311  | 
|  311 // Static. |  312 // Static. | 
|  312 File::Error File::OSErrorToFileError(DWORD last_error) { |  313 File::Error File::OSErrorToFileError(DWORD last_error) { | 
|  313   switch (last_error) { |  314   switch (last_error) { | 
|  314     case ERROR_SHARING_VIOLATION: |  315     case ERROR_SHARING_VIOLATION: | 
|  315       return FILE_ERROR_IN_USE; |  316       return FILE_ERROR_IN_USE; | 
| (...skipping 27 matching lines...) Expand all  Loading... | 
|  343                                   last_error); |  344                                   last_error); | 
|  344       return FILE_ERROR_FAILED; |  345       return FILE_ERROR_FAILED; | 
|  345   } |  346   } | 
|  346 } |  347 } | 
|  347  |  348  | 
|  348 void File::SetPlatformFile(PlatformFile file) { |  349 void File::SetPlatformFile(PlatformFile file) { | 
|  349   file_.Set(file); |  350   file_.Set(file); | 
|  350 } |  351 } | 
|  351  |  352  | 
|  352 }  // namespace base |  353 }  // namespace base | 
| OLD | NEW |