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

Powered by Google App Engine
This is Rietveld