Chromium Code Reviews| Index: webkit/fileapi/file_system_directory_database.cc |
| diff --git a/webkit/fileapi/file_system_directory_database.cc b/webkit/fileapi/file_system_directory_database.cc |
| index 217b98ffbff74be110ffd358b3425f8b5ed586b2..7f015dc7f6b2e3999c5cb51295643ee4ca5bb547 100644 |
| --- a/webkit/fileapi/file_system_directory_database.cc |
| +++ b/webkit/fileapi/file_system_directory_database.cc |
| @@ -6,17 +6,47 @@ |
| #include <math.h> |
| +#include "base/file_util.h" |
| #include "base/location.h" |
| #include "base/pickle.h" |
| #include "base/string_number_conversions.h" |
| #include "base/string_util.h" |
| -#include "base/sys_string_conversions.h" |
| +#include "base/utf_string_conversions.h" |
| #include "third_party/leveldatabase/src/include/leveldb/iterator.h" |
| +#include "third_party/leveldatabase/src/include/leveldb/status.h" |
| #include "third_party/leveldatabase/src/include/leveldb/write_batch.h" |
| #include "webkit/fileapi/file_system_util.h" |
| namespace { |
| +std::string FilePathStringToString(const FilePath::StringType& path) { |
|
kinuko
2012/03/26 05:25:09
Hmm. Could we move this into file_system_util.h o
tzik
2012/03/26 08:04:56
Done.
|
| + // TODO(tzik): Unify this to FilePathToString in |
| + // third_party/leveldatabase/env_chromium.cc. |
| +#if defined(OS_WIN) |
| + return UTF16ToUTF8(path); |
| +#elif defined(OS_POSIX) |
| + return path; |
| +#endif |
| +} |
| + |
| +std::string FilePathToString(const FilePath& path) { |
| + return FilePathStringToString(path.value()); |
| +} |
| + |
| +FilePath::StringType StringToFilePathString(const std::string& path_string) { |
| + // TODO(tzik): Unify this to CreateFilePath in |
| + // third_party/leveldatabase/env_chromium.cc. |
| +#if defined(OS_WIN) |
| + return UTF8ToUTF16(path_string); |
| +#elif defined(OS_POSIX) |
| + return path_string; |
| +#endif |
| +} |
| + |
| +FilePath StringToFilePath(const std::string& path_string) { |
| + return FilePath(StringToFilePathString(path_string)); |
| +} |
| + |
| bool PickleFromFileInfo( |
| const fileapi::FileSystemDirectoryDatabase::FileInfo& info, |
| Pickle* pickle) { |
| @@ -27,13 +57,9 @@ bool PickleFromFileInfo( |
| base::Time::FromDoubleT(floor(info.modification_time.ToDoubleT())); |
| std::string name; |
| -#if defined(OS_POSIX) |
| - data_path = info.data_path.value(); |
| - name = info.name; |
| -#elif defined(OS_WIN) |
| - data_path = base::SysWideToUTF8(info.data_path.value()); |
| - name = base::SysWideToUTF8(info.name); |
| -#endif |
| + data_path = FilePathToString(info.data_path); |
| + name = FilePathStringToString(info.name); |
| + |
| if (pickle->WriteInt64(info.parent_id) && |
| pickle->WriteString(data_path) && |
| pickle->WriteString(name) && |
| @@ -56,13 +82,9 @@ bool FileInfoFromPickle( |
| pickle.ReadString(&iter, &data_path) && |
| pickle.ReadString(&iter, &name) && |
| pickle.ReadInt64(&iter, &internal_time)) { |
| -#if defined(OS_POSIX) |
| - info->data_path = FilePath(data_path); |
| - info->name = name; |
| -#elif defined(OS_WIN) |
| - info->data_path = FilePath(base::SysUTF8ToWide(data_path)); |
| - info->name = base::SysUTF8ToWide(name); |
| -#endif |
| + |
| + info->data_path = FilePath(StringToFilePath(data_path)); |
| + info->name = StringToFilePathString(name); |
| info->modification_time = base::Time::FromInternalValue(internal_time); |
| return true; |
| } |
| @@ -70,6 +92,7 @@ bool FileInfoFromPickle( |
| return false; |
| } |
| +const FilePath::CharType kDirectoryDatabaseName[] = FILE_PATH_LITERAL("Paths"); |
| const char kChildLookupPrefix[] = "CHILD_OF:"; |
| const char kChildLookupSeparator[] = ":"; |
| const char kLastFileIdKey[] = "LAST_FILE_ID"; |
| @@ -79,11 +102,7 @@ std::string GetChildLookupKey( |
| fileapi::FileSystemDirectoryDatabase::FileId parent_id, |
| const FilePath::StringType& child_name) { |
| std::string name; |
| -#if defined(OS_POSIX) |
| - name = child_name; |
| -#elif defined(OS_WIN) |
| - name = base::SysWideToUTF8(child_name); |
| -#endif |
| + name = FilePathStringToString(child_name); |
| return std::string(kChildLookupPrefix) + base::Int64ToString(parent_id) + |
| std::string(kChildLookupSeparator) + name; |
| } |
| @@ -117,12 +136,9 @@ FileSystemDirectoryDatabase::FileInfo::FileInfo() : parent_id(0) { |
| FileSystemDirectoryDatabase::FileInfo::~FileInfo() { |
| } |
| -FileSystemDirectoryDatabase::FileSystemDirectoryDatabase(const FilePath& path) { |
| -#if defined(OS_POSIX) |
| - path_ = path.value(); |
| -#elif defined(OS_WIN) |
| - path_ = base::SysWideToUTF8(path.value()); |
| -#endif |
| +FileSystemDirectoryDatabase::FileSystemDirectoryDatabase( |
| + const FilePath& sandbox_directory) |
| + : sandbox_directory_(sandbox_directory) { |
| } |
| FileSystemDirectoryDatabase::~FileSystemDirectoryDatabase() { |
| @@ -130,7 +146,7 @@ FileSystemDirectoryDatabase::~FileSystemDirectoryDatabase() { |
| bool FileSystemDirectoryDatabase::GetChildWithName( |
| FileId parent_id, const FilePath::StringType& name, FileId* child_id) { |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| DCHECK(child_id); |
| std::string child_key = GetChildLookupKey(parent_id, name); |
| @@ -171,7 +187,7 @@ bool FileSystemDirectoryDatabase::GetFileWithPath( |
| bool FileSystemDirectoryDatabase::ListChildren( |
| FileId parent_id, std::vector<FileId>* children) { |
| // Check to add later: fail if parent is a file, at least in debug builds. |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| DCHECK(children); |
| std::string child_key_prefix = GetChildListingKeyPrefix(parent_id); |
| @@ -194,7 +210,7 @@ bool FileSystemDirectoryDatabase::ListChildren( |
| } |
| bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) { |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| DCHECK(info); |
| std::string file_key = GetFileLookupKey(file_id); |
| @@ -221,7 +237,7 @@ bool FileSystemDirectoryDatabase::GetFileInfo(FileId file_id, FileInfo* info) { |
| bool FileSystemDirectoryDatabase::AddFileInfo( |
| const FileInfo& info, FileId* file_id) { |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| DCHECK(file_id); |
| std::string child_key = GetChildLookupKey(info.parent_id, info.name); |
| @@ -263,7 +279,7 @@ bool FileSystemDirectoryDatabase::AddFileInfo( |
| } |
| bool FileSystemDirectoryDatabase::RemoveFileInfo(FileId file_id) { |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| leveldb::WriteBatch batch; |
| if (!RemoveFileInfoHelper(file_id, &batch)) |
| @@ -280,7 +296,7 @@ bool FileSystemDirectoryDatabase::UpdateFileInfo( |
| FileId file_id, const FileInfo& new_info) { |
| // TODO: We should also check to see that this doesn't create a loop, but |
| // perhaps only in a debug build. |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| DCHECK(file_id); // You can't remove the root, ever. Just delete the DB. |
| FileInfo old_info; |
| @@ -364,7 +380,7 @@ bool FileSystemDirectoryDatabase::OverwritingMoveFile( |
| } |
| bool FileSystemDirectoryDatabase::GetNextInteger(int64* next) { |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| DCHECK(next); |
| std::string int_string; |
| @@ -399,12 +415,7 @@ bool FileSystemDirectoryDatabase::GetNextInteger(int64* next) { |
| // static |
| bool FileSystemDirectoryDatabase::DestroyDatabase(const FilePath& path) { |
| - std::string name; |
| -#if defined(OS_POSIX) |
| - name = path.value(); |
| -#elif defined(OS_WIN) |
| - name = base::SysWideToUTF8(path.value()); |
| -#endif |
| + std::string name = FilePathToString(path.Append(kDirectoryDatabaseName)); |
| leveldb::Status status = leveldb::DestroyDB(name, leveldb::Options()); |
| if (status.ok()) |
| return true; |
| @@ -413,20 +424,32 @@ bool FileSystemDirectoryDatabase::DestroyDatabase(const FilePath& path) { |
| return false; |
| } |
| -bool FileSystemDirectoryDatabase::Init() { |
| - if (db_.get()) |
| - return true; |
| +bool FileSystemDirectoryDatabase::Init(RecoveryOption recovery_option) { |
| + if (db_.get()) |
| + return true; |
| + |
| + std::string path = |
| + FilePathToString(sandbox_directory_.Append(kDirectoryDatabaseName)); |
| + leveldb::Options options; |
| + options.create_if_missing = true; |
| + leveldb::DB* db; |
| + leveldb::Status status = leveldb::DB::Open(options, path, &db); |
| + // TODO(tzik): Collect status metrics here. |
| + if (status.ok()) { |
| + db_.reset(db); |
| + return true; |
| + } |
| + HandleError(FROM_HERE, status); |
| + |
| + if (recovery_option == FAIL_ON_CORRUPTION) |
| + return false; |
| - leveldb::Options options; |
| - options.create_if_missing = true; |
| - leveldb::DB* db; |
| - leveldb::Status status = leveldb::DB::Open(options, path_, &db); |
| - if (status.ok()) { |
| - db_.reset(db); |
| - return true; |
| - } |
| - HandleError(FROM_HERE, status); |
| - return false; |
| + DCHECK_EQ(DELETE_ON_CORRUPTION, recovery_option); |
| + if (!file_util::Delete(sandbox_directory_, true)) |
| + return false; |
| + if (!file_util::CreateDirectory(sandbox_directory_)) |
| + return false; |
| + return Init(FAIL_ON_CORRUPTION); |
| } |
| bool FileSystemDirectoryDatabase::StoreDefaultValues() { |
| @@ -456,7 +479,7 @@ bool FileSystemDirectoryDatabase::StoreDefaultValues() { |
| } |
| bool FileSystemDirectoryDatabase::GetLastFileId(FileId* file_id) { |
| - if (!Init()) |
| + if (!Init(FAIL_ON_CORRUPTION)) |
| return false; |
| DCHECK(file_id); |
| std::string id_string; |