Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/DefaultFileSystem.cpp

Issue 29449592: Issue 5183 - Provide async interface for FileSystem (Closed) Base URL: https://hg.adblockplus.org/libadblockplus/
Patch Set: Make read write deal with binary buffers. Created July 6, 2017, 12:19 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2017 eyeo GmbH 3 * Copyright (C) 2006-2017 eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 #include <AdblockPlus/DefaultFileSystem.h> 18 #include <AdblockPlus/DefaultFileSystem.h>
19 #include <cstdio> 19 #include <cstdio>
20 #include <cstring> 20 #include <cstring>
21 #include <fstream> 21 #include <fstream>
22 #include <sstream>
22 #include <stdexcept> 23 #include <stdexcept>
24 #include <thread>
23 25
24 #include <sys/types.h> 26 #include <sys/types.h>
25 27
26 #ifdef _WIN32 28 #ifdef _WIN32
27 #include <windows.h> 29 #include <windows.h>
28 #include <Shlobj.h> 30 #include <Shlobj.h>
29 #include <Shlwapi.h> 31 #include <Shlwapi.h>
30 #else 32 #else
31 #include <sys/stat.h> 33 #include <sys/stat.h>
32 #include <cerrno> 34 #include <cerrno>
(...skipping 27 matching lines...) Expand all
60 // POSIX systems: assume that file system encoding is UTF-8 and just use the 62 // POSIX systems: assume that file system encoding is UTF-8 and just use the
61 // file paths as they are. 63 // file paths as they are.
62 std::string NormalizePath(const std::string& path) 64 std::string NormalizePath(const std::string& path)
63 { 65 {
64 return path; 66 return path;
65 } 67 }
66 #endif 68 #endif
67 } 69 }
68 70
69 std::shared_ptr<std::istream> 71 std::shared_ptr<std::istream>
70 DefaultFileSystem::Read(const std::string& path) const 72 DefaultFileSystemSync::Read(const std::string& path) const
71 { 73 {
72 std::shared_ptr<std::istream> result(new std::ifstream(NormalizePath(path).c_s tr())); 74 std::shared_ptr<std::istream> result(new std::ifstream(NormalizePath(path).c_s tr(), std::ios_base::binary));
73 if (result->fail()) 75 if (result->fail())
74 throw RuntimeErrorWithErrno("Failed to open " + path); 76 throw RuntimeErrorWithErrno("Failed to open " + path);
75 return result; 77 return result;
76 } 78 }
77 79
78 void DefaultFileSystem::Write(const std::string& path, 80
79 std::istream& data) 81 void DefaultFileSystemSync::Write(const std::string& path,
82 std::ostream& data)
80 { 83 {
81 std::ofstream file(NormalizePath(path).c_str(), std::ios_base::out | std::ios_ base::binary); 84 std::ofstream file(NormalizePath(path).c_str(), std::ios_base::out | std::ios_ base::binary);
82 file << Utils::Slurp(data); 85 file << data.rdbuf();
83 } 86 }
84 87
85 void DefaultFileSystem::Move(const std::string& fromPath, 88 void DefaultFileSystemSync::Move(const std::string& fromPath,
86 const std::string& toPath) 89 const std::string& toPath)
87 { 90 {
88 if (rename(NormalizePath(fromPath).c_str(), NormalizePath(toPath).c_str())) 91 if (rename(NormalizePath(fromPath).c_str(), NormalizePath(toPath).c_str()))
89 throw RuntimeErrorWithErrno("Failed to move " + fromPath + " to " + toPath); 92 throw RuntimeErrorWithErrno("Failed to move " + fromPath + " to " + toPath);
90 } 93 }
91 94
92 void DefaultFileSystem::Remove(const std::string& path) 95 void DefaultFileSystemSync::Remove(const std::string& path)
93 { 96 {
94 if (remove(NormalizePath(path).c_str())) 97 if (remove(NormalizePath(path).c_str()))
95 throw RuntimeErrorWithErrno("Failed to remove " + path); 98 throw RuntimeErrorWithErrno("Failed to remove " + path);
96 } 99 }
97 100
98 FileSystem::StatResult DefaultFileSystem::Stat(const std::string& path) const 101 IFileSystem::StatResult DefaultFileSystemSync::Stat(const std::string& path) con st
99 { 102 {
100 FileSystem::StatResult result; 103 IFileSystem::StatResult result;
101 #ifdef WIN32 104 #ifdef WIN32
102 WIN32_FILE_ATTRIBUTE_DATA data; 105 WIN32_FILE_ATTRIBUTE_DATA data;
103 if (!GetFileAttributesExW(NormalizePath(path).c_str(), GetFileExInfoStandard, &data)) 106 if (!GetFileAttributesExW(NormalizePath(path).c_str(), GetFileExInfoStandard, &data))
104 { 107 {
105 DWORD err = GetLastError(); 108 DWORD err = GetLastError();
106 if (err == ERROR_FILE_NOT_FOUND || 109 if (err == ERROR_FILE_NOT_FOUND ||
107 err == ERROR_PATH_NOT_FOUND || 110 err == ERROR_PATH_NOT_FOUND ||
108 err == ERROR_INVALID_DRIVE) 111 err == ERROR_INVALID_DRIVE)
109 { 112 {
110 return result; 113 return result;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 #if _POSIX_C_SOURCE >= 200809L 157 #if _POSIX_C_SOURCE >= 200809L
155 result.lastModified = static_cast<int64_t>(nativeStat.st_mtim.tv_sec) * MSEC_I N_SEC 158 result.lastModified = static_cast<int64_t>(nativeStat.st_mtim.tv_sec) * MSEC_I N_SEC
156 + static_cast<int64_t>(nativeStat.st_mtim.tv_nsec) / NSEC _IN_MSEC; 159 + static_cast<int64_t>(nativeStat.st_mtim.tv_nsec) / NSEC _IN_MSEC;
157 #else 160 #else
158 result.lastModified = static_cast<int64_t>(nativeStat.st_mtime) * MSEC_IN_SEC; 161 result.lastModified = static_cast<int64_t>(nativeStat.st_mtime) * MSEC_IN_SEC;
159 #endif 162 #endif
160 return result; 163 return result;
161 #endif 164 #endif
162 } 165 }
163 166
164 std::string DefaultFileSystem::Resolve(const std::string& path) const 167 std::string DefaultFileSystemSync::Resolve(const std::string& path) const
165 { 168 {
166 if (basePath == "") 169 if (basePath == "")
167 { 170 {
168 return path; 171 return path;
169 } 172 }
170 else 173 else
171 { 174 {
172 #ifdef _WIN32 175 #ifdef _WIN32
173 if (PathIsRelative(NormalizePath(path).c_str())) 176 if (PathIsRelative(NormalizePath(path).c_str()))
174 #else 177 #else
175 if (path.length() && *path.begin() != PATH_SEPARATOR) 178 if (path.length() && *path.begin() != PATH_SEPARATOR)
176 #endif 179 #endif
177 { 180 {
178 return basePath + PATH_SEPARATOR + path; 181 return basePath + PATH_SEPARATOR + path;
179 } 182 }
180 else 183 else
181 { 184 {
182 return path; 185 return path;
183 } 186 }
184 } 187 }
185 } 188 }
186 189
187 void DefaultFileSystem::SetBasePath(const std::string& path) 190 void DefaultFileSystemSync::SetBasePath(const std::string& path)
188 { 191 {
189 basePath = path; 192 basePath = path;
190 193
191 if (*basePath.rbegin() == PATH_SEPARATOR) 194 if (*basePath.rbegin() == PATH_SEPARATOR)
192 { 195 {
193 basePath.resize(basePath.size() - 1); 196 basePath.resize(basePath.size() - 1);
194 } 197 }
195 } 198 }
196 199
200 DefaultFileSystem::DefaultFileSystem(const FileSystemSyncPtr& syncImpl)
201 : syncImpl(syncImpl)
202 {
203 }
204
205 void DefaultFileSystem::Read(const std::string& path,
206 const ReadCallback& callback) const
207 {
208 auto impl = syncImpl;
209 std::thread([impl, path, callback]
210 {
211 std::string error;
212 try
213 {
214 auto is = impl->Read(path);
215 is->seekg(0, std::ios_base::end);
216 auto dataSize = is->tellg();
217 is->seekg(0, std::ios_base::beg);
218
219 std::vector<char> data(dataSize);
220 is->read(data.data(), data.size());
221 callback(std::move(data), error);
222 return;
223 }
224 catch (std::exception& e)
225 {
226 error = e.what();
227 }
228 catch (...)
229 {
230 error = "Unknown error while reading from " + path;
231 }
232 callback(std::vector<char>(), error);
233 }).detach();
234 }
235
236 void DefaultFileSystem::Write(const std::string& path,
237 const std::vector<char>& data,
238 const Callback& callback)
239 {
240 auto impl = syncImpl;
241 std::thread([impl, path, data, callback]
242 {
243 std::string error;
244 try
245 {
246 std::stringstream stream;
247 stream.write(data.data(), data.size());
248 impl->Write(path, stream);
249 }
250 catch (std::exception& e)
251 {
252 error = e.what();
253 }
254 catch (...)
255 {
256 error = "Unknown error while writing to " + path;
257 }
258 callback(error);
259 }).detach();
260 }
261
262 void DefaultFileSystem::Move(const std::string& fromPath,
263 const std::string& toPath,
264 const Callback& callback)
265 {
266 auto impl = syncImpl;
267 std::thread([impl, fromPath, toPath, callback]
268 {
269 std::string error;
270 try
271 {
272 impl->Move(fromPath, toPath);
273 }
274 catch (std::exception& e)
275 {
276 error = e.what();
277 }
278 catch (...)
279 {
280 error = "Unknown error while moving " + fromPath + " to " + toPath;
281 }
282 callback(error);
283 }).detach();
284 }
285
286 void DefaultFileSystem::Remove(const std::string& path,
287 const Callback& callback)
288 {
289 auto impl = syncImpl;
290 std::thread([impl, path, callback]
291 {
292 std::string error;
293 try
294 {
295 impl->Remove(path);
296 }
297 catch (std::exception& e)
298 {
299 error = e.what();
300 }
301 catch (...)
302 {
303 error = "Unknown error while removing " + path;
304 }
305 callback(error);
306 }).detach();
307 }
308
309 void DefaultFileSystem::Stat(const std::string& path,
310 const StatCallback& callback) const
311 {
312 auto impl = syncImpl;
313 std::thread([impl, path, callback]
314 {
315 std::string error;
316 try
317 {
318 auto result = impl->Stat(path);
319 callback(result, error);
320 return;
321 }
322 catch (std::exception& e)
323 {
324 error = e.what();
325 }
326 catch (...)
327 {
328 error = "Unknown error while calling stat on " + path;
329 }
330 callback(StatResult(), error);
331 }).detach();
332 }
333
334 std::string DefaultFileSystem::Resolve(const std::string& path) const
335 {
336 return syncImpl->Resolve(path);
337 }
OLDNEW

Powered by Google App Engine
This is Rietveld