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 "storage/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 "storage/common/fileapi/file_system_types.h" 13 #include "storage/common/fileapi/file_system_util.h" 14 15 namespace storage { 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::CreateForTest( 40 const GURL& origin, 41 FileSystemType mount_type, 42 const base::FilePath& virtual_path, 43 const std::string& mount_filesystem_id, 44 FileSystemType cracked_type, 45 const base::FilePath& cracked_path, 46 const std::string& filesystem_id, 47 const FileSystemMountOption& mount_option) { 48 return FileSystemURL(origin, 49 mount_type, 50 virtual_path, 51 mount_filesystem_id, 52 cracked_type, 53 cracked_path, 54 filesystem_id, 55 mount_option); 56 } 57 58 FileSystemURL::FileSystemURL(const GURL& url) 59 : mount_type_(kFileSystemTypeUnknown), 60 type_(kFileSystemTypeUnknown), 61 mount_option_(COPY_SYNC_OPTION_NO_SYNC) { 62 is_valid_ = ParseFileSystemSchemeURL(url, &origin_, &mount_type_, 63 &virtual_path_); 64 path_ = virtual_path_; 65 type_ = mount_type_; 66 } 67 68 FileSystemURL::FileSystemURL(const GURL& origin, 69 FileSystemType mount_type, 70 const base::FilePath& virtual_path) 71 : is_valid_(true), 72 origin_(origin), 73 mount_type_(mount_type), 74 virtual_path_(virtual_path.NormalizePathSeparators()), 75 type_(mount_type), 76 path_(virtual_path.NormalizePathSeparators()), 77 mount_option_(COPY_SYNC_OPTION_NO_SYNC) { 78 } 79 80 FileSystemURL::FileSystemURL(const GURL& origin, 81 FileSystemType mount_type, 82 const base::FilePath& virtual_path, 83 const std::string& mount_filesystem_id, 84 FileSystemType cracked_type, 85 const base::FilePath& cracked_path, 86 const std::string& filesystem_id, 87 const FileSystemMountOption& mount_option) 88 : is_valid_(true), 89 origin_(origin), 90 mount_type_(mount_type), 91 virtual_path_(virtual_path.NormalizePathSeparators()), 92 mount_filesystem_id_(mount_filesystem_id), 93 type_(cracked_type), 94 path_(cracked_path.NormalizePathSeparators()), 95 filesystem_id_(filesystem_id), 96 mount_option_(mount_option) { 97 } 98 99 FileSystemURL::~FileSystemURL() {} 100 101 GURL FileSystemURL::ToGURL() const { 102 if (!is_valid_) 103 return GURL(); 104 105 std::string url = GetFileSystemRootURI(origin_, mount_type_).spec(); 106 if (url.empty()) 107 return GURL(); 108 109 // Exactly match with DOMFileSystemBase::createFileSystemURL()'s encoding 110 // behavior, where the path is escaped by KURL::encodeWithURLEscapeSequences 111 // which is essentially encodeURIComponent except '/'. 112 std::string escaped = net::EscapeQueryParamValue( 113 virtual_path_.NormalizePathSeparatorsTo('/').AsUTF8Unsafe(), 114 false /* use_plus */); 115 ReplaceSubstringsAfterOffset(&escaped, 0, "%2F", "/"); 116 url.append(escaped); 117 118 // Build nested GURL. 119 return GURL(url); 120 } 121 122 std::string FileSystemURL::DebugString() const { 123 if (!is_valid_) 124 return "invalid filesystem: URL"; 125 std::ostringstream ss; 126 ss << GetFileSystemRootURI(origin_, mount_type_); 127 128 // filesystem_id_ will be non empty for (and only for) cracked URLs. 129 if (!filesystem_id_.empty()) { 130 ss << virtual_path_.value(); 131 ss << " ("; 132 ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":"; 133 ss << path_.value(); 134 ss << ")"; 135 } else { 136 ss << path_.value(); 137 } 138 return ss.str(); 139 } 140 141 bool FileSystemURL::IsParent(const FileSystemURL& child) const { 142 return IsInSameFileSystem(child) && 143 path().IsParent(child.path()); 144 } 145 146 bool FileSystemURL::IsInSameFileSystem(const FileSystemURL& other) const { 147 return origin() == other.origin() && 148 type() == other.type() && 149 filesystem_id() == other.filesystem_id(); 150 } 151 152 bool FileSystemURL::operator==(const FileSystemURL& that) const { 153 return origin_ == that.origin_ && 154 type_ == that.type_ && 155 path_ == that.path_ && 156 filesystem_id_ == that.filesystem_id_ && 157 is_valid_ == that.is_valid_; 158 } 159 160 bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs, 161 const FileSystemURL& rhs) const { 162 DCHECK(lhs.is_valid_ && rhs.is_valid_); 163 if (lhs.origin_ != rhs.origin_) 164 return lhs.origin_ < rhs.origin_; 165 if (lhs.type_ != rhs.type_) 166 return lhs.type_ < rhs.type_; 167 if (lhs.filesystem_id_ != rhs.filesystem_id_) 168 return lhs.filesystem_id_ < rhs.filesystem_id_; 169 return lhs.path_ < rhs.path_; 170 } 171 172 } // namespace storage 173