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

Side by Side Diff: src/FileSystemJsObject.cpp

Issue 29731562: Issue 6477 - separate done and error callbacks in IFileSystem::Read (Closed) Base URL: https://github.com/adblockplus/libadblockplus.git@c0a6434596a83383e37678ef3b6ecef00ed6a261
Patch Set: Created March 23, 2018, 10:58 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
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-present eyeo GmbH 3 * Copyright (C) 2006-present 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
(...skipping 14 matching lines...) Expand all
25 #include "JsContext.h" 25 #include "JsContext.h"
26 #include "Utils.h" 26 #include "Utils.h"
27 #include "JsError.h" 27 #include "JsError.h"
28 #include <AdblockPlus/Platform.h> 28 #include <AdblockPlus/Platform.h>
29 29
30 using namespace AdblockPlus; 30 using namespace AdblockPlus;
31 using AdblockPlus::Utils::ThrowExceptionInJS; 31 using AdblockPlus::Utils::ThrowExceptionInJS;
32 32
33 namespace 33 namespace
34 { 34 {
35 void ReadCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 35 namespace ReadCallback
sergei 2018/03/23 11:27:19 the changes here are: - create the namespace `Read
36 { 36 {
37 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 37 struct WeakData
38 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 38 {
39 public:
40 WeakData(const JsEnginePtr& jsEngine,
41 JsEngine::JsWeakValuesID weakResolveCallback,
42 JsEngine::JsWeakValuesID weakRejectCallback)
43 : weakJsEngine(jsEngine)
44 , weakResolveCallback(weakResolveCallback)
45 , weakRejectCallback(weakRejectCallback)
46 {
47 }
48 virtual ~WeakData()
49 {
50 auto jsEngine = weakJsEngine.lock();
51 if (!jsEngine)
52 return;
53 jsEngine->TakeJsValues(weakResolveCallback);
54 jsEngine->TakeJsValues(weakRejectCallback);
55 }
56 std::weak_ptr<JsEngine> weakJsEngine;
57 JsEngine::JsWeakValuesID weakResolveCallback;
58 JsEngine::JsWeakValuesID weakRejectCallback;
59 };
39 60
40 v8::Isolate* isolate = arguments.GetIsolate(); 61 static void V8Callback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
41 if (converted.size() != 2) 62 {
42 return ThrowExceptionInJS(isolate, "_fileSystem.read requires 2 parameters "); 63 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(a rguments);
43 if (!converted[1].IsFunction()) 64 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments) ;
44 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.read mu st be a function");
45 65
46 JsValueList values; 66 v8::Isolate* isolate = arguments.GetIsolate();
47 values.push_back(converted[1]); 67 if (converted.size() != 3)
48 auto weakCallback = jsEngine->StoreJsValues(values); 68 return ThrowExceptionInJS(isolate, "_fileSystem.read requires 3 paramete rs");
49 std::weak_ptr<JsEngine> weakJsEngine = jsEngine; 69 if (!converted[1].IsFunction())
50 auto fileName = converted[0].AsString(); 70 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.read must be a function");
51 jsEngine->GetPlatform().WithFileSystem( 71 if (!converted[2].IsFunction())
52 [weakJsEngine, weakCallback, fileName](IFileSystem& fileSystem) 72 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.read m ust be a function");
73
74 auto weakResolveCallback = jsEngine->StoreJsValues({converted[1]});
75 auto weakRejectCallback = jsEngine->StoreJsValues({converted[2]});
76 auto weakData = std::make_shared<WeakData>(jsEngine, weakResolveCallback, weakRejectCallback);
77 auto fileName = converted[0].AsString();
78 jsEngine->GetPlatform().WithFileSystem(
79 [weakData, fileName](IFileSystem& fileSystem)
80 {
81 fileSystem.Read(fileName, [weakData](IFileSystem::IOBuffer&& content)
82 {
83 auto jsEngine = weakData->weakJsEngine.lock();
84 if (!jsEngine)
85 return;
86 const JsContext context(*jsEngine);
87 auto result = jsEngine->NewObject();
88 result.SetStringBufferProperty("content", content);
89 jsEngine->GetJsValues(weakData->weakResolveCallback)[0].Call(resul t);
90 },
91 [weakData](const std::string& error)
92 {
93 if (error.empty())
94 return;
95 auto jsEngine = weakData->weakJsEngine.lock();
96 if (!jsEngine)
97 return;
98 const JsContext context(*jsEngine);
99 jsEngine->GetJsValues(weakData->weakRejectCallback)[0].Call(jsEngi ne->NewValue(error));
100 });
101 });
102 } // V8Callback
103 } // namespace ReadCallback
104
105 namespace ReadFromFileCallback
sergei 2018/03/23 11:27:19 the changes here are: - create the namespace `Read
106 {
107 inline bool IsEndOfLine(char c)
108 {
109 return c == 10 || c == 13;
110 }
111
112 inline StringBuffer::const_iterator SkipEndOfLine(StringBuffer::const_iterat or ii, StringBuffer::const_iterator end)
113 {
114 while (ii != end && IsEndOfLine(*ii))
115 ++ii;
116 return ii;
117 }
118
119 inline StringBuffer::const_iterator AdvanceToEndOfLine(StringBuffer::const_i terator ii, StringBuffer::const_iterator end)
120 {
121 while (ii != end && !IsEndOfLine(*ii))
122 ++ii;
123 return ii;
124 }
125
126 struct WeakData : ReadCallback::WeakData
127 {
128 public:
129 WeakData(const JsEnginePtr& jsEngine,
130 JsEngine::JsWeakValuesID weakResolveCallback,
131 JsEngine::JsWeakValuesID weakRejectCallback,
132 JsEngine::JsWeakValuesID weakProcessFunc)
133 : ReadCallback::WeakData(jsEngine, weakResolveCallback, weakRejectCallba ck)
134 , weakProcessFunc(weakProcessFunc)
53 { 135 {
54 fileSystem.Read(fileName, 136 }
55 [weakJsEngine, weakCallback] 137 ~WeakData()
56 (IFileSystem::IOBuffer&& content, const std::string& error) 138 {
57 { 139 auto jsEngine = weakJsEngine.lock();
58 auto jsEngine = weakJsEngine.lock(); 140 if (!jsEngine)
59 if (!jsEngine) 141 return;
60 return; 142 jsEngine->TakeJsValues(weakProcessFunc);
143 }
144 JsEngine::JsWeakValuesID weakProcessFunc;
145 };
61 146
62 const JsContext context(*jsEngine); 147 void V8Callback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
63 auto result = jsEngine->NewObject(); 148 {
64 result.SetStringBufferProperty("content", std::move(content)); 149 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(a rguments);
65 if (!error.empty()) 150 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments) ;
66 result.SetProperty("error", error);
67 jsEngine->TakeJsValues(weakCallback)[0].Call(result);
68 });
69 });
70 }
71 151
72 inline bool IsEndOfLine(char c) 152 v8::Isolate* isolate = arguments.GetIsolate();
73 { 153 if (converted.size() != 4)
74 return c == 10 || c == 13; 154 return ThrowExceptionInJS(isolate, "_fileSystem.readFromFile requires 4 parameters");
75 } 155 if (!converted[1].IsFunction())
156 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.readF romFile must be a function (listener callback)");
157 if (!converted[2].IsFunction())
158 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.readFr omFile must be a function (done callback)");
159 if (!converted[3].IsFunction())
160 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.readFr omFile must be a function (error callback)");
76 161
77 inline StringBuffer::const_iterator SkipEndOfLine(StringBuffer::const_iterator ii, StringBuffer::const_iterator end) 162 auto weakProcessFunc = jsEngine->StoreJsValues({converted[1]});
78 { 163 auto weakResolveCallback = jsEngine->StoreJsValues({converted[2]});
79 while (ii != end && IsEndOfLine(*ii)) 164 auto weakRejectCallback = jsEngine->StoreJsValues({converted[3]});
80 ++ii; 165 auto weakData = std::make_shared<WeakData>(jsEngine, weakResolveCallback, weakRejectCallback, weakProcessFunc);
81 return ii; 166 auto fileName = converted[0].AsString();
82 } 167 jsEngine->GetPlatform().WithFileSystem([weakData, fileName](IFileSystem& f ileSystem)
168 {
169 fileSystem.Read(fileName, [weakData](IFileSystem::IOBuffer&& content)
170 {
171 auto jsEngine = weakData->weakJsEngine.lock();
172 if (!jsEngine)
173 return;
83 174
84 inline StringBuffer::const_iterator AdvanceToEndOfLine(StringBuffer::const_ite rator ii, StringBuffer::const_iterator end) 175 const JsContext context(*jsEngine);
85 { 176 auto jsValues = jsEngine->GetJsValues(weakData->weakProcessFunc);
86 while (ii != end && !IsEndOfLine(*ii)) 177 auto processFunc = jsValues[0].UnwrapValue().As<v8::Function>();
87 ++ii; 178 auto globalContext = context.GetV8Context()->Global();
88 return ii; 179 if (!globalContext->IsObject())
89 } 180 throw std::runtime_error("`this` pointer has to be an object");
90 181
91 void ReadFromFileCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments ) 182 const v8::TryCatch tryCatch;
92 { 183 const auto contentEnd = content.cend();
93 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 184 auto stringBegin = SkipEndOfLine(content.begin(), contentEnd);
94 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 185 do
95 186 {
96 v8::Isolate* isolate = arguments.GetIsolate(); 187 auto stringEnd = AdvanceToEndOfLine(stringBegin, contentEnd);
97 if (converted.size() != 3) 188 auto jsLine = Utils::StringBufferToV8String(jsEngine->GetIsolate (), StringBuffer(stringBegin, stringEnd)).As<v8::Value>();
98 return ThrowExceptionInJS(isolate, "_fileSystem.readFromFile requires 3 pa rameters"); 189 processFunc->Call(globalContext, 1, &jsLine);
99 if (!converted[1].IsFunction()) 190 if (tryCatch.HasCaught())
100 return ThrowExceptionInJS(isolate, "Second argument to _fileSystem.readFro mFile must be a function (listener callback)"); 191 throw JsError(tryCatch.Exception(), tryCatch.Message());
sergei 2018/03/23 11:27:19 Please pay attention to this change. Previously it
101 if (!converted[2].IsFunction()) 192 stringBegin = SkipEndOfLine(stringEnd, contentEnd);
102 return ThrowExceptionInJS(isolate, "Third argument to _fileSystem.readFrom File must be a function (done callback)"); 193 } while (stringBegin != contentEnd);
103 194 jsEngine->GetJsValues(weakData->weakResolveCallback)[0].Call();
104 JsValueList values; 195 }, [weakData](const std::string& error)
105 values.push_back(converted[1]);
106 values.push_back(converted[2]);
107 auto weakCallback = jsEngine->StoreJsValues(values);
108 std::weak_ptr<JsEngine> weakJsEngine = jsEngine;
109 auto fileName = converted[0].AsString();
110 jsEngine->GetPlatform().WithFileSystem(
111 [weakJsEngine, weakCallback, fileName](IFileSystem& fileSystem)
112 {
113 fileSystem.Read(fileName,
114 [weakJsEngine, weakCallback]
115 (IFileSystem::IOBuffer&& content, const std::string& error)
116 {
117 auto jsEngine = weakJsEngine.lock();
118 if (!jsEngine)
119 return;
120
121 const JsContext context(*jsEngine);
122
123 auto jsValues = jsEngine->TakeJsValues(weakCallback);
124 if (!error.empty())
125 { 196 {
126 jsValues[1].Call(jsEngine->NewValue(error)); 197 if (error.empty())
127 return;
128 }
129
130 auto processFunc = jsValues[0].UnwrapValue().As<v8::Function>();
131
132 auto globalContext = context.GetV8Context()->Global();
133 if (!globalContext->IsObject())
134 throw std::runtime_error("`this` pointer has to be an object");
135
136 const v8::TryCatch tryCatch;
137
138 const auto contentEnd = content.cend();
139 auto stringBegin = SkipEndOfLine(content.begin(), contentEnd);
140 do
141 {
142 auto stringEnd = AdvanceToEndOfLine(stringBegin, contentEnd);
143 auto jsLine = Utils::StringBufferToV8String(jsEngine->GetIsolate() , StringBuffer(stringBegin, stringEnd)).As<v8::Value>();
144 processFunc->Call(globalContext, 1, &jsLine);
145 if (tryCatch.HasCaught())
146 {
147 jsValues[1].Call(jsEngine->NewValue(JsError::ExceptionToString(t ryCatch.Exception(), tryCatch.Message())));
148 return; 198 return;
149 } 199 auto jsEngine = weakData->weakJsEngine.lock();
150 stringBegin = SkipEndOfLine(stringEnd, contentEnd); 200 if (!jsEngine)
151 } while (stringBegin != contentEnd); 201 return;
152 jsValues[1].Call(); 202 jsEngine->GetJsValues(weakData->weakRejectCallback)[0].Call(jsEngi ne->NewValue(error));
153 }); 203 });
154 }); 204 });
155 } 205 } // V8Callback
206 } // namespace ReadFromFileCallback
156 207
157 void WriteCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments) 208 void WriteCallback(const v8::FunctionCallbackInfo<v8::Value>& arguments)
158 { 209 {
159 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments); 210 AdblockPlus::JsEnginePtr jsEngine = AdblockPlus::JsEngine::FromArguments(arg uments);
160 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments); 211 AdblockPlus::JsValueList converted = jsEngine->ConvertArguments(arguments);
161 212
162 v8::Isolate* isolate = arguments.GetIsolate(); 213 v8::Isolate* isolate = arguments.GetIsolate();
163 if (converted.size() != 3) 214 if (converted.size() != 3)
164 return ThrowExceptionInJS(isolate, "_fileSystem.write requires 3 parameter s"); 215 return ThrowExceptionInJS(isolate, "_fileSystem.write requires 3 parameter s");
165 if (!converted[2].IsFunction()) 216 if (!converted[2].IsFunction())
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 params.push_back(result); 351 params.push_back(result);
301 jsEngine->TakeJsValues(weakCallback)[0].Call(params); 352 jsEngine->TakeJsValues(weakCallback)[0].Call(params);
302 }); 353 });
303 }); 354 });
304 } 355 }
305 } 356 }
306 357
307 358
308 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj) 359 JsValue& FileSystemJsObject::Setup(JsEngine& jsEngine, JsValue& obj)
309 { 360 {
310 obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback)); 361 obj.SetProperty("read", jsEngine.NewCallback(::ReadCallback::V8Callback));
311 obj.SetProperty("readFromFile", jsEngine.NewCallback(::ReadFromFileCallback)); 362 obj.SetProperty("readFromFile", jsEngine.NewCallback(::ReadFromFileCallback::V 8Callback));
312 obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback)); 363 obj.SetProperty("write", jsEngine.NewCallback(::WriteCallback));
313 obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback)); 364 obj.SetProperty("move", jsEngine.NewCallback(::MoveCallback));
314 obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback)); 365 obj.SetProperty("remove", jsEngine.NewCallback(::RemoveCallback));
315 obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback)); 366 obj.SetProperty("stat", jsEngine.NewCallback(::StatCallback));
316 return obj; 367 return obj;
317 } 368 }
OLDNEW
« no previous file with comments | « src/DefaultFileSystem.cpp ('k') | src/JsEngine.cpp » ('j') | test/BaseJsTest.h » ('J')

Powered by Google App Engine
This is Rietveld