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

Delta Between Two Patch Sets: src/FileSystemJsObject.cpp

Issue 10296001: Implement File API (Closed)
Left Patch Set: Don't pass a blog to _fileSystem.write Created April 12, 2013, 12:10 p.m.
Right Patch Set: Addressed the new issues Created April 16, 2013, 1:37 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « src/FileSystemJsObject.h ('k') | src/GlobalJsObject.h » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 #include <AdblockPlus/FileSystem.h> 1 #include <AdblockPlus/FileSystem.h>
2 #include <stdexcept> 2 #include <stdexcept>
3 #include <sstream> 3 #include <sstream>
4 #include <vector> 4 #include <vector>
5 5
6 #include "FileSystemJsObject.h" 6 #include "FileSystemJsObject.h"
7 #include "Utils.h" 7 #include "Utils.h"
8 #include "Thread.h" 8 #include "Thread.h"
9 #include "Utils.h"
9 10
10 using namespace AdblockPlus; 11 using namespace AdblockPlus;
11 12
12 namespace 13 namespace
13 { 14 {
14 class IoThread : public Thread 15 class IoThread : public Thread
15 { 16 {
16 public: 17 public:
17 IoThread(FileSystem& fileSystem, v8::Persistent<v8::Function> callback) 18 IoThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback)
Wladimir Palant 2013/04/12 16:10:35 Passing in callback like this is rather ugly - you
18 : isolate(v8::Isolate::GetCurrent()), 19 : isolate(v8::Isolate::GetCurrent()),
19 context(v8::Persistent<v8::Context>::New(isolate, 20 context(v8::Persistent<v8::Context>::New(isolate,
20 v8::Context::GetCurrent())), 21 v8::Context::GetCurrent())),
21 fileSystem(fileSystem), callback(callback) 22 fileSystem(fileSystem),
23 callback(v8::Persistent<v8::Function>::New(isolate, callback))
22 { 24 {
23 } 25 }
24 26
25 virtual ~IoThread() 27 virtual ~IoThread()
26 { 28 {
27 callback.Dispose(isolate); 29 callback.Dispose(isolate);
28 context.Dispose(isolate); 30 context.Dispose(isolate);
29 } 31 }
30 32
31 protected: 33 protected:
32 v8::Isolate* const isolate; 34 v8::Isolate* const isolate;
33 v8::Persistent<v8::Context> context; 35 v8::Persistent<v8::Context> context;
34 FileSystem& fileSystem; 36 FileSystem& fileSystem;
35 v8::Persistent<v8::Function> callback; 37 v8::Persistent<v8::Function> callback;
36 }; 38 };
37 39
38 class ReadThread : public IoThread 40 class ReadThread : public IoThread
39 { 41 {
40 public: 42 public:
41 ReadThread(FileSystem& fileSystem, v8::Persistent<v8::Function> callback, 43 ReadThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback,
42 const std::string& path) 44 const std::string& path)
43 : IoThread(fileSystem, callback), path(path) 45 : IoThread(fileSystem, callback), path(path)
44 { 46 {
45 } 47 }
46 48
47 void Run() 49 void Run()
48 { 50 {
49 std::string content; 51 std::string content;
50 std::string error; 52 std::string error;
51 try 53 try
52 { 54 {
53 std::auto_ptr<std::istream> stream = fileSystem.Read(path); 55 std::tr1::shared_ptr<std::istream> stream = fileSystem.Read(path);
54 content = Utils::Slurp(*stream); 56 content = Utils::Slurp(*stream);
55 } 57 }
56 catch (std::exception& e) 58 catch (std::exception& e)
57 { 59 {
58 error = e.what(); 60 error = e.what();
59 } 61 }
60 catch (...) 62 catch (...)
61 { 63 {
62 error = "Unknown error while reading from " + path; 64 error = "Unknown error while reading from " + path;
63 } 65 }
64 66
65 const v8::Locker locker(isolate); 67 const v8::Locker locker(isolate);
66 const v8::HandleScope handleScope; 68 const v8::HandleScope handleScope;
67 const v8::Context::Scope contextScope(context); 69 const v8::Context::Scope contextScope(context);
68 v8::Handle<v8::Object> result = v8::Object::New(); 70 v8::Handle<v8::Object> result = v8::Object::New();
69 result->Set(v8::String::New("content"), v8::String::New(content.c_str())); 71 result->Set(v8::String::New("content"), Utils::ToV8String(content));
70 result->Set(v8::String::New("error"), v8::String::New(error.c_str())); 72 result->Set(v8::String::New("error"), Utils::ToV8String(error));
Wladimir Palant 2013/04/12 16:10:35 Please always use the string length when convertin
Felix Dahlke 2013/04/15 03:43:34 Will do, I meant to add string conversion function
71 callback->Call(callback, 1, 73 callback->Call(callback, 1,
72 reinterpret_cast<v8::Handle<v8::Value>*>(&result)); 74 reinterpret_cast<v8::Handle<v8::Value>*>(&result));
73 delete this; 75 delete this;
74 } 76 }
75 77
76 private: 78 private:
77 std::string path; 79 std::string path;
78 }; 80 };
79 81
80 class WriteThread : public IoThread 82 class WriteThread : public IoThread
81 { 83 {
82 public: 84 public:
83 WriteThread(FileSystem& fileSystem, v8::Persistent<v8::Function> callback, 85 WriteThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback,
84 const std::string& path, const std::string& content) 86 const std::string& path, const std::string& content)
85 : IoThread(fileSystem, callback), path(path), content(content) 87 : IoThread(fileSystem, callback), path(path), content(content)
86 { 88 {
87 } 89 }
88 90
89 void Run() 91 void Run()
90 { 92 {
91 std::string error; 93 std::string error;
92 try 94 try
93 { 95 {
94 fileSystem.Write(path, content); 96 std::tr1::shared_ptr<std::ostream> stream(new std::stringstream);
97 *stream << content;
98 fileSystem.Write(path, stream);
95 } 99 }
96 catch (std::exception& e) 100 catch (std::exception& e)
97 { 101 {
98 error = e.what(); 102 error = e.what();
99 } 103 }
100 catch (...) 104 catch (...)
101 { 105 {
102 error = "Unknown error while writing to " + path; 106 error = "Unknown error while writing to " + path;
103 } 107 }
104 108
105 const v8::Locker locker(isolate); 109 const v8::Locker locker(isolate);
106 const v8::HandleScope handleScope; 110 const v8::HandleScope handleScope;
107 const v8::Context::Scope contextScope(context); 111 const v8::Context::Scope contextScope(context);
108 v8::Handle<v8::Value> errorValue = v8::String::New(error.c_str()); 112 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error);
109 callback->Call(callback, 1, &errorValue); 113 callback->Call(callback, 1, &errorValue);
110 delete this; 114 delete this;
111 } 115 }
112 116
113 private: 117 private:
114 std::string path; 118 std::string path;
115 std::string content; 119 std::string content;
116 }; 120 };
117 121
118 class MoveThread : public IoThread 122 class MoveThread : public IoThread
119 { 123 {
120 public: 124 public:
121 MoveThread(FileSystem& fileSystem, v8::Persistent<v8::Function> callback, 125 MoveThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback,
122 const std::string& fromPath, const std::string& toPath) 126 const std::string& fromPath, const std::string& toPath)
123 : IoThread(fileSystem, callback), fromPath(fromPath), toPath(toPath) 127 : IoThread(fileSystem, callback), fromPath(fromPath), toPath(toPath)
124 { 128 {
125 } 129 }
126 130
127 void Run() 131 void Run()
128 { 132 {
129 std::string error; 133 std::string error;
130 try 134 try
131 { 135 {
132 fileSystem.Move(fromPath, toPath); 136 fileSystem.Move(fromPath, toPath);
133 } 137 }
134 catch (std::exception& e) 138 catch (std::exception& e)
135 { 139 {
136 error = e.what(); 140 error = e.what();
137 } 141 }
138 catch (...) 142 catch (...)
139 { 143 {
140 error = "Unknown error while moving " + fromPath + " to " + toPath; 144 error = "Unknown error while moving " + fromPath + " to " + toPath;
141 } 145 }
142 146
143 const v8::Locker locker(isolate); 147 const v8::Locker locker(isolate);
144 const v8::HandleScope handleScope; 148 const v8::HandleScope handleScope;
145 const v8::Context::Scope contextScope(context); 149 const v8::Context::Scope contextScope(context);
146 v8::Handle<v8::Value> errorValue = v8::String::New(error.c_str()); 150 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error);
147 callback->Call(callback, 1, &errorValue); 151 callback->Call(callback, 1, &errorValue);
148 delete this; 152 delete this;
149 } 153 }
150 154
151 private: 155 private:
152 std::string fromPath; 156 std::string fromPath;
153 std::string toPath; 157 std::string toPath;
154 }; 158 };
155 159
156 class RemoveThread : public IoThread 160 class RemoveThread : public IoThread
157 { 161 {
158 public: 162 public:
159 RemoveThread(FileSystem& fileSystem, v8::Persistent<v8::Function> callback, 163 RemoveThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback,
160 const std::string& path) 164 const std::string& path)
161 : IoThread(fileSystem, callback), path(path) 165 : IoThread(fileSystem, callback), path(path)
162 { 166 {
163 } 167 }
164 168
165 void Run() 169 void Run()
166 { 170 {
167 std::string error; 171 std::string error;
168 try 172 try
169 { 173 {
170 fileSystem.Remove(path); 174 fileSystem.Remove(path);
171 } 175 }
172 catch (std::exception& e) 176 catch (std::exception& e)
173 { 177 {
174 error = e.what(); 178 error = e.what();
175 } 179 }
176 catch (...) 180 catch (...)
177 { 181 {
178 error = "Unknown error while removing " + path; 182 error = "Unknown error while removing " + path;
179 } 183 }
180 184
181 const v8::Locker locker(isolate); 185 const v8::Locker locker(isolate);
182 const v8::HandleScope handleScope; 186 const v8::HandleScope handleScope;
183 const v8::Context::Scope contextScope(context); 187 const v8::Context::Scope contextScope(context);
184 v8::Handle<v8::Value> errorValue = v8::String::New(error.c_str()); 188 v8::Handle<v8::Value> errorValue = Utils::ToV8String(error);
185 callback->Call(callback, 1, &errorValue); 189 callback->Call(callback, 1, &errorValue);
186 delete this; 190 delete this;
187 } 191 }
188 192
189 private: 193 private:
190 std::string path; 194 std::string path;
191 }; 195 };
192 196
193 class StatThread : public IoThread 197 class StatThread : public IoThread
194 { 198 {
195 public: 199 public:
196 StatThread(FileSystem& fileSystem, v8::Persistent<v8::Function> callback, 200 StatThread(FileSystem& fileSystem, v8::Handle<v8::Function> callback,
197 const std::string& path) 201 const std::string& path)
198 : IoThread(fileSystem, callback), path(path) 202 : IoThread(fileSystem, callback), path(path)
199 { 203 {
200 } 204 }
201 205
202 void Run() 206 void Run()
203 { 207 {
204 std::string error; 208 std::string error;
205 FileSystem::StatResult statResult; 209 FileSystem::StatResult statResult;
206 try 210 try
(...skipping 13 matching lines...) Expand all
220 const v8::HandleScope handleScope; 224 const v8::HandleScope handleScope;
221 const v8::Context::Scope contextScope(context); 225 const v8::Context::Scope contextScope(context);
222 v8::Handle<v8::Object> result = v8::Object::New(); 226 v8::Handle<v8::Object> result = v8::Object::New();
223 result->Set(v8::String::New("exists"), 227 result->Set(v8::String::New("exists"),
224 v8::Boolean::New(statResult.exists)); 228 v8::Boolean::New(statResult.exists));
225 result->Set(v8::String::New("isFile"), 229 result->Set(v8::String::New("isFile"),
226 v8::Boolean::New(statResult.isFile)); 230 v8::Boolean::New(statResult.isFile));
227 result->Set(v8::String::New("isDirectory"), 231 result->Set(v8::String::New("isDirectory"),
228 v8::Boolean::New(statResult.isDirectory)); 232 v8::Boolean::New(statResult.isDirectory));
229 result->Set(v8::String::New("lastModified"), 233 result->Set(v8::String::New("lastModified"),
230 v8::Number::New(statResult.lastModified)); 234 v8::Integer::New(statResult.lastModified));
231 result->Set(v8::String::New("error"), v8::String::New(error.c_str())); 235 result->Set(v8::String::New("error"), Utils::ToV8String(error));
232 callback->Call(callback, 1, 236 callback->Call(callback, 1,
233 reinterpret_cast<v8::Handle<v8::Value>*>(&result)); 237 reinterpret_cast<v8::Handle<v8::Value>*>(&result));
234 delete this; 238 delete this;
235 } 239 }
236 240
237 private: 241 private:
238 std::string path; 242 std::string path;
239 }; 243 };
240 244
241 std::string CheckArguments(const v8::Arguments& arguments,
242 const std::string& functionName,
Wladimir Palant 2013/04/12 16:10:35 Will arguments.Callee()->GetName() do as well?
243 const std::vector<std::string> requiredTypes)
244 {
245 const int requiredCount = requiredTypes.size();
246 if (arguments.Length() != requiredCount)
247 {
248 std::stringstream stream;
249 stream << functionName << " requires " << requiredCount
250 << (requiredCount == 1 ? " parameter" : " parameters");
251 return stream.str();
252 }
253
254 for (int i = 0; i < requiredCount; i++)
255 {
256 const v8::Handle<v8::Value> argument = arguments[i];
257 const std::string requiredType = requiredTypes[i];
258 if ((requiredType == "string" && !argument->IsString())
259 || (requiredType == "number" && !argument->IsNumber())
Wladimir Palant 2013/04/12 16:10:35 Please note that a parameter doesn't need to be a
260 || (requiredType == "function" && !argument->IsFunction()))
261 {
262 std::vector<std::string> countWords;
263 countWords.push_back("First");
264 countWords.push_back("Second");
265 countWords.push_back("Third");
266 std::stringstream stream;
267 if (i < countWords.size())
268 stream << countWords[i] << " argument";
269 else
270 stream << "Argument " << i;
Wladimir Palant 2013/04/12 16:10:35 I would opt against unnecessary complexity - pleas
271 stream << " to " << functionName << " must be a " << requiredType;
272 return stream.str();
273 }
274 }
275
276 return "";
277 }
278
279 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) 245 v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments)
280 { 246 {
281 std::vector<std::string> requiredTypes; 247 const v8::Handle<const v8::External> external =
282 requiredTypes.push_back("string"); 248 v8::Handle<const v8::External>::Cast(arguments.Data());
283 requiredTypes.push_back("function"); 249 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value());
284 const std::string error = CheckArguments(arguments, "_fileSystem.read", 250 if (arguments.Length() != 2)
285 requiredTypes); 251 return v8::ThrowException(v8::String::New(
Wladimir Palant 2013/04/12 16:10:35 Mozilla opted for a more trivial CheckArguments("s
Felix Dahlke 2013/04/15 03:43:34 I mainly introduced this to get the duplication do
286 if (error.length()) 252 "_fileSystem.read requires 2 parameters"));
287 return v8::ThrowException(v8::String::New(error.c_str())); 253 const std::string path = Utils::FromV8String(arguments[0]);
288 254 v8::Handle<v8::Value> callbackValue = arguments[1];
289 const v8::Handle<const v8::External> external = 255 if (!callbackValue->IsFunction())
290 v8::Handle<const v8::External>::Cast(arguments.Data()); 256 return v8::ThrowException(v8::String::New(
291 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); 257 "Second argument to _fileSystem.read must be a function"));
292 const std::string path = *v8::String::Utf8Value(arguments[0]->ToString()); 258 v8::Handle<v8::Function> callback =
293 v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New( 259 v8::Handle<v8::Function>::Cast(callbackValue);
294 v8::Isolate::GetCurrent(), v8::Handle<v8::Function>::Cast(arguments[1]));
295 ReadThread* const readThread = new ReadThread(*fileSystem, callback, path); 260 ReadThread* const readThread = new ReadThread(*fileSystem, callback, path);
296 readThread->Start(); 261 readThread->Start();
297 return v8::Undefined(); 262 return v8::Undefined();
298 } 263 }
299 264
300 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) 265 v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments)
301 { 266 {
302 std::vector<std::string> requiredTypes; 267 const v8::Handle<const v8::External> external =
303 requiredTypes.push_back("string"); 268 v8::Handle<const v8::External>::Cast(arguments.Data());
304 requiredTypes.push_back("string"); 269 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value());
305 requiredTypes.push_back("function"); 270 if (arguments.Length() != 3)
306 const std::string error = CheckArguments(arguments, "_fileSystem.write", 271 return v8::ThrowException(v8::String::New(
307 requiredTypes); 272 "_fileSystem.write requires 3 parameters"));
308 if (error.length()) 273 const std::string path = Utils::FromV8String(arguments[0]);
309 return v8::ThrowException(v8::String::New(error.c_str())); 274 const std::string content = Utils::FromV8String(arguments[1]);
310 275 v8::Handle<v8::Value> callbackValue = arguments[2];
311 const v8::Handle<const v8::External> external = 276 if (!callbackValue->IsFunction())
312 v8::Handle<const v8::External>::Cast(arguments.Data()); 277 return v8::ThrowException(v8::String::New(
313 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); 278 "Third argument to _fileSystem.write must be a function"));
314 const std::string path = *v8::String::Utf8Value(arguments[0]->ToString()); 279 v8::Handle<v8::Function> callback =
315 const std::string content = 280 v8::Handle<v8::Function>::Cast(callbackValue);
316 *v8::String::Utf8Value(arguments[1]->ToString());
317 v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New(
318 v8::Isolate::GetCurrent(), v8::Handle<v8::Function>::Cast(arguments[2]));
319 WriteThread* const writeThread = new WriteThread(*fileSystem, callback, 281 WriteThread* const writeThread = new WriteThread(*fileSystem, callback,
320 path, content); 282 path, content);
Wladimir Palant 2013/04/12 16:10:35 Just a thought: with the content parameter being a
321 writeThread->Start(); 283 writeThread->Start();
322 return v8::Undefined(); 284 return v8::Undefined();
323 } 285 }
324 286
325 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) 287 v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments)
326 { 288 {
327 std::vector<std::string> requiredTypes; 289 const v8::Handle<const v8::External> external =
328 requiredTypes.push_back("string"); 290 v8::Handle<const v8::External>::Cast(arguments.Data());
329 requiredTypes.push_back("string"); 291 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value());
330 requiredTypes.push_back("function"); 292 if (arguments.Length() != 3)
331 const std::string error = CheckArguments(arguments, "_fileSystem.move", 293 return v8::ThrowException(v8::String::New(
332 requiredTypes); 294 "_fileSystem.move requires 3 parameters"));
333 if (error.length()) 295 const std::string fromPath = Utils::FromV8String(arguments[0]);
334 return v8::ThrowException(v8::String::New(error.c_str())); 296 const std::string toPath = Utils::FromV8String(arguments[1]);
335 297 v8::Handle<v8::Value> callbackValue = arguments[2];
336 const v8::Handle<const v8::External> external = 298 if (!callbackValue->IsFunction())
337 v8::Handle<const v8::External>::Cast(arguments.Data()); 299 return v8::ThrowException(v8::String::New(
338 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); 300 "Third argument to _fileSystem.move must be a function"));
339 const std::string fromPath = 301 v8::Handle<v8::Function> callback =
340 *v8::String::Utf8Value(arguments[0]->ToString()); 302 v8::Handle<v8::Function>::Cast(callbackValue);
341 const std::string toPath = *v8::String::Utf8Value(arguments[1]->ToString());
342 v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New(
343 v8::Isolate::GetCurrent(), v8::Handle<v8::Function>::Cast(arguments[2]));
344 MoveThread* const moveThread = new MoveThread(*fileSystem, callback, 303 MoveThread* const moveThread = new MoveThread(*fileSystem, callback,
345 fromPath, toPath); 304 fromPath, toPath);
346 moveThread->Start(); 305 moveThread->Start();
347 return v8::Undefined(); 306 return v8::Undefined();
348 } 307 }
349 308
350 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) 309 v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments)
351 { 310 {
352 std::vector<std::string> requiredTypes; 311 const v8::Handle<const v8::External> external =
353 requiredTypes.push_back("string"); 312 v8::Handle<const v8::External>::Cast(arguments.Data());
354 requiredTypes.push_back("function"); 313 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value());
355 const std::string error = CheckArguments(arguments, "_fileSystem.remove", 314 if (arguments.Length() != 2)
356 requiredTypes); 315 return v8::ThrowException(v8::String::New(
357 if (error.length()) 316 "_fileSystem.remove requires 2 parameters"));
358 return v8::ThrowException(v8::String::New(error.c_str())); 317 const std::string path = Utils::FromV8String(arguments[0]);
359 318 v8::Handle<v8::Value> callbackValue = arguments[1];
360 const v8::Handle<const v8::External> external = 319 if (!callbackValue->IsFunction())
361 v8::Handle<const v8::External>::Cast(arguments.Data()); 320 return v8::ThrowException(v8::String::New(
362 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); 321 "Second argument to _fileSystem.remove must be a function"));
363 const std::string path = *v8::String::Utf8Value(arguments[0]->ToString()); 322 v8::Handle<v8::Function> callback =
364 v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New( 323 v8::Handle<v8::Function>::Cast(callbackValue);
365 v8::Isolate::GetCurrent(), v8::Handle<v8::Function>::Cast(arguments[1]));
366 RemoveThread* const removeThread = new RemoveThread(*fileSystem, callback, 324 RemoveThread* const removeThread = new RemoveThread(*fileSystem, callback,
367 path); 325 path);
368 removeThread->Start(); 326 removeThread->Start();
369 return v8::Undefined(); 327 return v8::Undefined();
370 } 328 }
371 329
372 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) 330 v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments)
373 { 331 {
374 std::vector<std::string> requiredTypes; 332 const v8::Handle<const v8::External> external =
375 requiredTypes.push_back("string"); 333 v8::Handle<const v8::External>::Cast(arguments.Data());
376 requiredTypes.push_back("function"); 334 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value());
377 const std::string error = CheckArguments(arguments, "_fileSystem.stat", 335 if (arguments.Length() != 2)
378 requiredTypes); 336 return v8::ThrowException(v8::String::New(
379 if (error.length()) 337 "_fileSystem.stat requires 2 parameters"));
380 return v8::ThrowException(v8::String::New(error.c_str())); 338 const std::string path = Utils::FromV8String(arguments[0]);
381 339 v8::Handle<v8::Value> callbackValue = arguments[1];
382 const v8::Handle<const v8::External> external = 340 if (!callbackValue->IsFunction())
383 v8::Handle<const v8::External>::Cast(arguments.Data()); 341 return v8::ThrowException(v8::String::New(
384 FileSystem* const fileSystem = static_cast<FileSystem*>(external->Value()); 342 "Second argument to _fileSystem.stat must be a function"));
385 const std::string path = *v8::String::Utf8Value(arguments[0]->ToString()); 343 v8::Handle<v8::Function> callback =
386 v8::Persistent<v8::Function> callback = v8::Persistent<v8::Function>::New( 344 v8::Handle<v8::Function>::Cast(callbackValue);
387 v8::Isolate::GetCurrent(), v8::Handle<v8::Function>::Cast(arguments[1]));
388 StatThread* const statThread = new StatThread(*fileSystem, callback, path); 345 StatThread* const statThread = new StatThread(*fileSystem, callback, path);
389 statThread->Start(); 346 statThread->Start();
390 return v8::Undefined(); 347 return v8::Undefined();
391 } 348 }
392 } 349 }
393 350
394 v8::Handle<v8::ObjectTemplate> 351 v8::Handle<v8::ObjectTemplate>
395 FileSystemJsObject::Create(FileSystem& fileSystem) 352 FileSystemJsObject::Create(FileSystem& fileSystem)
396 { 353 {
397 const v8::Locker locker(v8::Isolate::GetCurrent()); 354 const v8::Locker locker(v8::Isolate::GetCurrent());
398 v8::HandleScope handleScope; 355 v8::HandleScope handleScope;
399 const v8::Handle<v8::ObjectTemplate> file = v8::ObjectTemplate::New(); 356 const v8::Handle<v8::ObjectTemplate> file = v8::ObjectTemplate::New();
357 const v8::Local<v8::External> fileSystemExternal =
358 v8::External::New(&fileSystem);
400 file->Set(v8::String::New("read"), 359 file->Set(v8::String::New("read"),
401 v8::FunctionTemplate::New(ReadCallback, v8::External::New(&fileSystem))); 360 v8::FunctionTemplate::New(ReadCallback, fileSystemExternal));
Wladimir Palant 2013/04/12 16:10:35 How about using the same v8::External instance for
402 file->Set(v8::String::New("write"), 361 file->Set(v8::String::New("write"),
403 v8::FunctionTemplate::New(WriteCallback, v8::External::New(&fileSystem))); 362 v8::FunctionTemplate::New(WriteCallback, fileSystemExternal));
404 file->Set(v8::String::New("move"), 363 file->Set(v8::String::New("move"),
405 v8::FunctionTemplate::New(MoveCallback, v8::External::New(&fileSystem))); 364 v8::FunctionTemplate::New(MoveCallback, fileSystemExternal));
406 file->Set(v8::String::New("remove"), 365 file->Set(v8::String::New("remove"),
407 v8::FunctionTemplate::New(RemoveCallback, v8::External::New(&fileSystem))); 366 v8::FunctionTemplate::New(RemoveCallback, fileSystemExternal));
408 file->Set(v8::String::New("stat"), 367 file->Set(v8::String::New("stat"),
409 v8::FunctionTemplate::New(StatCallback, v8::External::New(&fileSystem))); 368 v8::FunctionTemplate::New(StatCallback, fileSystemExternal));
410 return handleScope.Close(file); 369 return handleScope.Close(file);
411 } 370 }
LEFTRIGHT

Powered by Google App Engine
This is Rietveld