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: Rebased. Corrected most of the review issues. Created July 4, 2017, 7:57 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 using AdblockPlus::Utils::ThrowExceptionInJS; 29 using AdblockPlus::Utils::ThrowExceptionInJS;
31 30
32 namespace 31 namespace
33 { 32 {
34 class IoThread : public Thread
35 {
36 public:
37 IoThread(const JsEnginePtr& jsEngine, const JsValue& callback)
38 : Thread(true), jsEngine(jsEngine), fileSystem(jsEngine->GetFileSystem()),
39 callback(callback)
40 {
41 }
42
43 protected:
44 JsEnginePtr jsEngine;
45 FileSystemPtr fileSystem;
46 JsValue callback;
47 };
48
49 class ReadThread : public IoThread
50 {
51 public:
52 ReadThread(const JsEnginePtr& jsEngine, const JsValue& callback,
53 const std::string& path)
54 : IoThread(jsEngine, callback), path(path)
55 {
56 }
57
58 void Run()
59 {
60 std::string content;
61 std::string error;
62 try
63 {
64 std::shared_ptr<std::istream> stream = fileSystem->Read(path);
65 content = Utils::Slurp(*stream);
66 }
67 catch (std::exception& e)
68 {
69 error = e.what();
70 }
71 catch (...)
72 {
73 error = "Unknown error while reading from " + path;
74 }
75
76 const JsContext context(*jsEngine);
77 auto result = jsEngine->NewObject();
78 result.SetProperty("content", content);
79 result.SetProperty("error", error);
80 JsValueList params;
81 params.push_back(result);
82 callback.Call(params);
83 }
84
85 private:
86 std::string path;
87 };
88
89 class WriteThread : public IoThread
90 {
91 public:
92 WriteThread(const JsEnginePtr& jsEngine, const JsValue& callback,
93 const std::string& path, const std::string& content)
94 : IoThread(jsEngine, callback), path(path), content(content)
95 {
96 }
97
98 void Run()
99 {
100 std::string error;
101 try
102 {
103 std::stringstream stream;
104 stream << content;
105 fileSystem->Write(path, stream);
106 }
107 catch (std::exception& e)
108 {
109 error = e.what();
110 }
111 catch (...)
112 {
113 error = "Unknown error while writing to " + path;
114 }
115
116 const JsContext context(*jsEngine);
117 auto errorValue = jsEngine->NewValue(error);
118 JsValueList params;
119 params.push_back(errorValue);
120 callback.Call(params);
121 }
122
123 private:
124 std::string path;
125 std::string content;
126 };
127
128 class MoveThread : public IoThread
129 {
130 public:
131 MoveThread(const JsEnginePtr& jsEngine, const JsValue& callback,
132 const std::string& fromPath, const std::string& toPath)
133 : IoThread(jsEngine, callback), fromPath(fromPath), toPath(toPath)
134 {
135 }
136
137 void Run()
138 {
139 std::string error;
140 try
141 {
142 fileSystem->Move(fromPath, toPath);
143 }
144 catch (std::exception& e)
145 {
146 error = e.what();
147 }
148 catch (...)
149 {
150 error = "Unknown error while moving " + fromPath + " to " + toPath;
151 }
152
153 const JsContext context(*jsEngine);
154 auto errorValue = jsEngine->NewValue(error);
155 JsValueList params;
156 params.push_back(errorValue);
157 callback.Call(params);
158 }
159
160 private:
161 std::string fromPath;
162 std::string toPath;
163 };
164
165 class RemoveThread : public IoThread
166 {
167 public:
168 RemoveThread(const JsEnginePtr& jsEngine, const JsValue& callback,
169 const std::string& path)
170 : IoThread(jsEngine, callback), path(path)
171 {
172 }
173
174 void Run()
175 {
176 std::string error;
177 try
178 {
179 fileSystem->Remove(path);
180 }
181 catch (std::exception& e)
182 {
183 error = e.what();
184 }
185 catch (...)
186 {
187 error = "Unknown error while removing " + path;
188 }
189
190 const JsContext context(*jsEngine);
191 auto errorValue = jsEngine->NewValue(error);
192 JsValueList params;
193 params.push_back(errorValue);
194 callback.Call(params);
195 }
196
197 private:
198 std::string path;
199 };
200
201
202 class StatThread : public IoThread
203 {
204 public:
205 StatThread(const JsEnginePtr& jsEngine, const JsValue& callback,
206 const std::string& path)
207 : IoThread(jsEngine, callback), path(path)
208 {
209 }
210
211 void Run()
212 {
213 std::string error;
214 FileSystem::StatResult statResult;
215 try
216 {
217 statResult = fileSystem->Stat(path);
218 }
219 catch (std::exception& e)
220 {
221 error = e.what();
222 }
223 catch (...)
224 {
225 error = "Unknown error while calling stat on " + path;
226 }
227
228 const JsContext context(*jsEngine);
229 auto result = jsEngine->NewObject();
230 result.SetProperty("exists", statResult.exists);
231 result.SetProperty("isFile", statResult.isFile);
232 result.SetProperty("isDirectory", statResult.isDirectory);
233 result.SetProperty("lastModified", statResult.lastModified);
234 result.SetProperty("error", error);
235
236 JsValueList params;
237 params.push_back(result);
238 callback.Call(params);
239 }
240
241 private:
242 std::string path;
243 };
244
245 void ReadCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 33 void ReadCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
246 { 34 {
247 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 35 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
248 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 36 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
249 37
250 v8::Isolate* isolate = arguments.GetIsolate(); 38 v8::Isolate* isolate = arguments.GetIsolate();
251 if (converted.size() != 2) 39 if (converted.size() != 2)
252 return ThrowExceptionInJS(isolate, "_fileSystem.read requires 2 parameters "); 40 return ThrowExceptionInJS(isolate, "_fileSystem.read requires 2 parameters ");
253 if (!converted[1].IsFunction()) 41 if (!converted[1].IsFunction())
254 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.read mu st be a function"); 42 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.read mu st be a function");
255 ReadThread* const readThread = new ReadThread(jsEngine, converted[1], 43
256 converted[0].AsString()); 44 JsValueList values;
257 readThread->Start(); 45 values.push_back(converted[1]);
46 auto weakCallback = jsEngine->StoreJsValues(values);
47 std::weak_ptr<JsEngine> weakJsEngine = jsEngine;
48 jsEngine->GetAsyncFileSystem()->Read(converted[0].AsString(),
49 [weakJsEngine, weakCallback]
50 (std::string&& content, const std::string& error)
51 {
52 auto jsEngine = weakJsEngine.lock();
53 if (!jsEngine)
54 return;
55
56 const JsContext context(*jsEngine);
57 auto result = jsEngine->NewObject();
58 result.SetProperty("content", std::move(content));
59 if (!error.empty())
60 result.SetProperty("error", error);
61 jsEngine->TakeJsValues(weakCallback)[0].Call(result);
62 });
258 } 63 }
259 64
260 void WriteCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 65 void WriteCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
261 { 66 {
262 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 67 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
263 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 68 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
264 69
265 v8::Isolate* isolate = arguments.GetIsolate(); 70 v8::Isolate* isolate = arguments.GetIsolate();
266 if (converted.size() != 3) 71 if (converted.size() != 3)
267 return ThrowExceptionInJS(isolate, "_fileSystem.write requires 3 parameter s"); 72 return ThrowExceptionInJS(isolate, "_fileSystem.write requires 3 parameter s");
268 if (!converted[2].IsFunction()) 73 if (!converted[2].IsFunction())
269 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.write mu st be a function"); 74 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.write mu st be a function");
270 WriteThread* const writeThread = new WriteThread(jsEngine, converted[2], 75
271 converted[0].AsString(), converted[1].AsString()); 76 JsValueList values;
272 writeThread->Start(); 77 values.push_back(converted[2]);
78 auto weakCallback = jsEngine->StoreJsValues(values);
79 std::weak_ptr<JsEngine> weakJsEngine = jsEngine;
80 jsEngine->GetAsyncFileSystem()->Write(converted[0].AsString(),
81 converted[1].AsString(),
82 [weakJsEngine, weakCallback](const std::string& error)
83 {
84 auto jsEngine = weakJsEngine.lock();
85 if (!jsEngine)
86 return;
87
88 const JsContext context(*jsEngine);
89 JsValueList params;
90 if (!error.empty())
91 params.push_back(jsEngine->NewValue(error));
92 jsEngine->TakeJsValues(weakCallback)[0].Call(params);
93 });
273 } 94 }
274 95
275 void MoveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 96 void MoveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
276 { 97 {
277 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 98 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
278 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 99 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
279 100
280 v8::Isolate* isolate = arguments.GetIsolate(); 101 v8::Isolate* isolate = arguments.GetIsolate();
281 if (converted.size() != 3) 102 if (converted.size() != 3)
282 return ThrowExceptionInJS(isolate, "_fileSystem.move requires 3 parameters "); 103 return ThrowExceptionInJS(isolate, "_fileSystem.move requires 3 parameters ");
283 if (!converted[2].IsFunction()) 104 if (!converted[2].IsFunction())
284 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.move mus t be a function"); 105 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.move mus t be a function");
285 MoveThread* const moveThread = new MoveThread(jsEngine, converted[2], 106
286 converted[0].AsString(), converted[1].AsString()); 107 JsValueList values;
287 moveThread->Start(); 108 values.push_back(converted[2]);
109 auto weakCallback = jsEngine->StoreJsValues(values);
110 std::weak_ptr<JsEngine> weakJsEngine = jsEngine;
111 jsEngine->GetAsyncFileSystem()->Move(converted[0].AsString(),
112 converted[1].AsString(),
113 [weakJsEngine, weakCallback](const std::string& error)
114 {
115 auto jsEngine = weakJsEngine.lock();
116 if (!jsEngine)
117 return;
118
119 const JsContext context(*jsEngine);
120 JsValueList params;
121 if (!error.empty())
122 params.push_back(jsEngine->NewValue(error));
123 jsEngine->TakeJsValues(weakCallback)[0].Call(params);
124 });
288 } 125 }
289 126
290 void RemoveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 127 void RemoveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
291 { 128 {
292 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 129 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
293 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 130 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
294 131
295 v8::Isolate* isolate = arguments.GetIsolate(); 132 v8::Isolate* isolate = arguments.GetIsolate();
296 if (converted.size() != 2) 133 if (converted.size() != 2)
297 return ThrowExceptionInJS(isolate, "_fileSystem.remove requires 2 paramete rs"); 134 return ThrowExceptionInJS(isolate, "_fileSystem.remove requires 2 paramete rs");
298 if (!converted[1].IsFunction()) 135 if (!converted[1].IsFunction())
299 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.remove must be a function"); 136 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.remove must be a function");
300 RemoveThread* const removeThread = new RemoveThread(jsEngine, converted[1], 137
301 converted[0].AsString()); 138 JsValueList values;
302 removeThread->Start(); 139 values.push_back(converted[1]);
140 auto weakCallback = jsEngine->StoreJsValues(values);
141 std::weak_ptr<JsEngine> weakJsEngine = jsEngine;
142 jsEngine->GetAsyncFileSystem()->Remove(converted[0].AsString(),
143 [weakJsEngine, weakCallback](const std::string& error)
144 {
145 auto jsEngine = weakJsEngine.lock();
146 if (!jsEngine)
147 return;
148
149 const JsContext context(*jsEngine);
150 JsValueList params;
151 if (!error.empty())
152 params.push_back(jsEngine->NewValue(error));
153 jsEngine->TakeJsValues(weakCallback)[0].Call(params);
154 });
303 } 155 }
304 156
305 void StatCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 157 void StatCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
306 { 158 {
307 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 159 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
308 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 160 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
309 161
310 v8::Isolate* isolate = arguments.GetIsolate(); 162 v8::Isolate* isolate = arguments.GetIsolate();
311 if (converted.size() != 2) 163 if (converted.size() != 2)
312 return ThrowExceptionInJS(isolate, "_fileSystem.stat requires 2 parameters "); 164 return ThrowExceptionInJS(isolate, "_fileSystem.stat requires 2 parameters ");
313 if (!converted[1].IsFunction()) 165 if (!converted[1].IsFunction())
314 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.stat mu st be a function"); 166 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.stat mu st be a function");
315 StatThread* const statThread = new StatThread(jsEngine, converted[1], 167
316 converted[0].AsString()); 168 JsValueList values;
317 statThread->Start(); 169 values.push_back(converted[1]);
170 auto weakCallback = jsEngine->StoreJsValues(values);
171 std::weak_ptr<JsEngine> weakJsEngine = jsEngine;
172 jsEngine->GetAsyncFileSystem()->Stat(converted[0].AsString(),
173 [weakJsEngine, weakCallback]
174 (const IFileSystem::StatResult& statResult, const std::string& error)
175 {
176 auto jsEngine = weakJsEngine.lock();
177 if (!jsEngine)
178 return;
179
180 const JsContext context(*jsEngine);
181 auto result = jsEngine->NewObject();
182
183 result.SetProperty("exists", statResult.exists);
184 result.SetProperty("isFile", statResult.isFile);
185 result.SetProperty("isDirectory", statResult.isDirectory);
186 result.SetProperty("lastModified", statResult.lastModified);
187 if (!error.empty())
188 result.SetProperty("error", error);
189
190 JsValueList params;
191 params.push_back(result);
192 jsEngine->TakeJsValues(weakCallback)[0].Call(params);
193 });
318 } 194 }
319 195
320 void ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 196 void ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
321 { 197 {
322 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 198 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
323 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 199 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
324 200
325 v8::Isolate* isolate = arguments.GetIsolate(); 201 v8::Isolate* isolate = arguments.GetIsolate();
326 if (converted.size() != 1) 202 if (converted.size() != 1)
327 return ThrowExceptionInJS(isolate, "_fileSystem.resolve requires 1 paramet er"); 203 return ThrowExceptionInJS(isolate, "_fileSystem.resolve requires 1 paramet er");
328 204
329 std::string resolved = jsEngine->GetFileSystem()->Resolve(converted[0].AsStr ing()); 205 std::string resolved = jsEngine->GetAsyncFileSystem()->Resolve(converted[0]. AsString());
330 arguments.GetReturnValue().Set(Utils::ToV8String(isolate, resolved)); 206 arguments.GetReturnValue().Set(Utils::ToV8String(isolate, resolved));
331 } 207 }
332 } 208 }
333 209
334 210
335 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj) 211 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj)
336 { 212 {
337 obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback)); 213 obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback));
338 obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback)); 214 obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback));
339 obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback)); 215 obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback));
340 obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback)); 216 obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback));
341 obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback)); 217 obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback));
342 obj.SetProperty("resolve", jsEngine.NewCallback(::ResolveCallback)); 218 obj.SetProperty("resolve", jsEngine.NewCallback(::ResolveCallback));
343 return obj; 219 return obj;
344 } 220 }
OLDNEW
« no previous file with comments | « src/FileSystemJsObject.h ('k') | src/FilterEngine.cpp » ('j') | src/FilterEngine.cpp » ('J')

Powered by Google App Engine
This is Rietveld