OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 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 "chrome/browser/chromeos/drive/file_system_core_util.h" |
| 6 |
| 7 #include <string> |
| 8 #include <vector> |
| 9 |
| 10 #include "base/basictypes.h" |
| 11 #include "base/bind.h" |
| 12 #include "base/bind_helpers.h" |
| 13 #include "base/files/file_path.h" |
| 14 #include "base/files/file_util.h" |
| 15 #include "base/i18n/icu_string_conversions.h" |
| 16 #include "base/json/json_file_value_serializer.h" |
| 17 #include "base/logging.h" |
| 18 #include "base/memory/scoped_ptr.h" |
| 19 #include "base/prefs/pref_service.h" |
| 20 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/strings/string_util.h" |
| 22 #include "base/strings/stringprintf.h" |
| 23 #include "base/thread_task_runner_handle.h" |
| 24 #include "base/threading/sequenced_worker_pool.h" |
| 25 #include "chrome/browser/chromeos/drive/drive.pb.h" |
| 26 #include "chrome/browser/chromeos/drive/drive_pref_names.h" |
| 27 #include "chrome/browser/chromeos/drive/file_system_interface.h" |
| 28 #include "chrome/browser/chromeos/drive/job_list.h" |
| 29 #include "chrome/browser/chromeos/drive/write_on_cache_file.h" |
| 30 #include "net/base/escape.h" |
| 31 |
| 32 namespace drive { |
| 33 namespace util { |
| 34 |
| 35 namespace { |
| 36 |
| 37 std::string ReadStringFromGDocFile(const base::FilePath& file_path, |
| 38 const std::string& key) { |
| 39 const int64 kMaxGDocSize = 4096; |
| 40 int64 file_size = 0; |
| 41 if (!base::GetFileSize(file_path, &file_size) || file_size > kMaxGDocSize) { |
| 42 LOG(WARNING) << "File too large to be a GDoc file " << file_path.value(); |
| 43 return std::string(); |
| 44 } |
| 45 |
| 46 JSONFileValueDeserializer reader(file_path); |
| 47 std::string error_message; |
| 48 scoped_ptr<base::Value> root_value(reader.Deserialize(NULL, &error_message)); |
| 49 if (!root_value) { |
| 50 LOG(WARNING) << "Failed to parse " << file_path.value() << " as JSON." |
| 51 << " error = " << error_message; |
| 52 return std::string(); |
| 53 } |
| 54 |
| 55 base::DictionaryValue* dictionary_value = NULL; |
| 56 std::string result; |
| 57 if (!root_value->GetAsDictionary(&dictionary_value) || |
| 58 !dictionary_value->GetString(key, &result)) { |
| 59 LOG(WARNING) << "No value for the given key is stored in " |
| 60 << file_path.value() << ". key = " << key; |
| 61 return std::string(); |
| 62 } |
| 63 |
| 64 return result; |
| 65 } |
| 66 |
| 67 } // namespace |
| 68 |
| 69 const base::FilePath& GetDriveGrandRootPath() { |
| 70 CR_DEFINE_STATIC_LOCAL( |
| 71 base::FilePath, grand_root_path, |
| 72 (base::FilePath::FromUTF8Unsafe(kDriveGrandRootDirName))); |
| 73 return grand_root_path; |
| 74 } |
| 75 |
| 76 const base::FilePath& GetDriveMyDriveRootPath() { |
| 77 CR_DEFINE_STATIC_LOCAL( |
| 78 base::FilePath, drive_root_path, |
| 79 (GetDriveGrandRootPath().AppendASCII(kDriveMyDriveRootDirName))); |
| 80 return drive_root_path; |
| 81 } |
| 82 |
| 83 base::FilePath GetDriveMountPointPathForUserIdHash( |
| 84 const std::string user_id_hash) { |
| 85 static const base::FilePath::CharType kSpecialMountPointRoot[] = |
| 86 FILE_PATH_LITERAL("/special"); |
| 87 static const char kDriveMountPointNameBase[] = "drive"; |
| 88 return base::FilePath(kSpecialMountPointRoot) |
| 89 .AppendASCII(net::EscapeQueryParamValue( |
| 90 kDriveMountPointNameBase + |
| 91 (user_id_hash.empty() ? "" : "-" + user_id_hash), |
| 92 false)); |
| 93 } |
| 94 |
| 95 bool IsUnderDriveMountPoint(const base::FilePath& path) { |
| 96 return !ExtractDrivePath(path).empty(); |
| 97 } |
| 98 |
| 99 base::FilePath ExtractDrivePath(const base::FilePath& path) { |
| 100 std::vector<base::FilePath::StringType> components; |
| 101 path.GetComponents(&components); |
| 102 if (components.size() < 3) |
| 103 return base::FilePath(); |
| 104 if (components[0] != FILE_PATH_LITERAL("/")) |
| 105 return base::FilePath(); |
| 106 if (components[1] != FILE_PATH_LITERAL("special")) |
| 107 return base::FilePath(); |
| 108 static const base::FilePath::CharType kPrefix[] = FILE_PATH_LITERAL("drive"); |
| 109 if (components[2].compare(0, arraysize(kPrefix) - 1, kPrefix) != 0) |
| 110 return base::FilePath(); |
| 111 |
| 112 base::FilePath drive_path = GetDriveGrandRootPath(); |
| 113 for (size_t i = 3; i < components.size(); ++i) |
| 114 drive_path = drive_path.Append(components[i]); |
| 115 return drive_path; |
| 116 } |
| 117 |
| 118 std::string EscapeCacheFileName(const std::string& filename) { |
| 119 // This is based on net/base/escape.cc: net::(anonymous namespace)::Escape |
| 120 std::string escaped; |
| 121 for (size_t i = 0; i < filename.size(); ++i) { |
| 122 char c = filename[i]; |
| 123 if (c == '%' || c == '.' || c == '/') { |
| 124 base::StringAppendF(&escaped, "%%%02X", c); |
| 125 } else { |
| 126 escaped.push_back(c); |
| 127 } |
| 128 } |
| 129 return escaped; |
| 130 } |
| 131 |
| 132 std::string UnescapeCacheFileName(const std::string& filename) { |
| 133 std::string unescaped; |
| 134 for (size_t i = 0; i < filename.size(); ++i) { |
| 135 char c = filename[i]; |
| 136 if (c == '%' && i + 2 < filename.length()) { |
| 137 c = (base::HexDigitToInt(filename[i + 1]) << 4) + |
| 138 base::HexDigitToInt(filename[i + 2]); |
| 139 i += 2; |
| 140 } |
| 141 unescaped.push_back(c); |
| 142 } |
| 143 return unescaped; |
| 144 } |
| 145 |
| 146 std::string NormalizeFileName(const std::string& input) { |
| 147 DCHECK(base::IsStringUTF8(input)); |
| 148 |
| 149 std::string output; |
| 150 if (!base::ConvertToUtf8AndNormalize(input, base::kCodepageUTF8, &output)) |
| 151 output = input; |
| 152 base::ReplaceChars(output, "/", "_", &output); |
| 153 if (!output.empty() && output.find_first_not_of('.', 0) == std::string::npos) |
| 154 output = "_"; |
| 155 return output; |
| 156 } |
| 157 |
| 158 void EmptyFileOperationCallback(FileError error) { |
| 159 } |
| 160 |
| 161 bool CreateGDocFile(const base::FilePath& file_path, |
| 162 const GURL& url, |
| 163 const std::string& resource_id) { |
| 164 std::string content = |
| 165 base::StringPrintf("{\"url\": \"%s\", \"resource_id\": \"%s\"}", |
| 166 url.spec().c_str(), resource_id.c_str()); |
| 167 return base::WriteFile(file_path, content.data(), content.size()) == |
| 168 static_cast<int>(content.size()); |
| 169 } |
| 170 |
| 171 GURL ReadUrlFromGDocFile(const base::FilePath& file_path) { |
| 172 return GURL(ReadStringFromGDocFile(file_path, "url")); |
| 173 } |
| 174 |
| 175 std::string ReadResourceIdFromGDocFile(const base::FilePath& file_path) { |
| 176 return ReadStringFromGDocFile(file_path, "resource_id"); |
| 177 } |
| 178 |
| 179 } // namespace util |
| 180 } // namespace drive |
OLD | NEW |