unsigned int AdBlockPlus::asyncLoader(void* ppathname) { wstring* pstr = reinterpret_cast<wstring*>(ppathname); wstring pathname = *pstr; delete pstr; bool loaded = false; // then load stuff CFile file; if (file.Open(pathname.c_str(), CFile::modeRead | CFile::shareDenyWrite)) { wstring content; bool success = Utils::File::readFile(file, content); file.Close(); if (success) { WriterLock wl(s_mutex); clearFiltersInternal(true); INIParser parser; // split content into lines, process with INIParser one by one size_t lastPos = 0; wchar_t lastCh = 0; for (size_t i = 0; i < content.length(); i++) { wchar_t ch = content[i]; // accept CR, LF and CRLF sequence if (ch == L'\r' || (ch == L'\n' && lastCh != L'\r')) { parser.process(content.substr(lastPos, i - lastPos), false); } if (ch == L'\r' || ch == L'\n') lastPos = i + 1; lastCh = ch; } if (lastPos < content.length()) parser.process(content.substr(lastPos, content.length() - lastPos), false); parser.process(L"", true); // put everything in INIParser::filters into the matcher for (auto iter = parser.filters.begin(); iter != parser.filters.end(); ++iter) { ActiveFilter* filter = *iter; if (!filter || filter->isDisabled()) continue; RegExpFilter* regexpFilter = filter->toRegExpFilter(); if (regexpFilter) { regexpMatcher.add(regexpFilter); continue; } ElemHideFilter* elemhideFilter = filter->toElemHideFilter(); if (elemhideFilter) elemhideMatcher.add(elemhideFilter); } // generate the general filter list for elemhideMatcher to improve speed elemhideMatcher.generateGeneralFilters(); loaded = true; } } // Notify main thread about load completion CIEHostWindow* pWindow = CIEHostWindow::GetAnyUtilsWindow(); if (pWindow) pWindow->RunAsync([=] { filterLoadedCallback(loaded); pWindow->SendMessage(UserMessage::WM_USER_MESSAGE, loaded ? UserMessage::WPARAM_ABP_FILTER_LOADED : UserMessage::WPARAM_ABP_LOAD_FAILURE, 0); }); else filterLoadedCallback(loaded); return 0; }
unsigned int AdBlockPlus::asyncLoader(void* vpparam) { AsyncLoaderParam* pparam = reinterpret_cast<AsyncLoaderParam*>(vpparam); wstring pathname = std::move(pparam->pathname); wstring additionalFilters = std::move(pparam->additionalFilters); unordered_map<wstring, wstring> options = std::move(pparam->options); delete pparam; bool loaded = false; // then load stuff CFile file; if (file.Open(pathname.c_str(), CFile::modeRead | CFile::shareDenyWrite)) { wstring content; bool success = Utils::File::readFile(file, content); file.Close(); if (success) { WriterLock wl(s_mutex); clearFiltersInternal(true); INIParser parser(options); loadContent(parser, content); loadContent(parser, additionalFilters); // put everything in INIParser::filters into the matcher for (auto iter = parser.filters.begin(); iter != parser.filters.end(); ++iter) { ActiveFilter* filter = *iter; if (!filter || filter->isDisabled()) continue; RegExpFilter* regexpFilter = filter->toRegExpFilter(); if (regexpFilter) { regexpMatcher.add(regexpFilter); continue; } ElemHideFilter* elemhideFilter = filter->toElemHideFilter(); if (elemhideFilter) elemhideMatcher.add(elemhideFilter); } // generate the general filter list for elemhideMatcher to improve speed elemhideMatcher.generateGeneralFilters(); loaded = true; } } // Notify main thread about load completion CIEHostWindow* pWindow = CIEHostWindow::GetAnyUtilsWindow(); if (pWindow) { pWindow->RunAsync([=] { // filterLoadedCallback() should be called on the main thread // to ensure atomicity; // Must call the callback before sending the message filterLoadedCallback(loaded); pWindow->SendMessage(UserMessage::WM_USER_MESSAGE, loaded ? UserMessage::WPARAM_ABP_FILTER_LOADED : UserMessage::WPARAM_ABP_LOAD_FAILURE, 0); }); } else { // Just a fallback, may never get to here filterLoadedCallback(loaded); } return 0; }