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

Unified Diff: Shared/AdblockPlusClient.cpp

Issue 10540013: Proof of concept: Use a single FilterEngine instance (Closed)
Patch Set: Created May 3, 2013, 3:58 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Shared/AdblockPlusClient.h ('k') | Shared/PluginFilter.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Shared/AdblockPlusClient.cpp
===================================================================
--- a/Shared/AdblockPlusClient.cpp
+++ b/Shared/AdblockPlusClient.cpp
@@ -11,32 +11,185 @@
#include "AdblockPlusClient.h"
+namespace
+{
+ const LPCWSTR responseClassName = L"FilterEngineResponse";
+ std::string response;
+ bool responseReady;
+
+ std::auto_ptr<AdblockPlus::FilterEngine> CreateFilterEngine()
+ {
+ try
+ {
+ DEBUG_GENERAL("Building client");
+ AdblockPlus::AppInfo appInfo;
+ appInfo.name = "adblockplusie";
+ appInfo.version = CT2CA(_T(IEPLUGIN_VERSION), CP_UTF8);
+ appInfo.platform = "msie";
+
+ DEBUG_GENERAL(L"Building engine");
+
+ JsEnginePtr jsEngine(AdblockPlus::JsEngine::New(appInfo));
+ return std::auto_ptr<AdblockPlus::FilterEngine>(new AdblockPlus::FilterEngine(jsEngine));
+ }
+ catch(std::exception ex)
+ {
+ DEBUG_GENERAL(ex.what());
+ }
+ }
+
+ template<typename T>
+ std::wstring ToWString(const T& value)
+ {
+ std::wstringstream stream;
+ stream << value;
+ return stream.str();
+ }
+
+ std::wstring ToWString(LPCSTR value)
+ {
+ USES_CONVERSION;
+ return ToWString(A2W(value));
+ }
+
+ template<>
+ std::wstring ToWString(const std::string& value)
+ {
+ return ToWString(value.c_str());
+ }
+
+ template<typename T>
+ std::string ToString(const T& value)
+ {
+ std::stringstream stream;
+ stream << value;
+ return stream.str();
+ }
+
+ std::string ToString(LPCWSTR value)
+ {
+ USES_CONVERSION;
+ return ToString(W2A(value));
+ }
+
+ template<>
+ std::string ToString(const std::wstring& value)
+ {
+ return ToString(value.c_str());
+ }
+
+ std::string MarshalStrings(const std::vector<std::string>& strings)
+ {
+ std::string marshalledStrings;
+ for (std::vector<std::string>::const_iterator it = strings.begin(); it != strings.end(); it++)
+ marshalledStrings += *it + '\0';
+ return marshalledStrings;
+ }
+
+ std::vector<std::string> UnmarshalStrings(std::string::value_type* message, int count)
+ {
+ std::vector<std::string> strings;
+ for (int i = 0; i < count; i++)
+ {
+ std::string::value_type* part = message;
+ strings.push_back(message);
+ message += strlen(part) + 1;
+ }
+ return strings;
+ }
+
+ void SendStringMessage(HWND messageWindow, const std::string& message)
+ {
+ COPYDATASTRUCT data;
+ data.cbData = message.length() * sizeof(std::string::value_type);
+ data.lpData = (PVOID) message.c_str();
+ SendMessage(messageWindow, WM_COPYDATA, (WPARAM) messageWindow, (LPARAM)(LPVOID) &data);
+ }
+
+ LRESULT CALLBACK RequestWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ if (uMsg == WM_COPYDATA)
+ {
+ COPYDATASTRUCT* data = (COPYDATASTRUCT*) lParam;
+ std::vector<std::string> args = UnmarshalStrings((std::string::value_type*) data->lpData, 4);
+
+ FilterEngine* filterEngine = (FilterEngine*) GetWindowLongPtr(hWnd, GWLP_USERDATA);
+ bool matches = filterEngine->Matches(args[1], args[2], args[3]);
+
+ std::wstring responseWindowName = ToWString(args[0]);
+ HWND responseWindow = FindWindowEx(HWND_MESSAGE, 0, responseClassName, responseWindowName.c_str());
+ if (!responseWindow)
+ {
+ DEBUG_GENERAL(L"Failed to find the filter engine response window");
+ }
+ else
+ {
+ SendStringMessage(responseWindow, ToString(matches));
+ }
+ }
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+
+ LRESULT CALLBACK ResponseWindowProcedure(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+ {
+ if (uMsg == WM_COPYDATA)
+ {
+ COPYDATASTRUCT* data = (COPYDATASTRUCT*) lParam;
+ response = (std::string::value_type*) data->lpData;
+ responseReady = true;
+ }
+ return DefWindowProc(hWnd, uMsg, wParam, lParam);
+ }
+}
CAdblockPlusClient* CAdblockPlusClient::s_instance = NULL;
-
CAdblockPlusClient::CAdblockPlusClient() : CPluginClientBase()
{
- try
+ m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
+
+ // TODO: Only create a single filter engine instance, share them across all
+ // processes. For this we need to invoke all filter engine methods via
+ // IPC. This is already done for FilterEngine::Matches().
+ filterEngine = CreateFilterEngine();
+
+ const LPCWSTR requestClassName = L"FilterEngineRequest";
+ WNDCLASS requestClass = {};
+ requestClass.lpfnWndProc = (WNDPROC) RequestWindowProcedure;
+ requestClass.lpszClassName = requestClassName;
+ if (!RegisterClass(&requestClass))
{
- DEBUG_GENERAL("Building client");
- m_filter = std::auto_ptr<CPluginFilter>(new CPluginFilter());
- AdblockPlus::AppInfo appInfo;
- appInfo.name = "adblockplusie";
- appInfo.version = CT2CA(_T(IEPLUGIN_VERSION), CP_UTF8);
- appInfo.platform = "msie";
-
- DEBUG_GENERAL(L"Building engine");
+ DEBUG_GENERAL(L"Failed to register FilterEngineRequest class");
+ return;
+ }
- JsEnginePtr jsEngine(AdblockPlus::JsEngine::New(appInfo));
- filterEngine = std::auto_ptr<AdblockPlus::FilterEngine>(new AdblockPlus::FilterEngine(jsEngine));
+ filterEngineRequestWindow = FindWindowEx(HWND_MESSAGE, 0, requestClassName, 0);
+ if (!filterEngineRequestWindow)
+ {
+ filterEngineRequestWindow = CreateWindow(requestClassName, 0, 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
+ if (!filterEngineRequestWindow)
+ {
+ DEBUG_GENERAL(L"Failed to create filter engine request window");
+ return;
+ }
+ SetWindowLongPtr(filterEngineRequestWindow, GWLP_USERDATA, (LONG_PTR) filterEngine.get());
+ }
+ WNDCLASS responseClass = {};
+ responseClass.lpfnWndProc = (WNDPROC) ResponseWindowProcedure;
+ responseClass.lpszClassName = responseClassName;
+ if (!RegisterClass(&responseClass))
+ {
+ DEBUG_GENERAL(L"Failed to register FilterEngineRequest class");
+ return;
}
- catch(std::exception ex)
- {
- DEBUG_GENERAL(ex.what());
- }
+
+ filterEngineResponseWindowName = ToWString(GetCurrentThreadId());
+ filterEngineResponseWindow = CreateWindow(responseClassName, filterEngineResponseWindowName.c_str(), 0, 0, 0, 0, 0, HWND_MESSAGE, 0, 0, 0);
+ if (!filterEngineResponseWindow)
+ DEBUG_GENERAL(L"Failed to create filter engine response window");
}
+
CAdblockPlusClient::~CAdblockPlusClient()
{
s_instance = NULL;
@@ -163,3 +316,17 @@
RegCloseKey(hKey);
return (int)(version[0] - 48);
}
+
+bool CAdblockPlusClient::Matches(const std::string& url, const std::string& contentType, const std::string& domain)
+{
+ std::vector<std::string> args;
+ args.push_back(ToString(filterEngineResponseWindowName));
+ args.push_back(url);
+ args.push_back(contentType);
+ args.push_back(domain);
+ responseReady = false;
+ SendStringMessage(filterEngineRequestWindow, MarshalStrings(args));
+ while (!responseReady)
+ Sleep(10);
+ return response == "1";
+}
« no previous file with comments | « Shared/AdblockPlusClient.h ('k') | Shared/PluginFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld