15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
115e3f23d412006dc4db4e659864679f29341e113fTorne (Richard Coles)#include "base/strings/string_util.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/sys_string_conversions.h"
13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/base/escape.h"
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/base/net_errors.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/database/database_identifier.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPersistentDir[] = "/persistent";
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTemporaryDir[] = "/temporary";
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIsolatedDir[] = "/isolated";
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kExternalDir[] = "/external";
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTestDir[] = "/test";
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType VirtualPath::kRoot[] = FILE_PATH_LITERAL("/");
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType VirtualPath::kSeparator = FILE_PATH_LITERAL('/');
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(ericu): Consider removing support for '\', even on Windows, if possible.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There's a lot of test code that will need reworking, and we may have trouble
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// with base::FilePath elsewhere [e.g. DirName and other methods may also need
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// replacement].
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath VirtualPath::BaseName(const base::FilePath& virtual_path) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType path = virtual_path.value();
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Keep everything after the final separator, but if the pathname is only
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // one character and it's a separator, leave it alone.
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (path.size() > 1 && base::FilePath::IsSeparator(path[path.size() - 1]))
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.resize(path.size() - 1);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType::size_type last_separator =
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      path.find_last_of(base::FilePath::kSeparators);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (last_separator != base::FilePath::StringType::npos &&
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      last_separator < path.size() - 1)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    path.erase(0, last_separator + 1);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(path);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath VirtualPath::DirName(const base::FilePath& virtual_path) {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::FilePath::StringType StringType;
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringType  path = virtual_path.value();
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The logic below is taken from that of base::FilePath::DirName, except
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that this version never cares about '//' or drive-letters even on win32.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Strip trailing separators.
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (path.size() > 1 && base::FilePath::IsSeparator(path[path.size() - 1]))
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    path.resize(path.size() - 1);
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringType::size_type last_separator =
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      path.find_last_of(base::FilePath::kSeparators);
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (last_separator == StringType::npos) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // path_ is in the current directory.
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath(base::FilePath::kCurrentDirectory);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (last_separator == 0) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // path_ is in the root directory.
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath(path.substr(0, 1));
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // path_ is somewhere else, trim the basename.
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  path.resize(last_separator);
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Strip trailing separators.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (path.size() > 1 && base::FilePath::IsSeparator(path[path.size() - 1]))
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    path.resize(path.size() - 1);
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (path.empty())
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath(base::FilePath::kCurrentDirectory);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(path);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void VirtualPath::GetComponents(
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<base::FilePath::StringType>* components) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::FilePath::StringType StringType;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(components);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!components)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  components->clear();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (path.value().empty())
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StringType::size_type begin = 0, end = 0;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  while (begin < path.value().length() && end != StringType::npos) {
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    end = path.value().find_first_of(base::FilePath::kSeparators, begin);
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    StringType component = path.value().substr(
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        begin, end == StringType::npos ? StringType::npos : end - begin);
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!component.empty() && component != base::FilePath::kCurrentDirectory)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      components->push_back(component);
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    begin = end + 1;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void VirtualPath::GetComponentsUTF8Unsafe(
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::FilePath& path,
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    std::vector<std::string>* components) {
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DCHECK(components);
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!components)
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return;
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  components->clear();
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<base::FilePath::StringType> stringtype_components;
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  VirtualPath::GetComponents(path, &stringtype_components);
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  std::vector<base::FilePath::StringType>::const_iterator it;
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (it = stringtype_components.begin(); it != stringtype_components.end();
1197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)       ++it) {
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    components->push_back(base::FilePath(*it).AsUTF8Unsafe());
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath::StringType VirtualPath::GetNormalizedFilePath(
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath::StringType normalized_path = path.value();
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const size_t num_separators = base::FilePath::StringType(
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath::kSeparators).length();
129b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  for (size_t i = 0; i < num_separators; ++i) {
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::replace(normalized_path.begin(), normalized_path.end(),
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                 base::FilePath::kSeparators[i], kSeparator);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return (IsAbsolute(normalized_path)) ?
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      normalized_path : base::FilePath::StringType(kRoot) + normalized_path;
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool VirtualPath::IsAbsolute(const base::FilePath::StringType& path) {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return path.find(kRoot) == 0;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool VirtualPath::IsRootPath(const base::FilePath& path) {
143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  std::vector<base::FilePath::StringType> components;
144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  VirtualPath::GetComponents(path, &components);
145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return (path.empty() || components.empty() ||
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          (components.size() == 1 &&
147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch           components[0] == VirtualPath::kRoot));
148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool ParseFileSystemSchemeURL(const GURL& url,
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              GURL* origin_url,
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              FileSystemType* type,
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                              base::FilePath* virtual_path) {
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  GURL origin;
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FileSystemType file_system_type = kFileSystemTypeUnknown;
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
157a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (!url.is_valid() || !url.SchemeIsFileSystem())
158a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
159a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
160a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const struct {
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FileSystemType type;
162a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    const char* dir;
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  } kValidTypes[] = {
164a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    { kFileSystemTypePersistent, kPersistentDir },
165a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    { kFileSystemTypeTemporary, kTemporaryDir },
166a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    { kFileSystemTypeIsolated, kIsolatedDir },
167a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    { kFileSystemTypeExternal, kExternalDir },
168a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    { kFileSystemTypeTest, kTestDir },
169a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  };
170a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
171a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // A path of the inner_url contains only mount type part (e.g. "/temporary").
172a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(url.inner_url());
173a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string inner_path = url.inner_url()->path();
174a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) {
175a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (inner_path == kValidTypes[i].dir) {
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      file_system_type = kValidTypes[i].type;
177a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      break;
178a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
179a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
180a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
181a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (file_system_type == kFileSystemTypeUnknown)
182a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
184a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::string path = net::UnescapeURLComponent(url.path(),
185a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::UnescapeRule::SPACES | net::UnescapeRule::URL_SPECIAL_CHARS |
186a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      net::UnescapeRule::CONTROL_CHARS);
187a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Ensure the path is relative.
189a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  while (!path.empty() && path[0] == '/')
190a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    path.erase(0, 1);
191a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
192a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  base::FilePath converted_path = base::FilePath::FromUTF8Unsafe(path);
193a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
194a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // All parent references should have been resolved in the renderer.
195a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (converted_path.ReferencesParent())
196a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    return false;
197a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
198a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (origin_url)
199a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *origin_url = url.GetOrigin();
200a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (type)
201a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *type = file_system_type;
202a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (virtual_path)
203a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    *virtual_path = converted_path.NormalizePathSeparators().
204a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        StripTrailingSeparators();
205a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
206a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return true;
207a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
208a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL GetFileSystemRootURI(const GURL& origin_url, FileSystemType type) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // origin_url is based on a security origin, so http://foo.com or file:///
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead of the corresponding filesystem URL.
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!origin_url.SchemeIsFileSystem());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string url = "filesystem:" + origin_url.GetWithEmptyPath().spec();
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
2164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case kFileSystemTypeTemporary:
2174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      url += (kTemporaryDir + 1);  // We don't want the leading slash.
2184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return GURL(url + "/");
2194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case kFileSystemTypePersistent:
2204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      url += (kPersistentDir + 1);  // We don't want the leading slash.
2214e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return GURL(url + "/");
2224e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case kFileSystemTypeExternal:
2234e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      url += (kExternalDir + 1);  // We don't want the leading slash.
2244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return GURL(url + "/");
2254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case kFileSystemTypeIsolated:
2264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      url += (kIsolatedDir + 1);  // We don't want the leading slash.
2274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return GURL(url + "/");
2284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    case kFileSystemTypeTest:
2294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      url += (kTestDir + 1);  // We don't want the leading slash.
2304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      return GURL(url + "/");
2314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      // Internal types are always pointed via isolated or external URLs.
2324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    default:
2334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      NOTREACHED();
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL();
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetFileSystemName(const GURL& origin_url, FileSystemType type) {
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string origin_identifier = storage::GetIdentifierFromOrigin(origin_url);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string type_string = GetFileSystemTypeString(type);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!type_string.empty());
2437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return origin_identifier + ":" + type_string;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemType QuotaStorageTypeToFileSystemType(
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::StorageType storage_type) {
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (storage_type) {
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case storage::kStorageTypeTemporary:
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kFileSystemTypeTemporary;
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case storage::kStorageTypePersistent:
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kFileSystemTypePersistent;
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case storage::kStorageTypeSyncable:
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kFileSystemTypeSyncable;
25503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case storage::kStorageTypeQuotaNotManaged:
25603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    case storage::kStorageTypeUnknown:
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kFileSystemTypeUnknown;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kFileSystemTypeUnknown;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)storage::StorageType FileSystemTypeToQuotaStorageType(FileSystemType type) {
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeTemporary:
26503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return storage::kStorageTypeTemporary;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypePersistent:
26703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return storage::kStorageTypePersistent;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeSyncable:
269868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kFileSystemTypeSyncableForInternalSync:
27003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return storage::kStorageTypeSyncable;
2711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    case kFileSystemTypePluginPrivate:
27203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return storage::kStorageTypeQuotaNotManaged;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
27403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      return storage::kStorageTypeUnknown;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetFileSystemTypeString(FileSystemType type) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (type) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeTemporary:
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Temporary";
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypePersistent:
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Persistent";
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeIsolated:
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Isolated";
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeExternal:
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "External";
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeTest:
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Test";
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeNativeLocal:
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "NativeLocal";
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeRestrictedNativeLocal:
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "RestrictedNativeLocal";
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeDragged:
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Dragged";
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeNativeMedia:
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "NativeMedia";
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeDeviceMedia:
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "DeviceMedia";
30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    case kFileSystemTypePicasa:
30190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return "Picasa";
302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    case kFileSystemTypeItunes:
303b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      return "Itunes";
30468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case kFileSystemTypeIphoto:
30568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      return "Iphoto";
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeDrive:
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Drive";
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeSyncable:
309868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    case kFileSystemTypeSyncableForInternalSync:
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Syncable";
3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    case kFileSystemTypeNativeForPlatformApp:
3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return "NativeForPlatformApp";
313a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    case kFileSystemTypeForTransientFile:
314a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      return "TransientFile";
3158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    case kFileSystemTypePluginPrivate:
3168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return "PluginPrivate";
3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case kFileSystemTypeCloudDevice:
3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return "CloudDevice";
319effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    case kFileSystemTypeProvided:
320effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return "Provided";
3215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    case kFileSystemTypeDeviceMediaAsFileStorage:
3225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return "DeviceMediaStorage";
323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case kFileSystemInternalTypeEnumStart:
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case kFileSystemInternalTypeEnumEnd:
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED();
326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // Fall through.
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case kFileSystemTypeUnknown:
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return "Unknown";
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string();
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string FilePathToString(const base::FilePath& file_path) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::UTF16ToUTF8(file_path.value());
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return file_path.value();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath StringToFilePath(const std::string& file_path_string) {
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::FilePath(base::UTF8ToUTF16(file_path_string));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return base::FilePath(file_path_string);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)blink::WebFileError FileErrorToWebFileError(
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error_code) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (error_code) {
3535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_NOT_FOUND:
354f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorNotFound;
3555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_INVALID_OPERATION:
3565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_EXISTS:
3575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_NOT_EMPTY:
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorInvalidModification;
3595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_NOT_A_DIRECTORY:
3605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_NOT_A_FILE:
361f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorTypeMismatch;
3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_ACCESS_DENIED:
363f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorNoModificationAllowed;
3645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_FAILED:
365f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorInvalidState;
3665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_ABORT:
367f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorAbort;
3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_SECURITY:
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorSecurity;
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_NO_SPACE:
371f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorQuotaExceeded;
3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_INVALID_URL:
373f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorEncoding;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:
375f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      return blink::WebFileErrorInvalidModification;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetFileSystemPublicType(
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string type_string,
381f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebFileSystemType* type) {
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(type);
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_string == "Temporary") {
384f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *type = blink::WebFileSystemTypeTemporary;
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_string == "Persistent") {
388f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *type = blink::WebFileSystemTypePersistent;
3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_string == "Isolated") {
392f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *type = blink::WebFileSystemTypeIsolated;
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (type_string == "External") {
396f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    *type = blink::WebFileSystemTypeExternal;
3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  NOTREACHED();
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string GetIsolatedFileSystemName(const GURL& origin_url,
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      const std::string& filesystem_id) {
40503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string name(
40603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::GetFileSystemName(origin_url, storage::kFileSystemTypeIsolated));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name.append("_");
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  name.append(filesystem_id);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return name;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CrackIsolatedFileSystemName(const std::string& filesystem_name,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 std::string* filesystem_id) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(filesystem_id);
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |filesystem_name| is of the form {origin}:isolated_{filesystem_id}.
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string start_token(":");
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  start_token = start_token.append(
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetFileSystemTypeString(kFileSystemTypeIsolated)).append("_");
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // WebKit uses different case in its constant for isolated file system
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // names, so we do a case insensitive compare by converting both strings
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to uppercase.
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(benwells): Remove this when WebKit uses the same constant.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  start_token = StringToUpperASCII(start_token);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string filesystem_name_upper = StringToUpperASCII(filesystem_name);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t pos = filesystem_name_upper.find(start_token);
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pos == std::string::npos)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pos == 0)
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *filesystem_id = filesystem_name.substr(pos + start_token.length(),
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          std::string::npos);
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (filesystem_id->empty())
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)bool ValidateIsolatedFileSystemId(const std::string& filesystem_id) {
4411e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const size_t kExpectedFileSystemIdSize = 32;
4421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (filesystem_id.size() != kExpectedFileSystemIdSize)
4431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    return false;
4441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  const std::string kExpectedChars("ABCDEF0123456789");
445a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return base::ContainsOnlyChars(filesystem_id, kExpectedChars);
4461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
4471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string GetIsolatedFileSystemRootURIString(
4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const GURL& origin_url,
4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& filesystem_id,
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& optional_root_name) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string root = GetFileSystemRootURI(origin_url,
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          kFileSystemTypeIsolated).spec();
454c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (base::FilePath::FromUTF8Unsafe(filesystem_id).ReferencesParent())
455c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  root.append(net::EscapePath(filesystem_id));
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  root.append("/");
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!optional_root_name.empty()) {
459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (base::FilePath::FromUTF8Unsafe(optional_root_name).ReferencesParent())
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return std::string();
461f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    root.append(net::EscapePath(optional_root_name));
4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    root.append("/");
4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return root;
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
467868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)std::string GetExternalFileSystemRootURIString(
468868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const GURL& origin_url,
469868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const std::string& mount_name) {
470868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  std::string root = GetFileSystemRootURI(origin_url,
471868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                                          kFileSystemTypeExternal).spec();
472868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (base::FilePath::FromUTF8Unsafe(mount_name).ReferencesParent())
473868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return std::string();
474f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  root.append(net::EscapePath(mount_name));
475868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  root.append("/");
476868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return root;
477868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::File::Error NetErrorToFileError(int error) {
48068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  switch (error) {
48168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::OK:
4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_OK;
48368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_ADDRESS_IN_USE:
4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_IN_USE;
48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_FILE_EXISTS:
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_EXISTS;
48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_FILE_NOT_FOUND:
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_NOT_FOUND;
48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_ACCESS_DENIED:
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_ACCESS_DENIED;
49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_TOO_MANY_SOCKET_STREAMS:
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_TOO_MANY_OPENED;
49368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_OUT_OF_MEMORY:
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_NO_MEMORY;
49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_FILE_NO_SPACE:
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_NO_SPACE;
49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_INVALID_ARGUMENT:
49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_INVALID_HANDLE:
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_INVALID_OPERATION;
50068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_ABORTED:
50168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_CONNECTION_ABORTED:
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_ABORT;
50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_ADDRESS_INVALID:
50468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    case net::ERR_INVALID_URL:
5055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_INVALID_URL;
50668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    default:
5075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      return base::File::FILE_ERROR_FAILED;
50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
50968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
51068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
51103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
512