Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: src/FileSystemJsObject.cpp

Issue 10296001: Implement File API (Closed)
Patch Set: Addressed all remaining issues Created April 16, 2013, 11:55 a.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
(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 }
OLDNEW
« src/DefaultFileSystem.cpp ('K') | « src/FileSystemJsObject.h ('k') | src/GlobalJsObject.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld