Left: | ||
Right: |
OLD | NEW |
---|---|
(Empty) | |
1 #include <AdblockPlus/FileSystem.h> | |
2 #include <stdexcept> | |
3 #include <sstream> | |
4 #include <vector> | |
5 | |
6 #include "FileSystemJsObject.h" | |
7 #include "Utils.h" | |
8 #include "Thread.h" | |
9 #include "Utils.h" | |
10 | |
11 using namespace AdblockPlus; | |
12 | |
13 namespace | |
14 { | |
15 class IoThread : public Thread | |
16 { | |
17 public: | |
18 IoThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback) | |
19 : isolate(v8::Isolate::GetCurrent()), | |
20 context(v8::Persistent<v8::Context>::New(isolate, | |
21 v8::Context::GetCurrent())), | |
22 fileSystem(fileSystem), | |
23 callback(v8::Persistent<v8::Function>::New(isolate, callback)) | |
24 { | |
25 } | |
26 | |
27 virtual ~IoThread() | |
28 { | |
29 callback.Dispose(isolate); | |
30 context.Dispose(isolate); | |
31 } | |
32 | |
33 protected: | |
34 v8::Isolate* const isolate; | |
35 v8::Persistent<v8::Context> context; | |
36 FileSystem& fileSystem; | |
37 v8::Persistent<v8::Function> callback; | |
38 }; | |
39 | |
40 class ReadThread : public IoThread | |
41 { | |
42 public: | |
43 ReadThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
44 const std::string& path) | |
45 : IoThread(fileSystem, callback), path(path) | |
46 { | |
47 } | |
48 | |
49 void Run() | |
50 { | |
51 std::string content; | |
52 std::string error; | |
53 try | |
54 { | |
55 std::tr1::shared_ptr<std::istream> stream = fileSystem.Read(path); | |
56 content = Utils::Slurp(*stream); | |
57 } | |
58 catch (std::exception& e) | |
59 { | |
60 error = e.what(); | |
61 } | |
62 catch (...) | |
63 { | |
64 error = "Unknown error while reading from " + path; | |
65 } | |
66 | |
67 const v8::Locker locker(isolate); | |
68 const v8::HandleScope handleScope; | |
69 const v8::Context::Scope contextScope(context); | |
70 v8::Handle<v8::Object> result = v8::Object::New(); | |
71 result->Set(v8::String::New("content"), Utils::ToV8String(content)); | |
72 result->Set(v8::String::New("error"), Utils::ToV8String(error)); | |
73 callback->Call(callback, 1, | |
74 reinterpret_cast<v8::Handle<v8::Value>*>(&result)); | |
75 delete this; | |
76 } | |
77 | |
78 private: | |
79 std::string path; | |
80 }; | |
81 | |
82 class WriteThread : public IoThread | |
83 { | |
84 public: | |
85 WriteThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
86 const std::string& path, const std::string& content) | |
87 : IoThread(fileSystem, callback), path(path), content(content) | |
88 { | |
89 } | |
90 | |
91 void Run() | |
92 { | |
93 std::string error; | |
94 try | |
95 { | |
96 std::tr1::shared_ptr<std::ostream> stream(new std::stringstream); | |
97 *stream << content; | |
98 fileSystem.Write(path, stream); | |
99 } | |
100 catch (std::exception& e) | |
101 { | |
102 error = e.what(); | |
103 } | |
104 catch (...) | |
105 { | |
106 error = "Unknown error while writing to " + path; | |
107 } | |
108 | |
109 const v8::Locker locker(isolate); | |
110 const v8::HandleScope handleScope; | |
111 const v8::Context::Scope contextScope(context); | |
112 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error); | |
113 callback->Call(callback, 1, &errorValue); | |
114 delete this; | |
115 } | |
116 | |
117 private: | |
118 std::string path; | |
119 std::string content; | |
120 }; | |
121 | |
122 class MoveThread : public IoThread | |
123 { | |
124 public: | |
125 MoveThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
126 const std::string& fromPath, const std::string& toPath) | |
127 : IoThread(fileSystem, callback), fromPath(fromPath), toPath(toPath) | |
128 { | |
129 } | |
130 | |
131 void Run() | |
132 { | |
133 std::string error; | |
134 try | |
135 { | |
136 fileSystem.Move(fromPath, toPath); | |
137 } | |
138 catch (std::exception& e) | |
139 { | |
140 error = e.what(); | |
141 } | |
142 catch (...) | |
143 { | |
144 error = "Unknown error while moving " + fromPath + " to " + toPath; | |
145 } | |
146 | |
147 const v8::Locker locker(isolate); | |
148 const v8::HandleScope handleScope; | |
149 const v8::Context::Scope contextScope(context); | |
150 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error); | |
151 callback->Call(callback, 1, &errorValue); | |
152 delete this; | |
153 } | |
154 | |
155 private: | |
156 std::string fromPath; | |
157 std::string toPath; | |
158 }; | |
159 | |
160 class RemoveThread : public IoThread | |
161 { | |
162 public: | |
163 RemoveThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
164 const std::string& path) | |
165 : IoThread(fileSystem, callback), path(path) | |
166 { | |
167 } | |
168 | |
169 void Run() | |
170 { | |
171 std::string error; | |
172 try | |
173 { | |
174 fileSystem.Remove(path); | |
175 } | |
176 catch (std::exception& e) | |
177 { | |
178 error = e.what(); | |
179 } | |
180 catch (...) | |
181 { | |
182 error = "Unknown error while removing " + path; | |
183 } | |
184 | |
185 const v8::Locker locker(isolate); | |
186 const v8::HandleScope handleScope; | |
187 const v8::Context::Scope contextScope(context); | |
188 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error); | |
189 callback->Call(callback, 1, &errorValue); | |
190 delete this; | |
191 } | |
192 | |
193 private: | |
194 std::string path; | |
195 }; | |
196 | |
197 class StatThread : public IoThread | |
198 { | |
199 public: | |
200 StatThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
201 const std::string& path) | |
202 : IoThread(fileSystem, callback), path(path) | |
203 { | |
204 } | |
205 | |
206 void Run() | |
207 { | |
208 std::string error; | |
209 FileSystem::StatResult statResult; | |
210 try | |
211 { | |
212 statResult = fileSystem.Stat(path); | |
213 } | |
214 catch (std::exception& e) | |
215 { | |
216 error = e.what(); | |
217 } | |
218 catch (...) | |
219 { | |
220 error = "Unknown error while calling stat on " + path; | |
221 } | |
222 | |
223 const v8::Locker locker(isolate); | |
224 const v8::HandleScope handleScope; | |
225 const v8::Context::Scope contextScope(context); | |
226 v8::Handle<v8::Object> result = v8::Object::New(); | |
227 result->Set(v8::String::New("exists"), | |
228 v8::Boolean::New(statResult.exists)); | |
229 result->Set(v8::String::New("isFile"), | |
230 v8::Boolean::New(statResult.isFile)); | |
231 result->Set(v8::String::New("isDirectory"), | |
232 v8::Boolean::New(statResult.isDirectory)); | |
233 result->Set(v8::String::New("lastModified"), | |
234 v8::Integer::New(statResult.lastModified)); | |
235 result->Set(v8::String::New("error"), Utils::ToV8String(error)); | |
236 callback->Call(callback, 1, | |
237 reinterpret_cast<v8::Handle<v8::Value>*>(&result)); | |
238 delete this; | |
239 } | |
240 | |
241 private: | |
242 std::string path; | |
243 }; | |
244 | |
245 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) | |
246 { | |
247 const v8::Handle<const v8::External> external = | |
248 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
249 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
250 if (!arguments.Length() == 2) | |
Wladimir Palant
2013/04/16 13:03:41
Does this actually work? :)
arguments.Length() !=
Felix Dahlke
2013/04/16 14:00:09
lol, yeah it does, but it sure is weird :) Fixed i
Wladimir Palant
2013/04/16 14:10:13
Weird operator precedence rules then...
| |
251 return v8::ThrowException(v8::String::New( | |
252 "_fileSystem.read requires 2 parameters")); | |
253 const std::string path = Utils::FromV8String(arguments[0]); | |
254 v8::Handle<v8::Value> callbackValue = arguments[1]; | |
255 if (!callbackValue->IsFunction()) | |
256 return v8::ThrowException(v8::String::New( | |
257 "Second argument to _fileSystem.read must be a function")); | |
258 v8::Handle<v8::Function> callback = | |
259 v8::Handle<v8::Function>::Cast(callbackValue); | |
260 ReadThread* const readThread = new ReadThread(*fileSystem, callback, path); | |
261 readThread->Start(); | |
262 return v8::Undefined(); | |
263 } | |
264 | |
265 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) | |
266 { | |
267 const v8::Handle<const v8::External> external = | |
268 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
269 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
270 if (!arguments.Length() == 3) | |
271 return v8::ThrowException(v8::String::New( | |
272 "_fileSystem.write requires 3 parameters")); | |
273 const std::string path = Utils::FromV8String(arguments[0]); | |
274 const std::string content = Utils::FromV8String(arguments[1]); | |
275 v8::Handle<v8::Value> callbackValue = arguments[2]; | |
276 if (!callbackValue->IsFunction()) | |
277 return v8::ThrowException(v8::String::New( | |
278 "Third argument to _fileSystem.write must be a function")); | |
279 v8::Handle<v8::Function> callback = | |
280 v8::Handle<v8::Function>::Cast(callbackValue); | |
281 WriteThread* const writeThread = new WriteThread(*fileSystem, callback, | |
282 path, content); | |
283 writeThread->Start(); | |
284 return v8::Undefined(); | |
285 } | |
286 | |
287 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) | |
288 { | |
289 const v8::Handle<const v8::External> external = | |
290 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
291 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
292 if (!arguments.Length() == 3) | |
293 return v8::ThrowException(v8::String::New( | |
294 "_fileSystem.move requires 3 parameters")); | |
295 const std::string fromPath = Utils::FromV8String(arguments[0]); | |
296 const std::string toPath = Utils::FromV8String(arguments[1]); | |
297 v8::Handle<v8::Value> callbackValue = arguments[2]; | |
298 if (!callbackValue->IsFunction()) | |
299 return v8::ThrowException(v8::String::New( | |
300 "Third argument to _fileSystem.move must be a function")); | |
301 v8::Handle<v8::Function> callback = | |
302 v8::Handle<v8::Function>::Cast(callbackValue); | |
303 MoveThread* const moveThread = new MoveThread(*fileSystem, callback, | |
304 fromPath, toPath); | |
305 moveThread->Start(); | |
306 return v8::Undefined(); | |
307 } | |
308 | |
309 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) | |
310 { | |
311 const v8::Handle<const v8::External> external = | |
312 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
313 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
314 if (!arguments.Length() == 2) | |
315 return v8::ThrowException(v8::String::New( | |
316 "_fileSystem.remove requires 2 parameters")); | |
317 const std::string path = Utils::FromV8String(arguments[0]); | |
318 v8::Handle<v8::Value> callbackValue = arguments[1]; | |
319 if (!callbackValue->IsFunction()) | |
320 return v8::ThrowException(v8::String::New( | |
321 "Second argument to _fileSystem.remove must be a function")); | |
322 v8::Handle<v8::Function> callback = | |
323 v8::Handle<v8::Function>::Cast(callbackValue); | |
324 RemoveThread* const removeThread = new RemoveThread(*fileSystem, callback, | |
325 path); | |
326 removeThread->Start(); | |
327 return v8::Undefined(); | |
328 } | |
329 | |
330 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) | |
331 { | |
332 const v8::Handle<const v8::External> external = | |
333 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
334 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
335 if (!arguments.Length() == 2) | |
336 return v8::ThrowException(v8::String::New( | |
337 "_fileSystem.stat requires 2 parameters")); | |
338 const std::string path = Utils::FromV8String(arguments[0]); | |
339 v8::Handle<v8::Value> callbackValue = arguments[1]; | |
340 if (!callbackValue->IsFunction()) | |
341 return v8::ThrowException(v8::String::New( | |
342 "Second argument to _fileSystem.stat must be a function")); | |
343 v8::Handle<v8::Function> callback = | |
344 v8::Handle<v8::Function>::Cast(callbackValue); | |
345 StatThread* const statThread = new StatThread(*fileSystem, callback, path); | |
346 statThread->Start(); | |
347 return v8::Undefined(); | |
348 } | |
349 } | |
350 | |
351 v8::Handle<v8::ObjectTemplate> | |
352 FileSystemJsObject::Create(FileSystem& fileSystem) | |
353 { | |
354 const v8::Locker locker(v8::Isolate::GetCurrent()); | |
355 v8::HandleScope handleScope; | |
356 const v8::Handle<v8::ObjectTemplate> file = v8::ObjectTemplate::New(); | |
357 const v8::Local<v8::External> fileSystemExternal = | |
358 v8::External::New(&fileSystem); | |
359 file->Set(v8::String::New("read"), | |
360 v8::FunctionTemplate::New(ReadCallback, fileSystemExternal)); | |
361 file->Set(v8::String::New("write"), | |
362 v8::FunctionTemplate::New(WriteCallback, fileSystemExternal)); | |
363 file->Set(v8::String::New("move"), | |
364 v8::FunctionTemplate::New(MoveCallback, fileSystemExternal)); | |
365 file->Set(v8::String::New("remove"), | |
366 v8::FunctionTemplate::New(RemoveCallback, fileSystemExternal)); | |
367 file->Set(v8::String::New("stat"), | |
368 v8::FunctionTemplate::New(StatCallback, fileSystemExternal)); | |
369 return handleScope.Close(file); | |
370 } | |
OLD | NEW |