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

Unified Diff: compiled/subscription/DownloadableSubscription.cpp

Issue 29606600: Issue 5146 - Implement DownloadableSubscription parsing in C++ (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created Nov. 13, 2017, 10:25 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
Index: compiled/subscription/DownloadableSubscription.cpp
===================================================================
--- a/compiled/subscription/DownloadableSubscription.cpp
+++ b/compiled/subscription/DownloadableSubscription.cpp
@@ -10,26 +10,172 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <cwctype>
+
#include "DownloadableSubscription.h"
+#include "../FilterNotifier.h"
+#include "../StringScanner.h"
+#include "../filter/CommentFilter.h"
+
+namespace {
+ constexpr int MILLIS_IN_HOUR = 60 * 60 * 1000;
+ constexpr int MILLIS_IN_DAY = 24 * MILLIS_IN_HOUR;
+}
+
+_DownloadableSubscription_Parser::_DownloadableSubscription_Parser(DownloadableSubscription& sub)
+ : mSubscription(&sub)
+{
+}
+
+void _DownloadableSubscription_Parser::Process(DependentString& line)
+{
+ auto filter = FilterPtr(Filter::FromText(line), false);
+ if (filter->mType == Filter::Type::COMMENT)
+ {
+ auto comment = filter->As<CommentFilter>();
+ if (!comment->GetParam().empty())
+ {
+ if (comment->GetParam() == u"checksum"_str)
+ {
+ // XXX we'll have to calculate the checksum.
hub 2017/11/13 22:35:27 this part will require import a md5sum calculation
+ }
+ mParams[comment->GetParam()] = comment->GetValue();
+ }
+ }
+
+ if (filter)
+ mFilters.push_back(filter);
+}
+
+int _DownloadableSubscription_Parser::ParseExpires(const String& expires)
+{
+ bool isHour = false;
+ StringScanner scanner(expires);
+ String::size_type numStart = 0;
+ String::size_type numLen = 0;
+ while(!scanner.done())
+ {
+ auto ch = scanner.next();
+ if (std::iswdigit(ch))
+ {
+ if (numLen == 0)
+ numStart = scanner.position();
+ numLen++;
+ }
+ else if (std::iswspace(ch))
+ {
+ if (numLen)
+ break;
+ }
+ else
+ {
+ if (numLen)
+ scanner.back();
+ break;
+ }
+ }
+
+ DependentString numStr(expires, numStart, numLen);
+ int num = numStr.toInt();
+ if (num == 0)
+ return 0;
+
+ while (!scanner.done())
+ {
+ auto ch = scanner.next();
+ if (std::iswspace(ch))
+ continue;
+ if (ch == u'h')
+ {
+ isHour = true;
+ // assume we are done here. The rest is ignored.
+ break;
+ }
+ }
+ // check for overflow.
+ if (!isHour && num > 24)
hub 2017/11/13 22:35:27 I should check the overflow for the expiration in
+ return 0;
+
+ num *= isHour ? MILLIS_IN_HOUR : MILLIS_IN_DAY;
+ return num;
+}
+
+int _DownloadableSubscription_Parser::Finalize()
+{
+ auto entry = mParams.find(u"title"_str);
+ if (entry)
+ {
+ mSubscription->SetTitle(entry->second);
+ mSubscription->SetFixedTitle(true);
+ }
+ else
+ mSubscription->SetFixedTitle(false);
+
+ int version = 0;
+ entry = mParams.find(u"version"_str);
+ if (entry)
+ version = entry->second.toInt();
+ mSubscription->SetDataRevision(version);
+
+ int expires = 0;
+ entry = mParams.find(u"expires"_str);
+ if (entry)
+ expires = ParseExpires(entry->second);
+
+ FilterNotifier::SubscriptionChange(
+ FilterNotifier::Topic::SUBSCRIPTION_BEFORE_FILTERS_REPLACED,
+ *mSubscription);
hub 2017/11/13 22:35:28 I'm not if that's the right place to send this not
+ auto oldFilters = std::move(mSubscription->GetFilters());
+ mSubscription->GetFilters() = std::move(mFilters);
+ FilterNotifier::SubscriptionChange(
+ FilterNotifier::Topic::SUBSCRIPTION_FILTERS_REPLACED, *mSubscription);
+
+ return expires;
+}
+
+namespace {
+ DependentString emptyString = u""_str;
+}
+
+const String& _DownloadableSubscription_Parser::GetRedirect() const
+{
+ auto entry = mParams.find(u"redirect"_str);
+ if (entry)
+ return entry->second;
+ return emptyString;
+}
+
+const String& _DownloadableSubscription_Parser::GetHomepage() const
+{
+ auto entry = mParams.find(u"homepage"_str);
+ if (entry)
+ return entry->second;
+ return emptyString;
+}
DownloadableSubscription::DownloadableSubscription(const String& id)
: Subscription(classType, id), mFixedTitle(false), mLastCheck(0),
mHardExpiration(0), mSoftExpiration(0), mLastDownload(0), mLastSuccess(0),
mErrorCount(0), mDataRevision(0), mDownloadCount(0)
{
SetTitle(id);
}
+_DownloadableSubscription_Parser* DownloadableSubscription::ParseDownload()
+{
+ return new _DownloadableSubscription_Parser(*this);
+}
+
OwnedString DownloadableSubscription::Serialize() const
{
OwnedString result(Subscription::Serialize());
if (mFixedTitle)
result.append(u"fixedTitle=true\n"_str);
if (!mHomepage.empty())
{
result.append(u"homepage="_str);

Powered by Google App Engine
This is Rietveld