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::auto_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 fileSystem.Write(path, content); | |
97 } | |
98 catch (std::exception& e) | |
99 { | |
100 error = e.what(); | |
101 } | |
102 catch (...) | |
103 { | |
104 error = "Unknown error while writing to " + path; | |
105 } | |
106 | |
107 const v8::Locker locker(isolate); | |
108 const v8::HandleScope handleScope; | |
109 const v8::Context::Scope contextScope(context); | |
110 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error); | |
111 callback->Call(callback, 1, &errorValue); | |
112 delete this; | |
113 } | |
114 | |
115 private: | |
116 std::string path; | |
117 std::string content; | |
118 }; | |
119 | |
120 class MoveThread : public IoThread | |
121 { | |
122 public: | |
123 MoveThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
124 const std::string& fromPath, const std::string& toPath) | |
125 : IoThread(fileSystem, callback), fromPath(fromPath), toPath(toPath) | |
126 { | |
127 } | |
128 | |
129 void Run() | |
130 { | |
131 std::string error; | |
132 try | |
133 { | |
134 fileSystem.Move(fromPath, toPath); | |
135 } | |
136 catch (std::exception& e) | |
137 { | |
138 error = e.what(); | |
139 } | |
140 catch (...) | |
141 { | |
142 error = "Unknown error while moving " + fromPath + " to " + toPath; | |
143 } | |
144 | |
145 const v8::Locker locker(isolate); | |
146 const v8::HandleScope handleScope; | |
147 const v8::Context::Scope contextScope(context); | |
148 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error); | |
149 callback->Call(callback, 1, &errorValue); | |
150 delete this; | |
151 } | |
152 | |
153 private: | |
154 std::string fromPath; | |
155 std::string toPath; | |
156 }; | |
157 | |
158 class RemoveThread : public IoThread | |
159 { | |
160 public: | |
161 RemoveThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
162 const std::string& path) | |
163 : IoThread(fileSystem, callback), path(path) | |
164 { | |
165 } | |
166 | |
167 void Run() | |
168 { | |
169 std::string error; | |
170 try | |
171 { | |
172 fileSystem.Remove(path); | |
173 } | |
174 catch (std::exception& e) | |
175 { | |
176 error = e.what(); | |
177 } | |
178 catch (...) | |
179 { | |
180 error = "Unknown error while removing " + path; | |
181 } | |
182 | |
183 const v8::Locker locker(isolate); | |
184 const v8::HandleScope handleScope; | |
185 const v8::Context::Scope contextScope(context); | |
186 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error); | |
187 callback->Call(callback, 1, &errorValue); | |
188 delete this; | |
189 } | |
190 | |
191 private: | |
192 std::string path; | |
193 }; | |
194 | |
195 class StatThread : public IoThread | |
196 { | |
197 public: | |
198 StatThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback, | |
199 const std::string& path) | |
200 : IoThread(fileSystem, callback), path(path) | |
201 { | |
202 } | |
203 | |
204 void Run() | |
205 { | |
206 std::string error; | |
207 FileSystem::StatResult statResult; | |
208 try | |
209 { | |
210 statResult = fileSystem.Stat(path); | |
211 } | |
212 catch (std::exception& e) | |
213 { | |
214 error = e.what(); | |
215 } | |
216 catch (...) | |
217 { | |
218 error = "Unknown error while calling stat on " + path; | |
219 } | |
220 | |
221 const v8::Locker locker(isolate); | |
222 const v8::HandleScope handleScope; | |
223 const v8::Context::Scope contextScope(context); | |
224 v8::Handle<v8::Object> result = v8::Object::New(); | |
225 result->Set(v8::String::New("exists"), | |
226 v8::Boolean::New(statResult.exists)); | |
227 result->Set(v8::String::New("isFile"), | |
228 v8::Boolean::New(statResult.isFile)); | |
229 result->Set(v8::String::New("isDirectory"), | |
230 v8::Boolean::New(statResult.isDirectory)); | |
231 result->Set(v8::String::New("lastModified"), | |
232 v8::Integer::New(statResult.lastModified)); | |
233 result->Set(v8::String::New("error"), Utils::ToV8String(error)); | |
234 callback->Call(callback, 1, | |
235 reinterpret_cast<v8::Handle<v8::Value>*>(&result)); | |
236 delete this; | |
237 } | |
238 | |
239 private: | |
240 std::string path; | |
241 }; | |
242 | |
243 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) | |
244 { | |
245 std::vector<std::string> requiredTypes; | |
246 requiredTypes.push_back("string"); | |
247 requiredTypes.push_back("function"); | |
Wladimir Palant
2013/04/16 06:50:13
requiredTypes is no longer used - and arguments.Le
| |
248 v8::TryCatch tryCatch; | |
Wladimir Palant
2013/04/16 06:50:13
If you are using TryCatch then you might want to b
| |
249 const v8::Handle<const v8::External> external = | |
250 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
251 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
252 const std::string path = Utils::FromV8String(arguments[0]); | |
253 v8::Handle<v8::Value> callbackValue = arguments[1]; | |
254 if (!callbackValue->IsFunction()) | |
255 return v8::ThrowException(v8::String::New( | |
256 "Second argument to _fileSystem.read must be a function")); | |
257 v8::Handle<v8::Function> callback = | |
258 v8::Handle<v8::Function>::Cast(callbackValue); | |
259 ReadThread* const readThread = new ReadThread(*fileSystem, callback, path); | |
260 readThread->Start(); | |
261 if (tryCatch.HasCaught()) | |
262 return tryCatch.Exception(); | |
263 return v8::Undefined(); | |
264 } | |
265 | |
266 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) | |
267 { | |
268 const v8::Handle<const v8::External> external = | |
269 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
270 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
271 const std::string path = Utils::FromV8String(arguments[0]); | |
272 const std::string content = Utils::FromV8String(arguments[1]); | |
273 v8::Handle<v8::Value> callbackValue = arguments[2]; | |
274 if (!callbackValue->IsFunction()) | |
275 return v8::ThrowException(v8::String::New( | |
276 "Third argument to _fileSystem.write must be a function")); | |
277 v8::Handle<v8::Function> callback = | |
278 v8::Handle<v8::Function>::Cast(callbackValue); | |
279 WriteThread* const writeThread = new WriteThread(*fileSystem, callback, | |
280 path, content); | |
281 writeThread->Start(); | |
282 return v8::Undefined(); | |
283 } | |
284 | |
285 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) | |
286 { | |
287 const v8::Handle<const v8::External> external = | |
288 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
289 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
290 const std::string fromPath = Utils::FromV8String(arguments[0]); | |
291 const std::string toPath = Utils::FromV8String(arguments[1]); | |
292 v8::Handle<v8::Value> callbackValue = arguments[2]; | |
293 if (!callbackValue->IsFunction()) | |
294 return v8::ThrowException(v8::String::New( | |
295 "Third argument to _fileSystem.move must be a function")); | |
296 v8::Handle<v8::Function> callback = | |
297 v8::Handle<v8::Function>::Cast(callbackValue); | |
298 MoveThread* const moveThread = new MoveThread(*fileSystem, callback, | |
299 fromPath, toPath); | |
300 moveThread->Start(); | |
301 return v8::Undefined(); | |
302 } | |
303 | |
304 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) | |
305 { | |
306 const v8::Handle<const v8::External> external = | |
307 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
308 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
309 const std::string path = Utils::FromV8String(arguments[0]); | |
310 v8::Handle<v8::Value> callbackValue = arguments[1]; | |
311 if (!callbackValue->IsFunction()) | |
312 return v8::ThrowException(v8::String::New( | |
313 "Second argument to _fileSystem.remove must be a function")); | |
314 v8::Handle<v8::Function> callback = | |
315 v8::Handle<v8::Function>::Cast(callbackValue); | |
316 RemoveThread* const removeThread = new RemoveThread(*fileSystem, callback, | |
317 path); | |
318 removeThread->Start(); | |
319 return v8::Undefined(); | |
320 } | |
321 | |
322 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) | |
323 { | |
324 const v8::Handle<const v8::External> external = | |
325 v8::Handle<const v8::External>::Cast(arguments.Data()); | |
326 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); | |
327 const std::string path = Utils::FromV8String(arguments[0]); | |
328 v8::Handle<v8::Value> callbackValue = arguments[1]; | |
329 if (!callbackValue->IsFunction()) | |
330 return v8::ThrowException(v8::String::New( | |
331 "Second argument to _fileSystem.stat must be a function")); | |
332 v8::Handle<v8::Function> callback = | |
333 v8::Handle<v8::Function>::Cast(callbackValue); | |
334 StatThread* const statThread = new StatThread(*fileSystem, callback, path); | |
335 statThread->Start(); | |
336 return v8::Undefined(); | |
337 } | |
338 } | |
339 | |
340 v8::Handle<v8::ObjectTemplate> | |
341 FileSystemJsObject::Create(FileSystem& fileSystem) | |
342 { | |
343 const v8::Locker locker(v8::Isolate::GetCurrent()); | |
344 v8::HandleScope handleScope; | |
345 const v8::Handle<v8::ObjectTemplate> file = v8::ObjectTemplate::New(); | |
346 const v8::Local<v8::External> fileSystemExternal = | |
347 v8::External::New(&fileSystem); | |
348 file->Set(v8::String::New("read"), | |
349 v8::FunctionTemplate::New(ReadCallback, fileSystemExternal)); | |
350 file->Set(v8::String::New("write"), | |
351 v8::FunctionTemplate::New(WriteCallback, fileSystemExternal)); | |
352 file->Set(v8::String::New("move"), | |
353 v8::FunctionTemplate::New(MoveCallback, fileSystemExternal)); | |
354 file->Set(v8::String::New("remove"), | |
355 v8::FunctionTemplate::New(RemoveCallback, fileSystemExternal)); | |
356 file->Set(v8::String::New("stat"), | |
357 v8::FunctionTemplate::New(StatCallback, fileSystemExternal)); | |
358 return handleScope.Close(file); | |
359 } | |
OLD | NEW |