Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / storage / browser / fileapi / obfuscated_file_util.cc
index 4e202eb..8f696c0 100644 (file)
@@ -15,6 +15,7 @@
 #include "base/metrics/histogram.h"
 #include "base/stl_util.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
@@ -67,6 +68,8 @@ void InitFileInfo(
 const int64 kPathCreationQuotaCost = 146;  // Bytes per inode, basically.
 const int64 kPathByteQuotaCost = 2;  // Bytes per byte of path length in UTF-8.
 
+const char kDirectoryDatabaseKeySeparator = ' ';
+
 int64 UsageForPath(size_t length) {
   return kPathCreationQuotaCost +
       static_cast<int64>(length) * kPathByteQuotaCost;
@@ -130,9 +133,9 @@ class ObfuscatedFileEnumerator
     recurse_queue_.push(record);
   }
 
-  virtual ~ObfuscatedFileEnumerator() {}
+  ~ObfuscatedFileEnumerator() override {}
 
-  virtual base::FilePath Next() OVERRIDE {
+  base::FilePath Next() override {
     ProcessRecurseQueue();
     if (display_stack_.empty())
       return base::FilePath();
@@ -158,15 +161,13 @@ class ObfuscatedFileEnumerator
     return virtual_path;
   }
 
-  virtual int64 Size() OVERRIDE {
-    return current_platform_file_info_.size;
-  }
+  int64 Size() override { return current_platform_file_info_.size; }
 
-  virtual base::Time LastModifiedTime() OVERRIDE {
+  base::Time LastModifiedTime() override {
     return current_platform_file_info_.last_modified;
   }
 
-  virtual bool IsDirectory() OVERRIDE {
+  bool IsDirectory() override {
     return current_platform_file_info_.is_directory;
   }
 
@@ -217,10 +218,10 @@ class ObfuscatedOriginEnumerator
       origin_database->ListAllOrigins(&origins_);
   }
 
-  virtual ~ObfuscatedOriginEnumerator() {}
+  ~ObfuscatedOriginEnumerator() override {}
 
   // Returns the next origin.  Returns empty if there are no more origins.
-  virtual GURL Next() OVERRIDE {
+  GURL Next() override {
     OriginRecord record;
     if (!origins_.empty()) {
       record = origins_.back();
@@ -231,7 +232,7 @@ class ObfuscatedOriginEnumerator
   }
 
   // Returns the current origin's information.
-  virtual bool HasTypeDirectory(const std::string& type_string) const OVERRIDE {
+  bool HasTypeDirectory(const std::string& type_string) const override {
     if (current_.path.empty())
       return false;
     if (type_string.empty()) {
@@ -857,28 +858,22 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType(
 bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
     const GURL& origin,
     const std::string& type_string) {
-  base::File::Error error = base::File::FILE_OK;
-  base::FilePath origin_type_path = GetDirectoryForOriginAndType(
-      origin, type_string, false, &error);
-  if (origin_type_path.empty())
-    return true;
-  if (error != base::File::FILE_ERROR_NOT_FOUND) {
-    // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase.
-    // We ignore its error now since 1) it doesn't matter the final result, and
-    // 2) it always returns false in Windows because of LevelDB's
-    // implementation.
-    // Information about failure would be useful for debugging.
-    if (!type_string.empty())
-      DestroyDirectoryDatabase(origin, type_string);
-    if (!base::DeleteFile(origin_type_path, true /* recursive */))
-      return false;
-  }
-
-  base::FilePath origin_path = VirtualPath::DirName(origin_type_path);
-  DCHECK_EQ(origin_path.value(),
-            GetDirectoryForOrigin(origin, false, NULL).value());
+  DestroyDirectoryDatabase(origin, type_string);
 
+  const base::FilePath origin_path = GetDirectoryForOrigin(origin, false, NULL);
   if (!type_string.empty()) {
+    // Delete the filesystem type directory.
+    base::File::Error error = base::File::FILE_OK;
+    const base::FilePath origin_type_path =
+        GetDirectoryForOriginAndType(origin, type_string, false, &error);
+    if (error == base::File::FILE_ERROR_FAILED)
+      return false;
+    if (error == base::File::FILE_OK &&
+        !origin_type_path.empty() &&
+        !base::DeleteFile(origin_type_path, true /* recursive */)) {
+      return false;
+    }
+
     // At this point we are sure we had successfully deleted the origin/type
     // directory (i.e. we're ready to just return true).
     // See if we have other directories in this origin directory.
@@ -900,10 +895,7 @@ bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
     origin_database_->RemovePathForOrigin(
         storage::GetIdentifierFromOrigin(origin));
   }
-  if (!base::DeleteFile(origin_path, true /* recursive */))
-    return false;
-
-  return true;
+  return base::DeleteFile(origin_path, true /* recursive */);
 }
 
 ObfuscatedFileUtil::AbstractOriginEnumerator*
@@ -915,18 +907,23 @@ ObfuscatedFileUtil::CreateOriginEnumerator() {
       origin_database_.get(), file_system_directory_);
 }
 
-bool ObfuscatedFileUtil::DestroyDirectoryDatabase(
+void ObfuscatedFileUtil::DestroyDirectoryDatabase(
     const GURL& origin,
     const std::string& type_string) {
-  std::string key = GetDirectoryDatabaseKey(origin, type_string);
-  if (key.empty())
-    return true;
-  DirectoryMap::iterator iter = directories_.find(key);
-  if (iter == directories_.end())
-    return true;
-  scoped_ptr<SandboxDirectoryDatabase> database(iter->second);
-  directories_.erase(iter);
-  return database->DestroyDatabase();
+  // If |type_string| is empty, delete all filesystem types under |origin|.
+  const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string);
+  for (DirectoryMap::iterator iter = directories_.lower_bound(key_prefix);
+       iter != directories_.end();) {
+    if (!StartsWithASCII(iter->first, key_prefix, true))
+      break;
+    DCHECK(type_string.empty() || iter->first == key_prefix);
+    scoped_ptr<SandboxDirectoryDatabase> database(iter->second);
+    directories_.erase(iter++);
+
+    // Continue to destroy databases even if it failed because it doesn't affect
+    // the final result.
+    database->DestroyDatabase();
+  }
 }
 
 // static
@@ -1138,12 +1135,9 @@ base::FilePath ObfuscatedFileUtil::DataPathToLocalPath(
 
 std::string ObfuscatedFileUtil::GetDirectoryDatabaseKey(
     const GURL& origin, const std::string& type_string) {
-  if (type_string.empty()) {
-    LOG(WARNING) << "Unknown filesystem type requested:" << type_string;
-    return std::string();
-  }
   // For isolated origin we just use a type string as a key.
-  return storage::GetIdentifierFromOrigin(origin) + type_string;
+  return storage::GetIdentifierFromOrigin(origin) +
+      kDirectoryDatabaseKeySeparator + type_string;
 }
 
 // TODO(ericu): How to do the whole validation-without-creation thing?