Left: | ||
Right: |
OLD | NEW |
---|---|
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 Loading... | |
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 } |
OLD | NEW |