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