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 3 // found in the LICENSE file. 4 5 #include "webkit/browser/fileapi/file_system_url.h" 6 7 #include <sstream> 8 9 #include "base/logging.h" 10 #include "base/strings/string_util.h" 11 #include "net/base/escape.h" 12 #include "webkit/common/fileapi/file_system_types.h" 13 #include "webkit/common/fileapi/file_system_util.h" 14 15 namespace fileapi { 16 17 namespace { 18 19 } // namespace 20 21 FileSystemURL::FileSystemURL() 22 : is_valid_(false), 23 mount_type_(kFileSystemTypeUnknown), 24 type_(kFileSystemTypeUnknown), 25 mount_option_(COPY_SYNC_OPTION_NO_SYNC) { 26 } 27 28 // static 29 FileSystemURL FileSystemURL::CreateForTest(const GURL& url) { 30 return FileSystemURL(url); 31 } 32 33 FileSystemURL FileSystemURL::CreateForTest(const GURL& origin, 34 FileSystemType mount_type, 35 const base::FilePath& virtual_path) { 36 return FileSystemURL(origin, mount_type, virtual_path); 37 } 38 39 FileSystemURL::FileSystemURL(const GURL& url) 40 : mount_type_(kFileSystemTypeUnknown), 41 type_(kFileSystemTypeUnknown), 42 mount_option_(COPY_SYNC_OPTION_NO_SYNC) { 43 is_valid_ = ParseFileSystemSchemeURL(url, &origin_, &mount_type_, 44 &virtual_path_); 45 path_ = virtual_path_; 46 type_ = mount_type_; 47 } 48 49 FileSystemURL::FileSystemURL(const GURL& origin, 50 FileSystemType mount_type, 51 const base::FilePath& virtual_path) 52 : is_valid_(true), 53 origin_(origin), 54 mount_type_(mount_type), 55 virtual_path_(virtual_path.NormalizePathSeparators()), 56 type_(mount_type), 57 path_(virtual_path.NormalizePathSeparators()), 58 mount_option_(COPY_SYNC_OPTION_NO_SYNC) { 59 } 60 61 FileSystemURL::FileSystemURL(const GURL& origin, 62 FileSystemType mount_type, 63 const base::FilePath& virtual_path, 64 const std::string& mount_filesystem_id, 65 FileSystemType cracked_type, 66 const base::FilePath& cracked_path, 67 const std::string& filesystem_id, 68 const FileSystemMountOption& mount_option) 69 : is_valid_(true), 70 origin_(origin), 71 mount_type_(mount_type), 72 virtual_path_(virtual_path.NormalizePathSeparators()), 73 mount_filesystem_id_(mount_filesystem_id), 74 type_(cracked_type), 75 path_(cracked_path.NormalizePathSeparators()), 76 filesystem_id_(filesystem_id), 77 mount_option_(mount_option) { 78 } 79 80 FileSystemURL::~FileSystemURL() {} 81 82 GURL FileSystemURL::ToGURL() const { 83 if (!is_valid_) 84 return GURL(); 85 86 std::string url = GetFileSystemRootURI(origin_, mount_type_).spec(); 87 if (url.empty()) 88 return GURL(); 89 90 // Exactly match with DOMFileSystemBase::createFileSystemURL()'s encoding 91 // behavior, where the path is escaped by KURL::encodeWithURLEscapeSequences 92 // which is essentially encodeURIComponent except '/'. 93 std::string escaped = net::EscapeQueryParamValue( 94 virtual_path_.NormalizePathSeparatorsTo('/').AsUTF8Unsafe(), 95 false /* use_plus */); 96 ReplaceSubstringsAfterOffset(&escaped, 0, "%2F", "/"); 97 url.append(escaped); 98 99 // Build nested GURL. 100 return GURL(url); 101 } 102 103 std::string FileSystemURL::DebugString() const { 104 if (!is_valid_) 105 return "invalid filesystem: URL"; 106 std::ostringstream ss; 107 ss << GetFileSystemRootURI(origin_, mount_type_); 108 109 // filesystem_id_ will be non empty for (and only for) cracked URLs. 110 if (!filesystem_id_.empty()) { 111 ss << virtual_path_.value(); 112 ss << " ("; 113 ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":"; 114 ss << path_.value(); 115 ss << ")"; 116 } else { 117 ss << path_.value(); 118 } 119 return ss.str(); 120 } 121 122 bool FileSystemURL::IsParent(const FileSystemURL& child) const { 123 return IsInSameFileSystem(child) && 124 path().IsParent(child.path()); 125 } 126 127 bool FileSystemURL::IsInSameFileSystem(const FileSystemURL& other) const { 128 return origin() == other.origin() && 129 type() == other.type() && 130 filesystem_id() == other.filesystem_id(); 131 } 132 133 bool FileSystemURL::operator==(const FileSystemURL& that) const { 134 return origin_ == that.origin_ && 135 type_ == that.type_ && 136 path_ == that.path_ && 137 filesystem_id_ == that.filesystem_id_ && 138 is_valid_ == that.is_valid_; 139 } 140 141 bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs, 142 const FileSystemURL& rhs) const { 143 DCHECK(lhs.is_valid_ && rhs.is_valid_); 144 if (lhs.origin_ != rhs.origin_) 145 return lhs.origin_ < rhs.origin_; 146 if (lhs.type_ != rhs.type_) 147 return lhs.type_ < rhs.type_; 148 if (lhs.filesystem_id_ != rhs.filesystem_id_) 149 return lhs.filesystem_id_ < rhs.filesystem_id_; 150 return lhs.path_ < rhs.path_; 151 } 152 153 } // namespace fileapi 154