1b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// Use of this source code is governed by a BSD-style license that can be 3b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat// found in the LICENSE file. 4b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 5b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/files/file.h" 6b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/files/file_path.h" 7b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/files/file_tracing.h" 8b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/metrics/histogram.h" 9b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#include "base/timer/elapsed_timer.h" 10cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko#include "build/build_config.h" 11b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 12b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratnamespace base { 13b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 14b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratFile::Info::Info() 15b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : size(0), 16b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat is_directory(false), 17b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat is_symbolic_link(false) { 18b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 19b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 20b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratFile::Info::~Info() { 21b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 22b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 23b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratFile::File() 24b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : error_details_(FILE_ERROR_FAILED), 25b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat created_(false), 26b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat async_(false) { 27b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 28b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 29b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if !defined(OS_NACL) 30cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoFile::File(const FilePath& path, uint32_t flags) 31cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko : error_details_(FILE_OK), created_(false), async_(false) { 32b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Initialize(path, flags); 33b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 34b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 35b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 36b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratFile::File(PlatformFile platform_file) 37b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : file_(platform_file), 38b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat error_details_(FILE_OK), 39b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat created_(false), 40b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat async_(false) { 41b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if defined(OS_POSIX) 42b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat DCHECK_GE(platform_file, -1); 43b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 44b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 45b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 46b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratFile::File(Error error_details) 47b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat : error_details_(error_details), 48b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat created_(false), 49b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat async_(false) { 50b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 51b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 52cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoFile::File(File&& other) 53cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko : file_(other.TakePlatformFile()), 54cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko tracing_path_(other.tracing_path_), 55cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko error_details_(other.error_details()), 56cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko created_(other.created()), 57cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko async_(other.async_) {} 58b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 59b8cf94937c52feb53b55c39e3f82094d27de464cDaniel EratFile::~File() { 60b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat // Go through the AssertIOAllowed logic. 61b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat Close(); 62b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 63b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 64cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko// static 65cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoFile File::CreateForAsyncHandle(PlatformFile platform_file) { 66cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko File file(platform_file); 67cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // It would be nice if we could validate that |platform_file| was opened with 68cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko // FILE_FLAG_OVERLAPPED on Windows but this doesn't appear to be possible. 69cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko file.async_ = true; 70cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko return file; 71cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko} 72cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko 73cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex VakulenkoFile& File::operator=(File&& other) { 74cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko DCHECK_NE(this, &other); 75cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko Close(); 76cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko SetPlatformFile(other.TakePlatformFile()); 77cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko tracing_path_ = other.tracing_path_; 78cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko error_details_ = other.error_details(); 79cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko created_ = other.created(); 80cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko async_ = other.async_; 81b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return *this; 82b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 83b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 84b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#if !defined(OS_NACL) 85cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenkovoid File::Initialize(const FilePath& path, uint32_t flags) { 86b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat if (path.ReferencesParent()) { 87b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat error_details_ = FILE_ERROR_ACCESS_DENIED; 88b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return; 89b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 90cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko if (FileTracing::IsCategoryEnabled()) 91cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko tracing_path_ = path; 92b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat SCOPED_FILE_TRACE("Initialize"); 93cce46a0c214b37e8da48c522c83037e8ffa4f9fdAlex Vakulenko DoInitialize(path, flags); 94b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 95b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat#endif 96b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 97b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratstd::string File::ErrorToString(Error error) { 98b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat switch (error) { 99b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_OK: 100b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_OK"; 101b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_FAILED: 102b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_FAILED"; 103b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_IN_USE: 104b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_IN_USE"; 105b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_EXISTS: 106b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_EXISTS"; 107b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_NOT_FOUND: 108b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_NOT_FOUND"; 109b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_ACCESS_DENIED: 110b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_ACCESS_DENIED"; 111b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_TOO_MANY_OPENED: 112b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_TOO_MANY_OPENED"; 113b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_NO_MEMORY: 114b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_NO_MEMORY"; 115b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_NO_SPACE: 116b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_NO_SPACE"; 117b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_NOT_A_DIRECTORY: 118b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_NOT_A_DIRECTORY"; 119b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_INVALID_OPERATION: 120b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_INVALID_OPERATION"; 121b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_SECURITY: 122b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_SECURITY"; 123b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_ABORT: 124b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_ABORT"; 125b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_NOT_A_FILE: 126b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_NOT_A_FILE"; 127b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_NOT_EMPTY: 128b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_NOT_EMPTY"; 129b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_INVALID_URL: 130b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_INVALID_URL"; 131b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_IO: 132b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return "FILE_ERROR_IO"; 133b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat case FILE_ERROR_MAX: 134b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat break; 135b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat } 136b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 137b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat NOTREACHED(); 138b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return ""; 139b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 140b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 141b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Eratbool File::Flush() { 142b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat ElapsedTimer timer; 143b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat SCOPED_FILE_TRACE("Flush"); 144b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat bool return_value = DoFlush(); 145b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat UMA_HISTOGRAM_TIMES("PlatformFile.FlushTime", timer.Elapsed()); 146b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat return return_value; 147b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} 148b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat 149b8cf94937c52feb53b55c39e3f82094d27de464cDaniel Erat} // namespace base 150