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); |