OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-present eyeo GmbH |
| 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. |
| 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. |
| 13 * |
| 14 * You should have received a copy of the GNU General Public License |
| 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| 16 */ |
| 17 |
| 18 #include "Parser.h" |
| 19 #include "../subscription/DownloadableSubscription.h" |
| 20 #include "../subscription/UserDefinedSubscription.h" |
| 21 #include "../filter/Filter.h" |
| 22 |
| 23 namespace |
| 24 { |
| 25 bool IsSection(const String& value, const String& expectedSectionName) |
| 26 { |
| 27 auto valueLength = value.length(); |
| 28 // fast check whether it's a section and if its length is expected |
| 29 if (!(valueLength == expectedSectionName.length() + 2 && value[0] == u'[' &&
value[valueLength - 1] == u']')) |
| 30 return false; |
| 31 OwnedString sectionName(DependentString(value, 1, valueLength - 2)); |
| 32 sectionName.toLower(); |
| 33 return sectionName == expectedSectionName; |
| 34 } |
| 35 |
| 36 bool IsSubscriptionSection(const String& value) |
| 37 { |
| 38 return IsSection(value, u"subscription"_str); |
| 39 } |
| 40 |
| 41 bool IsSubscriptionFiltersSection(const String& value) |
| 42 { |
| 43 return ::IsSection(value, u"subscription filters"_str); |
| 44 } |
| 45 |
| 46 Subscription::KeyValue CreateKeyValue(const std::pair<DependentString, Depende
ntString>& pair) |
| 47 { |
| 48 Subscription::KeyValue retValue; |
| 49 retValue.first = TrimSpaces(pair.first); |
| 50 retValue.second = TrimSpaces(pair.second); |
| 51 return retValue; |
| 52 } |
| 53 |
| 54 void DecodeOpeningBracket(DependentString& value) |
| 55 { |
| 56 String::size_type skippedChars = 0; |
| 57 for (String::size_type i = 1; i < value.length(); ++i) |
| 58 { |
| 59 if (value[i - 1] == u'\\' && value[i] == u'[') |
| 60 ++skippedChars; |
| 61 value[i - skippedChars] = value[i]; |
| 62 } |
| 63 if (skippedChars > 0) |
| 64 value.reset(value, 0, value.length() - skippedChars); |
| 65 } |
| 66 } |
| 67 |
| 68 Parser::Parser() |
| 69 : mCurrentState{State::Initial} |
| 70 { |
| 71 } |
| 72 |
| 73 void Parser::Process(const String& untrimmedLine) |
| 74 { |
| 75 auto line = TrimSpaces(untrimmedLine); |
| 76 // skip empty lines |
| 77 if (line.length() == 0) |
| 78 return; |
| 79 |
| 80 if (IsSubscriptionSection(line)) |
| 81 { |
| 82 Finalize(); |
| 83 mCurrentState = State::SubscriptionSection; |
| 84 return; |
| 85 } |
| 86 |
| 87 switch (mCurrentState) |
| 88 { |
| 89 case State::Initial: |
| 90 Initial_processLine(line); |
| 91 break; |
| 92 case State::SubscriptionSection: |
| 93 SubscriptionSection_processLine(line); |
| 94 break; |
| 95 case State::SubscriptionFiltersSection: |
| 96 SubscriptionFiltersSection_processLine(line); |
| 97 break; |
| 98 default: |
| 99 ; |
| 100 } |
| 101 } |
| 102 |
| 103 void Parser::Finalize() |
| 104 { |
| 105 switch (mCurrentState) |
| 106 { |
| 107 case State::Initial: |
| 108 // don't clear file properties because they are also the parser member |
| 109 break; |
| 110 case State::SubscriptionSection: |
| 111 onSubscription(createSubscriptionFromProperties()); |
| 112 mSubscriptionProperties.clear(); |
| 113 break; |
| 114 case State::SubscriptionFiltersSection: |
| 115 onSubscription(std::move(mSubscription)); |
| 116 break; |
| 117 default: |
| 118 ; |
| 119 } |
| 120 } |
| 121 |
| 122 Parser::Subscriptions::size_type Parser::GetSubscriptionCount() const |
| 123 { |
| 124 return mSubscriptions.size(); |
| 125 } |
| 126 |
| 127 Subscription* Parser::SubscriptionAt(Subscriptions::size_type index) |
| 128 { |
| 129 if (index >= mSubscriptions.size()) |
| 130 return nullptr; |
| 131 return SubscriptionPtr(mSubscriptions[index]).release(); |
| 132 } |
| 133 |
| 134 SubscriptionPtr Parser::createSubscriptionFromProperties() const |
| 135 { |
| 136 return Subscription::FromProperties(mSubscriptionProperties); |
| 137 } |
| 138 |
| 139 void Parser::Initial_processLine(const String& line) |
| 140 { |
| 141 // skip # Adblock Plus preferences |
| 142 if (line[0] == u'#') |
| 143 return; |
| 144 |
| 145 String::size_type assignSignPos = line.find(u'='); |
| 146 if (assignSignPos != String::npos) |
| 147 { |
| 148 mFileProperties.emplace_back(CreateKeyValue(SplitString(line, assignSignPos)
)); |
| 149 return; |
| 150 } |
| 151 onFail("Unexpected line value, it should be either a file property or the [Sub
scription] section"); |
| 152 } |
| 153 |
| 154 void Parser::SubscriptionSection_processLine(const String& line) |
| 155 { |
| 156 String::size_type assignSignPos = line.find(u'='); |
| 157 if (assignSignPos != String::npos) |
| 158 { |
| 159 mSubscriptionProperties.emplace_back(CreateKeyValue(SplitString(line, assign
SignPos))); |
| 160 return; |
| 161 } |
| 162 if (IsSubscriptionFiltersSection(line)) |
| 163 { |
| 164 mSubscription = createSubscriptionFromProperties(); |
| 165 mCurrentState = State::SubscriptionFiltersSection; |
| 166 return; |
| 167 } |
| 168 onFail("Unexpected line value, it should be either a subscription property, th
e [Subscription filters] section or the [Subscription] section"); |
| 169 } |
| 170 |
| 171 void Parser::SubscriptionFiltersSection_processLine(const String& line) |
| 172 { |
| 173 OwnedString lineCopy{line}; |
| 174 DependentString lineForFilter{lineCopy}; |
| 175 DecodeOpeningBracket(lineForFilter); |
| 176 mSubscription->AddFilter(*FilterPtr(Filter::FromText(lineForFilter))); |
| 177 // any line is considered as a filter, there can be no error |
| 178 } |
| 179 |
| 180 void Parser::onSubscription(SubscriptionPtr subscription) |
| 181 { |
| 182 mSubscriptions.emplace_back(std::move(subscription)); |
| 183 } |
OLD | NEW |