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

Side by Side Diff: src/FileSystemJsObject.cpp

Issue 29449592: Issue 5183 - Provide async interface for FileSystem (Closed) Base URL: https://hg.adblockplus.org/libadblockplus/
Patch Set: Remove a #include Utils.h from test. Created June 2, 2017, 7:38 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/FileSystem.h> 18 #include <AdblockPlus/FileSystem.h>
19 #include <stdexcept> 19 #include <stdexcept>
20 #include <sstream> 20 #include <sstream>
21 #include <vector> 21 #include <vector>
22 22
23 #include <AdblockPlus/JsValue.h> 23 #include <AdblockPlus/JsValue.h>
24 #include "FileSystemJsObject.h" 24 #include "FileSystemJsObject.h"
25 #include "JsContext.h" 25 #include "JsContext.h"
26 #include "Thread.h"
27 #include "Utils.h" 26 #include "Utils.h"
28 27
29 using namespace AdblockPlus; 28 using namespace AdblockPlus;
30 29
31 namespace 30 namespace
32 { 31 {
33 class IoThread : public Thread
34 {
35 public:
36 IoThread(const JsEnginePtr& jsEngine, const JsValue& callback)
37 : Thread(true), jsEngine(jsEngine), fileSystem(jsEngine->GetFileSystem()),
38 callback(callback)
39 {
40 }
41
42 protected:
43 JsEnginePtr jsEngine;
44 FileSystemPtr fileSystem;
45 JsValue callback;
46 };
47
48 class ReadThread : public IoThread
49 {
50 public:
51 ReadThread(const JsEnginePtr& jsEngine, const JsValue& callback,
52 const std::string& path)
53 : IoThread(jsEngine, callback), path(path)
54 {
55 }
56
57 void Run()
58 {
59 std::string content;
60 std::string error;
61 try
62 {
63 std::shared_ptr<std::istream> stream = fileSystem->Read(path);
64 content = Utils::Slurp(*stream);
65 }
66 catch (std::exception& e)
67 {
68 error = e.what();
69 }
70 catch (...)
71 {
72 error = "Unknown error while reading from " + path;
73 }
74
75 const JsContext context(*jsEngine);
76 auto result = jsEngine->NewObject();
77 result.SetProperty("content", content);
78 result.SetProperty("error", error);
79 JsValueList params;
80 params.push_back(result);
81 callback.Call(params);
82 }
83
84 private:
85 std::string path;
86 };
87
88 class WriteThread : public IoThread
89 {
90 public:
91 WriteThread(const JsEnginePtr& jsEngine, const JsValue& callback,
92 const std::string& path, const std::string& content)
93 : IoThread(jsEngine, callback), path(path), content(content)
94 {
95 }
96
97 void Run()
98 {
99 std::string error;
100 try
101 {
102 std::stringstream stream;
103 stream << content;
104 fileSystem->Write(path, stream);
105 }
106 catch (std::exception& e)
107 {
108 error = e.what();
109 }
110 catch (...)
111 {
112 error = "Unknown error while writing to " + path;
113 }
114
115 const JsContext context(*jsEngine);
116 auto errorValue = jsEngine->NewValue(error);
117 JsValueList params;
118 params.push_back(errorValue);
119 callback.Call(params);
120 }
121
122 private:
123 std::string path;
124 std::string content;
125 };
126
127 class MoveThread : public IoThread
128 {
129 public:
130 MoveThread(const JsEnginePtr& jsEngine, const JsValue& callback,
131 const std::string& fromPath, const std::string& toPath)
132 : IoThread(jsEngine, callback), fromPath(fromPath), toPath(toPath)
133 {
134 }
135
136 void Run()
137 {
138 std::string error;
139 try
140 {
141 fileSystem->Move(fromPath, toPath);
142 }
143 catch (std::exception& e)
144 {
145 error = e.what();
146 }
147 catch (...)
148 {
149 error = "Unknown error while moving " + fromPath + " to " + toPath;
150 }
151
152 const JsContext context(*jsEngine);
153 auto errorValue = jsEngine->NewValue(error);
154 JsValueList params;
155 params.push_back(errorValue);
156 callback.Call(params);
157 }
158
159 private:
160 std::string fromPath;
161 std::string toPath;
162 };
163
164 class RemoveThread : public IoThread
165 {
166 public:
167 RemoveThread(const JsEnginePtr& jsEngine, const JsValue& callback,
168 const std::string& path)
169 : IoThread(jsEngine, callback), path(path)
170 {
171 }
172
173 void Run()
174 {
175 std::string error;
176 try
177 {
178 fileSystem->Remove(path);
179 }
180 catch (std::exception& e)
181 {
182 error = e.what();
183 }
184 catch (...)
185 {
186 error = "Unknown error while removing " + path;
187 }
188
189 const JsContext context(*jsEngine);
190 auto errorValue = jsEngine->NewValue(error);
191 JsValueList params;
192 params.push_back(errorValue);
193 callback.Call(params);
194 }
195
196 private:
197 std::string path;
198 };
199
200
201 class StatThread : public IoThread
202 {
203 public:
204 StatThread(const JsEnginePtr& jsEngine, const JsValue& callback,
205 const std::string& path)
206 : IoThread(jsEngine, callback), path(path)
207 {
208 }
209
210 void Run()
211 {
212 std::string error;
213 FileSystem::StatResult statResult;
214 try
215 {
216 statResult = fileSystem->Stat(path);
217 }
218 catch (std::exception& e)
219 {
220 error = e.what();
221 }
222 catch (...)
223 {
224 error = "Unknown error while calling stat on " + path;
225 }
226
227 const JsContext context(*jsEngine);
228 auto result = jsEngine->NewObject();
229 result.SetProperty("exists", statResult.exists);
230 result.SetProperty("isFile", statResult.isFile);
231 result.SetProperty("isDirectory", statResult.isDirectory);
232 result.SetProperty("lastModified", statResult.lastModified);
233 result.SetProperty("error", error);
234
235 JsValueList params;
236 params.push_back(result);
237 callback.Call(params);
238 }
239
240 private:
241 std::string path;
242 };
243
244 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) 32 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments)
245 { 33 {
246 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 34 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
247 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 35 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
248 36
249 v8::Isolate* isolate = arguments.GetIsolate(); 37 v8::Isolate* isolate = arguments.GetIsolate();
250 if (converted.size() != 2) 38 if (converted.size() != 2)
251 return v8::ThrowException(Utils::ToV8String(isolate, 39 return v8::ThrowException(Utils::ToV8String(isolate,
252 "_fileSystem.read requires 2 parameters")); 40 "_fileSystem.read requires 2 parameters"));
253 if (!converted[1].IsFunction()) 41 if (!converted[1].IsFunction())
254 return v8::ThrowException(Utils::ToV8String(isolate, 42 return v8::ThrowException(Utils::ToV8String(isolate,
255 "Second argument to _fileSystem.read must be a function")); 43 "Second argument to _fileSystem.read must be a function"));
256 ReadThread* const readThread = new ReadThread(jsEngine, converted[1], 44
257 converted[0].AsString()); 45
258 readThread->Start(); 46 JsValue callback(converted[1]);
47 jsEngine->GetFileSystem()->Read(converted[0].AsString(),
48 [jsEngine, callback]
sergei 2017/06/16 15:05:55 Here and below that's what we also want to avoid.
hub 2017/06/16 21:52:54 Done.
49 (std::string&& content, const std::string& error)
50 {
51 const JsContext context(*jsEngine);
52 auto result = jsEngine->NewObject();
53 result.SetProperty("content", content);
sergei 2017/06/16 15:05:55 `content` should be moved, but getting into accoun
hub 2017/06/16 21:52:54 Acknowledged.
54 result.SetProperty("error", error);
55 JsValueList params;
56 params.push_back(result);
57 callback.Call(params);
sergei 2017/06/16 15:05:55 We can simply call `callback.Call(result);` withou
hub 2017/06/16 21:52:54 Done.
58 });
59
259 return v8::Undefined(); 60 return v8::Undefined();
260 } 61 }
261 62
262 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) 63 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments)
263 { 64 {
264 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 65 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
265 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 66 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
266 67
267 v8::Isolate* isolate = arguments.GetIsolate(); 68 v8::Isolate* isolate = arguments.GetIsolate();
268 if (converted.size() != 3) 69 if (converted.size() != 3)
269 return v8::ThrowException(Utils::ToV8String(isolate, 70 return v8::ThrowException(Utils::ToV8String(isolate,
270 "_fileSystem.write requires 3 parameters")); 71 "_fileSystem.write requires 3 parameters"));
271 if (!converted[2].IsFunction()) 72 if (!converted[2].IsFunction())
272 return v8::ThrowException(Utils::ToV8String(isolate, 73 return v8::ThrowException(Utils::ToV8String(isolate,
273 "Third argument to _fileSystem.write must be a function")); 74 "Third argument to _fileSystem.write must be a function"));
274 WriteThread* const writeThread = new WriteThread(jsEngine, converted[2], 75
275 converted[0].AsString(), converted[1].AsString()); 76 JsValue callback(converted[2]);
276 writeThread->Start(); 77 auto stream = std::make_shared<std::stringstream>();
78 *stream << converted[1].AsString();
79 jsEngine->GetFileSystem()->Write(converted[0].AsString(), stream,
80 [jsEngine, callback](const std::string& error)
81 {
82 const JsContext context(*jsEngine);
83 auto errorValue = jsEngine->NewValue(error);
84 JsValueList params;
85 params.push_back(errorValue);
sergei 2017/06/16 15:05:55 If the error is an empty string it will be still e
hub 2017/06/16 21:52:54 We can rework this later I think. Currently the Fi
86 callback.Call(params);
87 });
88
277 return v8::Undefined(); 89 return v8::Undefined();
278 } 90 }
279 91
280 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) 92 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments)
281 { 93 {
282 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 94 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
283 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 95 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
284 96
285 v8::Isolate* isolate = arguments.GetIsolate(); 97 v8::Isolate* isolate = arguments.GetIsolate();
286 if (converted.size() != 3) 98 if (converted.size() != 3)
287 return v8::ThrowException(Utils::ToV8String(isolate, 99 return v8::ThrowException(Utils::ToV8String(isolate,
288 "_fileSystem.move requires 3 parameters")); 100 "_fileSystem.move requires 3 parameters"));
289 if (!converted[2].IsFunction()) 101 if (!converted[2].IsFunction())
290 return v8::ThrowException(Utils::ToV8String(isolate, 102 return v8::ThrowException(Utils::ToV8String(isolate,
291 "Third argument to _fileSystem.move must be a function")); 103 "Third argument to _fileSystem.move must be a function"));
292 MoveThread* const moveThread = new MoveThread(jsEngine, converted[2], 104
293 converted[0].AsString(), converted[1].AsString()); 105 JsValue callback(converted[2]);
294 moveThread->Start(); 106 jsEngine->GetFileSystem()->Move(converted[0].AsString(),
107 converted[1].AsString(),
108 [jsEngine, callback](const std::string& error)
109 {
110 const JsContext context(*jsEngine);
111 auto errorValue = jsEngine->NewValue(error);
112 JsValueList params;
113 params.push_back(errorValue);
114 callback.Call(params);
115 });
116
295 return v8::Undefined(); 117 return v8::Undefined();
296 } 118 }
297 119
298 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) 120 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments)
299 { 121 {
300 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 122 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
301 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 123 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
302 124
303 v8::Isolate* isolate = arguments.GetIsolate(); 125 v8::Isolate* isolate = arguments.GetIsolate();
304 if (converted.size() != 2) 126 if (converted.size() != 2)
305 return v8::ThrowException(Utils::ToV8String(isolate, 127 return v8::ThrowException(Utils::ToV8String(isolate,
306 "_fileSystem.remove requires 2 parameters")); 128 "_fileSystem.remove requires 2 parameters"));
307 if (!converted[1].IsFunction()) 129 if (!converted[1].IsFunction())
308 return v8::ThrowException(Utils::ToV8String(isolate, 130 return v8::ThrowException(Utils::ToV8String(isolate,
309 "Second argument to _fileSystem.remove must be a function")); 131 "Second argument to _fileSystem.remove must be a function"));
310 RemoveThread* const removeThread = new RemoveThread(jsEngine, converted[1], 132
311 converted[0].AsString()); 133 JsValue callback(converted[1]);
312 removeThread->Start(); 134 jsEngine->GetFileSystem()->Remove(converted[0].AsString(),
135 [jsEngine, callback](const std::string& error)
136 {
137 const JsContext context(*jsEngine);
138 auto errorValue = jsEngine->NewValue(error);
139 JsValueList params;
140 params.push_back(errorValue);
141 callback.Call(params);
142 });
143
313 return v8::Undefined(); 144 return v8::Undefined();
314 } 145 }
315 146
316 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) 147 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments)
317 { 148 {
318 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 149 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
319 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 150 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
320 151
321 v8::Isolate* isolate = arguments.GetIsolate(); 152 v8::Isolate* isolate = arguments.GetIsolate();
322 if (converted.size() != 2) 153 if (converted.size() != 2)
323 return v8::ThrowException(Utils::ToV8String(isolate, 154 return v8::ThrowException(Utils::ToV8String(isolate,
324 "_fileSystem.stat requires 2 parameters")); 155 "_fileSystem.stat requires 2 parameters"));
325 if (!converted[1].IsFunction()) 156 if (!converted[1].IsFunction())
326 return v8::ThrowException(Utils::ToV8String(isolate, 157 return v8::ThrowException(Utils::ToV8String(isolate,
327 "Second argument to _fileSystem.stat must be a function")); 158 "Second argument to _fileSystem.stat must be a function"));
328 StatThread* const statThread = new StatThread(jsEngine, converted[1], 159
329 converted[0].AsString()); 160 JsValue callback(converted[1]);
330 statThread->Start(); 161 jsEngine->GetFileSystem()->Stat(converted[0].AsString(),
162 [jsEngine, callback]
163 (const IFileSystem::StatResult& statResult, const std::string& error)
164 {
165 const JsContext context(*jsEngine);
166 auto result = jsEngine->NewObject();
167
168 result.SetProperty("exists", statResult.exists);
169 result.SetProperty("isFile", statResult.isFile);
170 result.SetProperty("isDirectory", statResult.isDirectory);
171 result.SetProperty("lastModified", statResult.lastModified);
172 result.SetProperty("error", error);
173
174 JsValueList params;
175 params.push_back(result);
176 callback.Call(params);
177 });
178
331 return v8::Undefined(); 179 return v8::Undefined();
332 } 180 }
333 181
334 v8::Handle<v8::Value> ResolveCallback(const v8::Arguments& arguments) 182 v8::Handle<v8::Value> ResolveCallback(const v8::Arguments& arguments)
335 { 183 {
336 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 184 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
337 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 185 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
338 186
339 v8::Isolate* isolate = arguments.GetIsolate(); 187 v8::Isolate* isolate = arguments.GetIsolate();
340 if (converted.size() != 1) 188 if (converted.size() != 1)
(...skipping 11 matching lines...) Expand all
352 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj) 200 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj)
353 { 201 {
354 obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback)); 202 obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback));
355 obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback)); 203 obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback));
356 obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback)); 204 obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback));
357 obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback)); 205 obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback));
358 obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback)); 206 obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback));
359 obj.SetProperty("resolve", jsEngine.NewCallback(::ResolveCallback)); 207 obj.SetProperty("resolve", jsEngine.NewCallback(::ResolveCallback));
360 return obj; 208 return obj;
361 } 209 }
OLDNEW

Powered by Google App Engine
This is Rietveld