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

Unified Diff: compiled/subscription/DownloadableSubscription.cpp

Issue 29630576: Issue 5146 - Part 2: Process http response in C++ (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Rebased Created Aug. 14, 2018, 12:45 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 | « compiled/subscription/DownloadableSubscription.h ('k') | lib/synchronizer.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: compiled/subscription/DownloadableSubscription.cpp
===================================================================
--- a/compiled/subscription/DownloadableSubscription.cpp
+++ b/compiled/subscription/DownloadableSubscription.cpp
@@ -82,37 +82,112 @@
text, beginValue, text.length() - beginValue);
}
}
return param;
}
}
DownloadableSubscription_Parser::DownloadableSubscription_Parser()
- : mFirstLine(true)
{
annotate_address(this, "DownloadableSubscription_Parser");
}
namespace {
const DependentString ADBLOCK_HEADER(u"[Adblock"_str);
+ const DependentString ADBLOCK_PLUS_EXTRA_HEADER(u"Plus"_str);
+
+ const DependentString ERROR_INVALID_DATA(u"synchronize_invalid_data"_str);
+}
+
+/// Return true if more line expected.
+bool DownloadableSubscription_Parser::GetNextLine(DependentString& buffer, DependentString& line)
+{
+ StringScanner scanner(buffer);
+ String::value_type ch = 0;
+ while (ch != u'\r' && ch != u'\n')
+ {
+ ch = scanner.next();
+ if (ch == 0)
+ break;
+ }
+
+ auto eol = scanner.position();
+ line.reset(buffer, 0, eol);
+ if (eol == 0 || ch == 0)
+ return false;
+ while (scanner.skipOne(u'\r') || scanner.skipOne(u'\n'))
+ ;
+ buffer.reset(buffer, scanner.position() + 1);
+ return true;
}
-void DownloadableSubscription_Parser::Process(const String& line)
+bool DownloadableSubscription_Parser::Process(const String& buffer)
{
- bool isHeader = false;
- isHeader = line.find(ADBLOCK_HEADER) != String::npos;
- if (!isHeader)
+ DependentString currentBuffer(buffer);
+ bool firstLine = true;
+
+ DependentString line;
+ while (true)
{
- auto param = ParseParam(line);
- if (param.first.is_invalid())
+ bool more = GetNextLine(currentBuffer, line);
+ if (firstLine)
+ {
+ if (!ProcessFirstLine(line))
+ {
+ mError = ERROR_INVALID_DATA;
+ return false;
+ }
+ firstLine = false;
+ }
+ else
+ ProcessLine(line);
+ if (!more)
+ break;
+ }
+ return true;
+}
+
+bool DownloadableSubscription_Parser::ProcessFirstLine(const String& line)
+{
+ auto index = line.find(ADBLOCK_HEADER);
+ if (index == String::npos)
+ return false;
+
+ DependentString minVersion;
+ DependentString current(line, index + ADBLOCK_HEADER.length());
+ StringScanner scanner(current);
+ if (scanner.skipWhiteSpace() && scanner.skipString(ADBLOCK_PLUS_EXTRA_HEADER))
+ scanner.skipWhiteSpace();
+ index = scanner.position() + 1;
+ String::value_type ch = u'\0';
+ while((ch = scanner.next()) && (ch == u'.' || std::iswdigit(ch)))
+ ;
+ if (ch)
+ scanner.back();
+ if (scanner.position() + 1 > index)
+ minVersion.reset(current, index, scanner.position() + 1 - index);
+
+ if (ch != u']')
+ return false;
+
+ mRequiredVersion = minVersion;
+ return true;
+}
+
+void DownloadableSubscription_Parser::ProcessLine(const String& line)
+{
+ auto param = ParseParam(line);
+ if (param.first.is_invalid())
+ {
+ if (!line.empty())
mFiltersText.emplace_back(line);
- else
- mParams[param.first] = param.second;
}
+ else
+ mParams[param.first] = param.second;
}
int64_t DownloadableSubscription_Parser::ParseExpires(const String& expires)
{
bool isHour = false;
StringScanner scanner(expires);
String::size_type numStart = 0;
String::size_type numLen = 0;
@@ -160,16 +235,23 @@
return 0;
num *= isHour ? MILLIS_IN_HOUR : MILLIS_IN_DAY;
return num;
}
int64_t DownloadableSubscription_Parser::Finalize(DownloadableSubscription& subscription)
{
+ FilterNotifier::SubscriptionChange(
+ FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED,
+ subscription);
+
+ if (!mRequiredVersion.empty())
+ subscription.SetRequiredVersion(mRequiredVersion);
+
auto entry = mParams.find(u"title"_str);
if (entry)
{
subscription.SetTitle(entry->second);
subscription.SetFixedTitle(true);
}
else
subscription.SetFixedTitle(false);
@@ -180,20 +262,16 @@
version = lexical_cast<int32_t>(entry->second);
subscription.SetDataRevision(version);
int64_t expires = 0;
entry = mParams.find(u"expires"_str);
if (entry)
expires = ParseExpires(entry->second);
- FilterNotifier::SubscriptionChange(
- FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED,
- subscription);
-
Subscription::Filters filters;
filters.reserve(mFiltersText.size());
for (auto text : mFiltersText)
{
DependentString dependent(text);
filters.emplace_back(Filter::FromText(dependent), false);
}
« no previous file with comments | « compiled/subscription/DownloadableSubscription.h ('k') | lib/synchronizer.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld