| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "storage/browser/fileapi/file_system_url.h" |
| |
| #include <sstream> |
| |
| #include "base/logging.h" |
| #include "base/strings/string_util.h" |
| #include "net/base/escape.h" |
| #include "storage/common/fileapi/file_system_util.h" |
| |
| namespace storage { |
| |
| namespace { |
| |
| } // namespace |
| |
| FileSystemURL::FileSystemURL() |
| : is_valid_(false), |
| mount_type_(kFileSystemTypeUnknown), |
| type_(kFileSystemTypeUnknown), |
| mount_option_(FlushPolicy::NO_FLUSH_ON_COMPLETION) { |
| } |
| |
| FileSystemURL::FileSystemURL(const FileSystemURL& other) = default; |
| |
| // static |
| FileSystemURL FileSystemURL::CreateForTest(const GURL& url) { |
| return FileSystemURL(url); |
| } |
| |
| FileSystemURL FileSystemURL::CreateForTest(const GURL& origin, |
| FileSystemType mount_type, |
| const base::FilePath& virtual_path) { |
| return FileSystemURL(origin, mount_type, virtual_path); |
| } |
| |
| FileSystemURL FileSystemURL::CreateForTest( |
| const GURL& origin, |
| FileSystemType mount_type, |
| const base::FilePath& virtual_path, |
| const std::string& mount_filesystem_id, |
| FileSystemType cracked_type, |
| const base::FilePath& cracked_path, |
| const std::string& filesystem_id, |
| const FileSystemMountOption& mount_option) { |
| return FileSystemURL(origin, |
| mount_type, |
| virtual_path, |
| mount_filesystem_id, |
| cracked_type, |
| cracked_path, |
| filesystem_id, |
| mount_option); |
| } |
| |
| FileSystemURL::FileSystemURL(const GURL& url) |
| : mount_type_(kFileSystemTypeUnknown), |
| type_(kFileSystemTypeUnknown), |
| mount_option_(FlushPolicy::NO_FLUSH_ON_COMPLETION) { |
| is_valid_ = ParseFileSystemSchemeURL(url, &origin_, &mount_type_, |
| &virtual_path_); |
| path_ = virtual_path_; |
| type_ = mount_type_; |
| } |
| |
| FileSystemURL::FileSystemURL(const GURL& origin, |
| FileSystemType mount_type, |
| const base::FilePath& virtual_path) |
| : is_valid_(true), |
| origin_(origin), |
| mount_type_(mount_type), |
| virtual_path_(virtual_path.NormalizePathSeparators()), |
| type_(mount_type), |
| path_(virtual_path.NormalizePathSeparators()), |
| mount_option_(FlushPolicy::NO_FLUSH_ON_COMPLETION) { |
| } |
| |
| FileSystemURL::FileSystemURL(const GURL& origin, |
| FileSystemType mount_type, |
| const base::FilePath& virtual_path, |
| const std::string& mount_filesystem_id, |
| FileSystemType cracked_type, |
| const base::FilePath& cracked_path, |
| const std::string& filesystem_id, |
| const FileSystemMountOption& mount_option) |
| : is_valid_(true), |
| origin_(origin), |
| mount_type_(mount_type), |
| virtual_path_(virtual_path.NormalizePathSeparators()), |
| mount_filesystem_id_(mount_filesystem_id), |
| type_(cracked_type), |
| path_(cracked_path.NormalizePathSeparators()), |
| filesystem_id_(filesystem_id), |
| mount_option_(mount_option) { |
| } |
| |
| FileSystemURL::~FileSystemURL() {} |
| |
| GURL FileSystemURL::ToGURL() const { |
| if (!is_valid_) |
| return GURL(); |
| |
| std::string url = GetFileSystemRootURI(origin_, mount_type_).spec(); |
| if (url.empty()) |
| return GURL(); |
| |
| // Exactly match with DOMFileSystemBase::createFileSystemURL()'s encoding |
| // behavior, where the path is escaped by KURL::encodeWithURLEscapeSequences |
| // which is essentially encodeURIComponent except '/'. |
| std::string escaped = net::EscapeQueryParamValue( |
| virtual_path_.NormalizePathSeparatorsTo('/').AsUTF8Unsafe(), |
| false /* use_plus */); |
| base::ReplaceSubstringsAfterOffset(&escaped, 0, "%2F", "/"); |
| url.append(escaped); |
| |
| // Build nested GURL. |
| return GURL(url); |
| } |
| |
| std::string FileSystemURL::DebugString() const { |
| if (!is_valid_) |
| return "invalid filesystem: URL"; |
| std::ostringstream ss; |
| ss << GetFileSystemRootURI(origin_, mount_type_); |
| |
| // filesystem_id_ will be non empty for (and only for) cracked URLs. |
| if (!filesystem_id_.empty()) { |
| ss << virtual_path_.value(); |
| ss << " ("; |
| ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":"; |
| ss << path_.value(); |
| ss << ")"; |
| } else { |
| ss << path_.value(); |
| } |
| return ss.str(); |
| } |
| |
| bool FileSystemURL::IsParent(const FileSystemURL& child) const { |
| return IsInSameFileSystem(child) && |
| path().IsParent(child.path()); |
| } |
| |
| bool FileSystemURL::IsInSameFileSystem(const FileSystemURL& other) const { |
| return origin() == other.origin() && |
| type() == other.type() && |
| filesystem_id() == other.filesystem_id(); |
| } |
| |
| bool FileSystemURL::operator==(const FileSystemURL& that) const { |
| return origin_ == that.origin_ && |
| type_ == that.type_ && |
| path_ == that.path_ && |
| filesystem_id_ == that.filesystem_id_ && |
| is_valid_ == that.is_valid_; |
| } |
| |
| bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs, |
| const FileSystemURL& rhs) const { |
| DCHECK(lhs.is_valid_ && rhs.is_valid_); |
| if (lhs.origin_ != rhs.origin_) |
| return lhs.origin_ < rhs.origin_; |
| if (lhs.type_ != rhs.type_) |
| return lhs.type_ < rhs.type_; |
| if (lhs.filesystem_id_ != rhs.filesystem_id_) |
| return lhs.filesystem_id_ < rhs.filesystem_id_; |
| return lhs.path_ < rhs.path_; |
| } |
| |
| } // namespace storage |