| LEFT | RIGHT | 
|    1 /* |    1 /* | 
|    2  * This file is part of Adblock Plus <https://adblockplus.org/>, |    2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
|    3  * Copyright (C) 2006-2017 eyeo GmbH |    3  * Copyright (C) 2006-2017 eyeo GmbH | 
|    4  * |    4  * | 
|    5  * Adblock Plus is free software: you can redistribute it and/or modify |    5  * Adblock Plus is free software: you can redistribute it and/or modify | 
|    6  * it under the terms of the GNU General Public License version 3 as |    6  * it under the terms of the GNU General Public License version 3 as | 
|    7  * published by the Free Software Foundation. |    7  * published by the Free Software Foundation. | 
|    8  * |    8  * | 
|    9  * Adblock Plus is distributed in the hope that it will be useful, |    9  * Adblock Plus is distributed in the hope that it will be useful, | 
|   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of |   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|   12  * GNU General Public License for more details. |   12  * GNU General Public License for more details. | 
|   13  * |   13  * | 
|   14  * You should have received a copy of the GNU General Public License |   14  * You should have received a copy of the GNU General Public License | 
|   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. |   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
|   16  */ |   16  */ | 
|   17  |   17  | 
|   18 #include <AdblockPlus/FileSystem.h> |   18 #include <AdblockPlus/FileSystem.h> | 
|   19 #include <stdexcept> |   19 #include <stdexcept> | 
|   20 #include <sstream> |   20 #include <sstream> | 
|   21 #include <vector> |   21 #include <vector> | 
|   22  |   22  | 
|   23 #include <AdblockPlus/JsValue.h> |   23 #include <AdblockPlus/JsValue.h> | 
|   24 #include "FileSystemJsObject.h" |   24 #include "FileSystemJsObject.h" | 
|   25 #include "JsContext.h" |   25 #include "JsContext.h" | 
|   26 #include "Utils.h" |   26 #include "Utils.h" | 
|   27  |   27  | 
|   28 using namespace AdblockPlus; |   28 using namespace AdblockPlus; | 
 |   29 using AdblockPlus::Utils::ThrowExceptionInJS; | 
|   29  |   30  | 
|   30 namespace |   31 namespace | 
|   31 { |   32 { | 
|   32   v8::Handle<v8::Value> ReadCallback(const v8::Arguments& arguments) |   33   void ReadCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) | 
|   33   { |   34   { | 
|   34     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); |   35     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); | 
|   35     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |   36     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); | 
|   36  |   37  | 
|   37     v8::Isolate* isolate = arguments.GetIsolate(); |   38     v8::Isolate* isolate = arguments.GetIsolate(); | 
|   38     if (converted.size() != 2) |   39     if (converted.size() != 2) | 
|   39       return v8::ThrowException(Utils::ToV8String(isolate, |   40       return ThrowExceptionInJS(isolate, "_fileSystem.read requires 2 parameters
     "); | 
|   40         "_fileSystem.read requires 2 parameters")); |  | 
|   41     if (!converted[1].IsFunction()) |   41     if (!converted[1].IsFunction()) | 
|   42       return v8::ThrowException(Utils::ToV8String(isolate, |   42       return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.read mu
     st be a function"); | 
|   43         "Second argument to _fileSystem.read must be a function")); |   43  | 
|   44  |   44     JsValueList values; | 
|   45  |   45     values.push_back(converted[1]); | 
|   46     JsValue callback(converted[1]); |   46     auto weakCallback = jsEngine->StoreJsValues(values); | 
|   47     jsEngine->GetFileSystem()->Read(converted[0].AsString(), |   47     std::weak_ptr<JsEngine> weakJsEngine = jsEngine; | 
|   48       [jsEngine, callback] |   48     jsEngine->GetAsyncFileSystem()->Read(converted[0].AsString(), | 
|   49       (std::string&& content, const std::string& error) |   49       [weakJsEngine, weakCallback] | 
|   50       { |   50       (IFileSystem::IOBuffer&& content, const std::string& error) | 
 |   51       { | 
 |   52         auto jsEngine = weakJsEngine.lock(); | 
 |   53         if (!jsEngine) | 
 |   54           return; | 
 |   55  | 
|   51         const JsContext context(*jsEngine); |   56         const JsContext context(*jsEngine); | 
|   52         auto result = jsEngine->NewObject(); |   57         auto result = jsEngine->NewObject(); | 
|   53         result.SetProperty("content", content); |   58         result.SetStringBufferProperty("content", std::move(content)); | 
|   54         result.SetProperty("error", error); |   59         if (!error.empty()) | 
|   55         JsValueList params; |   60           result.SetProperty("error", error); | 
|   56         params.push_back(result); |   61         jsEngine->TakeJsValues(weakCallback)[0].Call(result); | 
|   57         callback.Call(params); |   62       }); | 
|   58       }); |   63   } | 
|   59  |   64  | 
|   60     return v8::Undefined(); |   65   void WriteCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) | 
|   61   } |  | 
|   62  |  | 
|   63   v8::Handle<v8::Value> WriteCallback(const v8::Arguments& arguments) |  | 
|   64   { |   66   { | 
|   65     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); |   67     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); | 
|   66     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |   68     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); | 
|   67  |   69  | 
|   68     v8::Isolate* isolate = arguments.GetIsolate(); |   70     v8::Isolate* isolate = arguments.GetIsolate(); | 
|   69     if (converted.size() != 3) |   71     if (converted.size() != 3) | 
|   70       return v8::ThrowException(Utils::ToV8String(isolate, |   72       return ThrowExceptionInJS(isolate, "_fileSystem.write requires 3 parameter
     s"); | 
|   71         "_fileSystem.write requires 3 parameters")); |  | 
|   72     if (!converted[2].IsFunction()) |   73     if (!converted[2].IsFunction()) | 
|   73       return v8::ThrowException(Utils::ToV8String(isolate, |   74       return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.write mu
     st be a function"); | 
|   74         "Third argument to _fileSystem.write must be a function")); |   75  | 
|   75  |   76     JsValueList values; | 
|   76     JsValue callback(converted[2]); |   77     values.push_back(converted[2]); | 
|   77     auto stream = std::make_shared<std::stringstream>(); |   78     auto weakCallback = jsEngine->StoreJsValues(values); | 
|   78     *stream << converted[1].AsString(); |   79     std::weak_ptr<JsEngine> weakJsEngine = jsEngine; | 
|   79     jsEngine->GetFileSystem()->Write(converted[0].AsString(), stream, |   80     auto content = converted[1].AsStringBuffer(); | 
|   80       [jsEngine, callback](const std::string& error) |   81     jsEngine->GetAsyncFileSystem()->Write(converted[0].AsString(), | 
|   81       { |   82       content, | 
|   82         const JsContext context(*jsEngine); |   83       [weakJsEngine, weakCallback](const std::string& error) | 
|   83         auto errorValue = jsEngine->NewValue(error); |   84       { | 
|   84         JsValueList params; |   85         auto jsEngine = weakJsEngine.lock(); | 
|   85         params.push_back(errorValue); |   86         if (!jsEngine) | 
|   86         callback.Call(params); |   87           return; | 
|   87       }); |   88  | 
|   88  |   89         const JsContext context(*jsEngine); | 
|   89     return v8::Undefined(); |   90         JsValueList params; | 
|   90   } |   91         if (!error.empty()) | 
|   91  |   92           params.push_back(jsEngine->NewValue(error)); | 
|   92   v8::Handle<v8::Value> MoveCallback(const v8::Arguments& arguments) |   93         jsEngine->TakeJsValues(weakCallback)[0].Call(params); | 
 |   94       }); | 
 |   95   } | 
 |   96  | 
 |   97   void MoveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) | 
|   93   { |   98   { | 
|   94     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); |   99     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); | 
|   95     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |  100     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); | 
|   96  |  101  | 
|   97     v8::Isolate* isolate = arguments.GetIsolate(); |  102     v8::Isolate* isolate = arguments.GetIsolate(); | 
|   98     if (converted.size() != 3) |  103     if (converted.size() != 3) | 
|   99       return v8::ThrowException(Utils::ToV8String(isolate, |  104       return ThrowExceptionInJS(isolate, "_fileSystem.move requires 3 parameters
     "); | 
|  100         "_fileSystem.move requires 3 parameters")); |  | 
|  101     if (!converted[2].IsFunction()) |  105     if (!converted[2].IsFunction()) | 
|  102       return v8::ThrowException(Utils::ToV8String(isolate, |  106       return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.move mus
     t be a function"); | 
|  103         "Third argument to _fileSystem.move must be a function")); |  107  | 
|  104  |  108     JsValueList values; | 
|  105     JsValue callback(converted[2]); |  109     values.push_back(converted[2]); | 
|  106     jsEngine->GetFileSystem()->Move(converted[0].AsString(), |  110     auto weakCallback = jsEngine->StoreJsValues(values); | 
 |  111     std::weak_ptr<JsEngine> weakJsEngine = jsEngine; | 
 |  112     jsEngine->GetAsyncFileSystem()->Move(converted[0].AsString(), | 
|  107       converted[1].AsString(), |  113       converted[1].AsString(), | 
|  108       [jsEngine, callback](const std::string& error) |  114       [weakJsEngine, weakCallback](const std::string& error) | 
|  109       { |  115       { | 
|  110         const JsContext context(*jsEngine); |  116         auto jsEngine = weakJsEngine.lock(); | 
|  111         auto errorValue = jsEngine->NewValue(error); |  117         if (!jsEngine) | 
|  112         JsValueList params; |  118           return; | 
|  113         params.push_back(errorValue); |  119  | 
|  114         callback.Call(params); |  120         const JsContext context(*jsEngine); | 
|  115       }); |  121         JsValueList params; | 
|  116  |  122         if (!error.empty()) | 
|  117     return v8::Undefined(); |  123           params.push_back(jsEngine->NewValue(error)); | 
|  118   } |  124         jsEngine->TakeJsValues(weakCallback)[0].Call(params); | 
|  119  |  125       }); | 
|  120   v8::Handle<v8::Value> RemoveCallback(const v8::Arguments& arguments) |  126   } | 
 |  127  | 
 |  128   void RemoveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) | 
|  121   { |  129   { | 
|  122     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); |  130     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); | 
|  123     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |  131     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); | 
|  124  |  132  | 
|  125     v8::Isolate* isolate = arguments.GetIsolate(); |  133     v8::Isolate* isolate = arguments.GetIsolate(); | 
|  126     if (converted.size() != 2) |  134     if (converted.size() != 2) | 
|  127       return v8::ThrowException(Utils::ToV8String(isolate, |  135       return ThrowExceptionInJS(isolate, "_fileSystem.remove requires 2 paramete
     rs"); | 
|  128         "_fileSystem.remove requires 2 parameters")); |  | 
|  129     if (!converted[1].IsFunction()) |  136     if (!converted[1].IsFunction()) | 
|  130       return v8::ThrowException(Utils::ToV8String(isolate, |  137       return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.remove 
     must be a function"); | 
|  131         "Second argument to _fileSystem.remove must be a function")); |  138  | 
|  132  |  139     JsValueList values; | 
|  133     JsValue callback(converted[1]); |  140     values.push_back(converted[1]); | 
|  134     jsEngine->GetFileSystem()->Remove(converted[0].AsString(), |  141     auto weakCallback = jsEngine->StoreJsValues(values); | 
|  135       [jsEngine, callback](const std::string& error) |  142     std::weak_ptr<JsEngine> weakJsEngine = jsEngine; | 
|  136       { |  143     jsEngine->GetAsyncFileSystem()->Remove(converted[0].AsString(), | 
|  137         const JsContext context(*jsEngine); |  144       [weakJsEngine, weakCallback](const std::string& error) | 
|  138         auto errorValue = jsEngine->NewValue(error); |  145       { | 
|  139         JsValueList params; |  146         auto jsEngine = weakJsEngine.lock(); | 
|  140         params.push_back(errorValue); |  147         if (!jsEngine) | 
|  141         callback.Call(params); |  148           return; | 
|  142       }); |  149  | 
|  143  |  150         const JsContext context(*jsEngine); | 
|  144     return v8::Undefined(); |  151         JsValueList params; | 
|  145   } |  152         if (!error.empty()) | 
|  146  |  153           params.push_back(jsEngine->NewValue(error)); | 
|  147   v8::Handle<v8::Value> StatCallback(const v8::Arguments& arguments) |  154         jsEngine->TakeJsValues(weakCallback)[0].Call(params); | 
 |  155       }); | 
 |  156   } | 
 |  157  | 
 |  158   void StatCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) | 
|  148   { |  159   { | 
|  149     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); |  160     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); | 
|  150     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |  161     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); | 
|  151  |  162  | 
|  152     v8::Isolate* isolate = arguments.GetIsolate(); |  163     v8::Isolate* isolate = arguments.GetIsolate(); | 
|  153     if (converted.size() != 2) |  164     if (converted.size() != 2) | 
|  154       return v8::ThrowException(Utils::ToV8String(isolate, |  165       return ThrowExceptionInJS(isolate, "_fileSystem.stat requires 2 parameters
     "); | 
|  155         "_fileSystem.stat requires 2 parameters")); |  | 
|  156     if (!converted[1].IsFunction()) |  166     if (!converted[1].IsFunction()) | 
|  157       return v8::ThrowException(Utils::ToV8String(isolate, |  167       return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.stat mu
     st be a function"); | 
|  158         "Second argument to _fileSystem.stat must be a function")); |  168  | 
|  159  |  169     JsValueList values; | 
|  160     JsValue callback(converted[1]); |  170     values.push_back(converted[1]); | 
|  161     jsEngine->GetFileSystem()->Stat(converted[0].AsString(), |  171     auto weakCallback = jsEngine->StoreJsValues(values); | 
|  162       [jsEngine, callback] |  172     std::weak_ptr<JsEngine> weakJsEngine = jsEngine; | 
 |  173     jsEngine->GetAsyncFileSystem()->Stat(converted[0].AsString(), | 
 |  174       [weakJsEngine, weakCallback] | 
|  163       (const IFileSystem::StatResult& statResult, const std::string& error) |  175       (const IFileSystem::StatResult& statResult, const std::string& error) | 
|  164       { |  176       { | 
 |  177         auto jsEngine = weakJsEngine.lock(); | 
 |  178         if (!jsEngine) | 
 |  179           return; | 
 |  180  | 
|  165         const JsContext context(*jsEngine); |  181         const JsContext context(*jsEngine); | 
|  166         auto result = jsEngine->NewObject(); |  182         auto result = jsEngine->NewObject(); | 
|  167  |  183  | 
|  168         result.SetProperty("exists", statResult.exists); |  184         result.SetProperty("exists", statResult.exists); | 
|  169         result.SetProperty("isFile", statResult.isFile); |  185         result.SetProperty("isFile", statResult.isFile); | 
|  170         result.SetProperty("isDirectory", statResult.isDirectory); |  186         result.SetProperty("isDirectory", statResult.isDirectory); | 
|  171         result.SetProperty("lastModified", statResult.lastModified); |  187         result.SetProperty("lastModified", statResult.lastModified); | 
|  172         result.SetProperty("error", error); |  188         if (!error.empty()) | 
 |  189           result.SetProperty("error", error); | 
|  173  |  190  | 
|  174         JsValueList params; |  191         JsValueList params; | 
|  175         params.push_back(result); |  192         params.push_back(result); | 
|  176         callback.Call(params); |  193         jsEngine->TakeJsValues(weakCallback)[0].Call(params); | 
|  177       }); |  194       }); | 
|  178  |  195   } | 
|  179     return v8::Undefined(); |  196  | 
|  180   } |  197   void ResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) | 
|  181  |  | 
|  182   v8::Handle<v8::Value> ResolveCallback(const v8::Arguments& arguments) |  | 
|  183   { |  198   { | 
|  184     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); |  199     AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg
     uments); | 
|  185     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); |  200     AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); | 
|  186  |  201  | 
|  187     v8::Isolate* isolate = arguments.GetIsolate(); |  202     v8::Isolate* isolate = arguments.GetIsolate(); | 
|  188     if (converted.size() != 1) |  203     if (converted.size() != 1) | 
|  189       return v8::ThrowException(Utils::ToV8String(isolate, |  204       return ThrowExceptionInJS(isolate, "_fileSystem.resolve requires 1 paramet
     er"); | 
|  190         "_fileSystem.resolve requires 1 parameter")); |  205  | 
|  191  |  206     std::string resolved = jsEngine->GetAsyncFileSystem()->Resolve(converted[0].
     AsString()); | 
|  192     std::string resolved = jsEngine->GetFileSystem()->Resolve(converted[0].AsStr
     ing()); |  207     arguments.GetReturnValue().Set(Utils::ToV8String(isolate, resolved)); | 
|  193  |  208   } | 
|  194     return Utils::ToV8String(isolate, resolved); |  | 
|  195   } |  | 
|  196  |  | 
|  197 } |  209 } | 
|  198  |  210  | 
|  199  |  211  | 
|  200 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj) |  212 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj) | 
|  201 { |  213 { | 
|  202   obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback)); |  214   obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback)); | 
|  203   obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback)); |  215   obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback)); | 
|  204   obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback)); |  216   obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback)); | 
|  205   obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback)); |  217   obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback)); | 
|  206   obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback)); |  218   obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback)); | 
|  207   obj.SetProperty("resolve", jsEngine.NewCallback(::ResolveCallback)); |  219   obj.SetProperty("resolve", jsEngine.NewCallback(::ResolveCallback)); | 
|  208   return obj; |  220   return obj; | 
|  209 } |  221 } | 
| LEFT | RIGHT |