| 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 |