Index: chrome/browser/privacy_blacklist/blacklist_io.cc |
diff --git a/chrome/browser/privacy_blacklist/blacklist_io.cc b/chrome/browser/privacy_blacklist/blacklist_io.cc |
index 9c61b12c75cc6aafa33e3ca28e55db0ddc55442e..e8578ecd6826a562d21bc0909549d135e64ca3d3 100644 |
--- a/chrome/browser/privacy_blacklist/blacklist_io.cc |
+++ b/chrome/browser/privacy_blacklist/blacklist_io.cc |
@@ -4,13 +4,13 @@ |
#include "chrome/browser/privacy_blacklist/blacklist_io.h" |
-#include <algorithm> |
-#include <string> |
+#include <limits> |
#include "base/file_path.h" |
#include "base/file_util.h" |
-#include "base/string_util.h" |
#include "base/string_tokenizer.h" |
+#include "base/string_util.h" |
+#include "chrome/browser/privacy_blacklist/blacklist.h" |
#include "chrome/browser/privacy_blacklist/blacklist_store.h" |
namespace { |
@@ -37,71 +37,66 @@ class IsNotWhiteSpace { |
bool StartsWith(const char* cur, const char* end, |
const char* tag, std::size_t size) { |
- return cur+size <= end && std::equal(tag, tag+size-1, cur); |
+ return cur + size <= end && std::equal(tag, tag + size - 1, cur); |
} |
} // namespace |
-BlacklistIO::BlacklistIO() {} |
- |
-BlacklistIO::~BlacklistIO() { |
- for (std::list<Blacklist::Entry*>::iterator i = blacklist_.begin(); |
- i != blacklist_.end(); ++i) { |
- delete *i; |
- } |
- for (std::list<Blacklist::Provider*>::iterator i = providers_.begin(); |
- i != providers_.end(); ++i) { |
- delete *i; |
- } |
-} |
- |
-bool BlacklistIO::Read(const FilePath& file) { |
+// static |
+bool BlacklistIO::ReadText(Blacklist* blacklist, |
+ const FilePath& path, |
+ std::string* error_string) { |
+ DCHECK(blacklist); |
+ |
// Memory map for efficient parsing. If the file cannot fit in available |
// memory it would be the least of our worries. Typical blacklist files |
// are less than 200K. |
file_util::MemoryMappedFile input; |
- if (!input.Initialize(file) || !input.data()) { |
- last_error_ = ASCIIToUTF16("File I/O error. Check path and permissions."); |
+ if (!input.Initialize(path) || !input.data()) { |
+ *error_string = "File I/O error. Check path and permissions."; |
return false; |
} |
- |
+ |
const char* cur = reinterpret_cast<const char*>(input.data()); |
const char* end = cur + input.length(); |
- |
+ |
// Check header. |
if (!StartsWith(cur, end, header, arraysize(header))) { |
- last_error_ = ASCIIToUTF16("Incorrect header."); |
+ *error_string = "Incorrect header."; |
return false; |
} |
- |
+ |
+ Blacklist::EntryList entries; |
+ Blacklist::ProviderList providers; |
+ |
Blacklist::Provider* provider = new Blacklist::Provider; |
- providers_.push_back(provider); |
- |
+ providers.push_back(linked_ptr<Blacklist::Provider>(provider)); |
+ |
cur = std::find(cur, end, '\n') + 1; // Skip past EOL. |
- |
+ |
// Each loop iteration takes care of one input line. |
while (cur < end) { |
// Skip whitespace at beginning of line. |
cur = std::find_if(cur, end, IsNotWhiteSpace()); |
if (cur == end) |
break; |
- |
+ |
if (*cur == '#') { |
cur = std::find(cur, end, '\n') + 1; |
continue; |
} |
- |
+ |
if (*cur == '|') { |
++cur; |
if (StartsWith(cur, end, name_tag, arraysize(name_tag))) { |
// Edge condition: if the find below fails, the next one will too, |
// so we'll just skip to the EOF below. |
- cur = std::find_if(cur+arraysize(name_tag), end, IsNotWhiteSpace()); |
+ cur = std::find_if(cur + arraysize(name_tag), end, IsNotWhiteSpace()); |
const char* skip = std::find_if(cur, end, IsWhiteSpace()); |
if (skip < end) |
provider->set_name(std::string(cur, skip)); |
} else if (StartsWith(cur, end, url_tag, arraysize(url_tag))) { |
- cur = std::find_if(cur+arraysize(url_tag), end, IsNotWhiteSpace()); |
+ cur = std::find_if(cur + arraysize(url_tag), end, IsNotWhiteSpace()); |
const char* skip = std::find_if(cur, end, IsWhiteSpace()); |
if (skip < end) |
provider->set_url(std::string(cur, skip)); |
@@ -109,43 +104,42 @@ bool BlacklistIO::Read(const FilePath& file) { |
cur = std::find(cur, end, '\n') + 1; |
continue; |
} |
- |
+ |
const char* skip = std::find_if(cur, end, IsWhiteSpace()); |
std::string pattern(cur, skip); |
- |
- cur = std::find_if(cur+pattern.size(), end, IsNotWhiteSpace()); |
+ |
+ cur = std::find_if(cur + pattern.size(), end, IsNotWhiteSpace()); |
if (!StartsWith(cur, end, arrow_tag, arraysize(arrow_tag))) { |
- last_error_ = ASCIIToUTF16("Missing => in rule."); |
+ *error_string = "Missing => in rule."; |
return false; |
} |
- |
- scoped_ptr<Blacklist::Entry> entry(new Blacklist::Entry(pattern, provider)); |
- |
- cur = std::find_if(cur+arraysize(arrow_tag), end, IsNotWhiteSpace()); |
- skip = std::find_first_of(cur, end, eol, eol+2); |
+ |
+ linked_ptr<Blacklist::Entry> entry(new Blacklist::Entry(pattern, provider)); |
+ |
+ cur = std::find_if(cur + arraysize(arrow_tag), end, IsNotWhiteSpace()); |
+ skip = std::find_first_of(cur, end, eol, eol + 2); |
std::string buf(cur, skip); |
cur = skip + 1; |
- |
- StringTokenizer tokenier(buf, " (),\n\r"); |
- tokenier.set_options(StringTokenizer::RETURN_DELIMS); |
- |
+ |
+ StringTokenizer tokenizer(buf, " (),\n\r"); |
+ tokenizer.set_options(StringTokenizer::RETURN_DELIMS); |
+ |
bool in_attribute = false; |
unsigned int last_attribute = 0; |
- |
- while (tokenier.GetNext()) { |
- if (tokenier.token_is_delim()) { |
- switch (*tokenier.token_begin()) { |
+ |
+ while (tokenizer.GetNext()) { |
+ if (tokenizer.token_is_delim()) { |
+ switch (*tokenizer.token_begin()) { |
case '(': |
if (in_attribute) { |
- last_error_ = |
- ASCIIToUTF16("Unexpected ( in attribute parameters."); |
+ *error_string = "Unexpected ( in attribute parameters."; |
return false; |
} |
in_attribute = true; |
continue; |
case ')': |
if (!in_attribute) { |
- last_error_ = ASCIIToUTF16("Unexpected ) in attribute list."); |
+ *error_string = "Unexpected ) in attribute list."; |
return false; |
} |
in_attribute = false; |
@@ -155,59 +149,126 @@ bool BlacklistIO::Read(const FilePath& file) { |
continue; |
} |
} |
- |
+ |
if (in_attribute) { |
// The only attribute to support sub_tokens is kBlockByType, for now. |
if (last_attribute == Blacklist::kBlockByType) |
- entry->AddType(tokenier.token()); |
+ entry->AddType(tokenizer.token()); |
} else { |
// Filter attribute. Unrecognized attributes are ignored. |
- last_attribute = Blacklist::String2Attribute(tokenier.token()); |
+ last_attribute = Blacklist::String2Attribute(tokenizer.token()); |
entry->AddAttributes(last_attribute); |
} |
} |
- blacklist_.push_back(entry.release()); |
+ entries.push_back(entry); |
+ } |
+ |
+ for (Blacklist::EntryList::iterator i = entries.begin(); |
+ i != entries.end(); ++i) { |
+ blacklist->AddEntry(i->release()); |
} |
+ for (Blacklist::ProviderList::iterator i = providers.begin(); |
+ i != providers.end(); ++i) { |
+ blacklist->AddProvider(i->release()); |
+ } |
+ |
return true; |
} |
-bool BlacklistIO::Write(const FilePath& file) { |
- BlacklistStoreOutput output(file_util::OpenFile(file, "wb")); |
- if (!output.is_good()) { |
- last_error_ = ASCIIToUTF16("Error opening file for writing."); |
+// static |
+bool BlacklistIO::ReadBinary(Blacklist* blacklist, const FilePath& path) { |
+ DCHECK(blacklist); |
+ |
+ FILE* fp = file_util::OpenFile(path, "rb"); |
+ if (fp == NULL) |
return false; |
+ |
+ BlacklistStoreInput input(fp); |
+ |
+ // Read the providers. |
+ uint32 num_providers = input.ReadNumProviders(); |
+ if (num_providers == std::numeric_limits<uint32>::max()) |
+ return false; |
+ |
+ Blacklist::EntryList entries; |
+ Blacklist::ProviderList providers; |
+ std::map<size_t, Blacklist::Provider*> provider_map; |
+ |
+ std::string name; |
+ std::string url; |
+ for (size_t i = 0; i < num_providers; ++i) { |
+ if (!input.ReadProvider(&name, &url)) |
+ return false; |
+ provider_map[i] = new Blacklist::Provider(name.c_str(), url.c_str()); |
+ providers.push_back(linked_ptr<Blacklist::Provider>(provider_map[i])); |
+ } |
+ |
+ // Read the entries. |
+ uint32 num_entries = input.ReadNumEntries(); |
+ if (num_entries == std::numeric_limits<uint32>::max()) |
+ return false; |
+ |
+ std::string pattern; |
+ unsigned int attributes, provider; |
+ std::vector<std::string> types; |
+ for (size_t i = 0; i < num_entries; ++i) { |
+ if (!input.ReadEntry(&pattern, &attributes, &types, &provider)) |
+ return false; |
+ |
+ Blacklist::Entry* entry = |
+ new Blacklist::Entry(pattern, provider_map[provider]); |
+ entry->AddAttributes(attributes); |
+ entry->SwapTypes(&types); |
+ entries.push_back(linked_ptr<Blacklist::Entry>(entry)); |
} |
+ |
+ for (Blacklist::EntryList::iterator i = entries.begin(); |
+ i != entries.end(); ++i) { |
+ blacklist->AddEntry(i->release()); |
+ } |
+ for (Blacklist::ProviderList::iterator i = providers.begin(); |
+ i != providers.end(); ++i) { |
+ blacklist->AddProvider(i->release()); |
+ } |
+ |
+ return true; |
+} |
+ |
+// static |
+bool BlacklistIO::WriteBinary(const Blacklist* blacklist, |
+ const FilePath& file) { |
+ BlacklistStoreOutput output(file_util::OpenFile(file, "wb")); |
+ if (!output.is_good()) |
+ return false; |
+ |
+ Blacklist::EntryList entries(blacklist->entries_begin(), |
+ blacklist->entries_end()); |
+ Blacklist::ProviderList providers(blacklist->providers_begin(), |
+ blacklist->providers_end()); |
// Output providers, give each one an index. |
std::map<const Blacklist::Provider*, uint32> index; |
uint32 current = 0; |
- if (!output.ReserveProviders(providers_.size())) { |
- last_error_ = ASCIIToUTF16("Error writing to file."); |
+ if (!output.ReserveProviders(providers.size())) |
return false; |
- } |
- for (std::list<Blacklist::Provider*>::const_iterator i = providers_.begin(); |
- i != providers_.end(); ++i, ++current) { |
- if (!output.StoreProvider((*i)->name(), (*i)->url())) { |
- last_error_ = ASCIIToUTF16("Error writing to file."); |
+ for (Blacklist::ProviderList::const_iterator i = providers.begin(); |
+ i != providers.end(); ++i, ++current) { |
+ if (!output.StoreProvider((*i)->name(), (*i)->url())) |
return false; |
- } |
- index[*i] = current; |
+ index[i->get()] = current; |
} |
// Output entries, replacing the provider with its index. |
- if (!output.ReserveEntries(blacklist_.size())) { |
- last_error_ = ASCIIToUTF16("Error writing to file."); |
+ if (!output.ReserveEntries(entries.size())) |
return false; |
- } |
- for (std::list<Blacklist::Entry*>::const_iterator i = blacklist_.begin(); |
- i != blacklist_.end(); ++i) { |
+ for (Blacklist::EntryList::const_iterator i = entries.begin(); |
+ i != entries.end(); ++i) { |
if (!output.StoreEntry((*i)->pattern_, |
(*i)->attributes_, |
(*i)->types_, |
index[(*i)->provider_])) { |
- last_error_ = ASCIIToUTF16("Error writing to file."); |
return false; |
} |
} |