| Index: chrome/browser/bookmarks/bookmark_codec.cc
|
| ===================================================================
|
| --- chrome/browser/bookmarks/bookmark_codec.cc (revision 14989)
|
| +++ chrome/browser/bookmarks/bookmark_codec.cc (working copy)
|
| @@ -13,11 +13,34 @@
|
|
|
| using base::Time;
|
|
|
| +UniqueIDGenerator::UniqueIDGenerator() {
|
| + Reset();
|
| +}
|
| +
|
| +int UniqueIDGenerator::GetUniqueID(int id) {
|
| + if (assigned_ids_.find(id) != assigned_ids_.end())
|
| + id = current_max_ + 1;
|
| +
|
| + if (id > current_max_)
|
| + current_max_ = id;
|
| +
|
| + assigned_ids_.insert(id);
|
| + return id;
|
| +}
|
| +
|
| +void UniqueIDGenerator::Reset() {
|
| + current_max_ = 0;
|
| + assigned_ids_.clear();
|
| + // 0 should always be considered as an ID that's already generated.
|
| + assigned_ids_.insert(0);
|
| +}
|
| +
|
| const wchar_t* BookmarkCodec::kRootsKey = L"roots";
|
| const wchar_t* BookmarkCodec::kRootFolderNameKey = L"bookmark_bar";
|
| const wchar_t* BookmarkCodec::kOtherBookmarFolderNameKey = L"other";
|
| const wchar_t* BookmarkCodec::kVersionKey = L"version";
|
| const wchar_t* BookmarkCodec::kChecksumKey = L"checksum";
|
| +const wchar_t* BookmarkCodec::kIdKey = L"id";
|
| const wchar_t* BookmarkCodec::kTypeKey = L"type";
|
| const wchar_t* BookmarkCodec::kNameKey = L"name";
|
| const wchar_t* BookmarkCodec::kDateAddedKey = L"date_added";
|
| @@ -30,6 +53,14 @@
|
| // Current version of the file.
|
| static const int kCurrentVersion = 1;
|
|
|
| +BookmarkCodec::BookmarkCodec()
|
| + : persist_ids_(false) {
|
| +}
|
| +
|
| +BookmarkCodec::BookmarkCodec(bool persist_ids)
|
| + : persist_ids_(persist_ids) {
|
| +}
|
| +
|
| Value* BookmarkCodec::Encode(BookmarkModel* model) {
|
| return Encode(model->GetBookmarkBarNode(), model->other_node());
|
| }
|
| @@ -53,15 +84,22 @@
|
| }
|
|
|
| bool BookmarkCodec::Decode(BookmarkModel* model, const Value& value) {
|
| + id_generator_.Reset();
|
| stored_checksum_.clear();
|
| InitializeChecksum();
|
| bool success = DecodeHelper(model, value);
|
| FinalizeChecksum();
|
| + BookmarkNode::SetNextId(id_generator_.current_max() + 1);
|
| return success;
|
| }
|
|
|
| Value* BookmarkCodec::EncodeNode(BookmarkNode* node) {
|
| DictionaryValue* value = new DictionaryValue();
|
| + std::string id;
|
| + if (persist_ids_) {
|
| + id = IntToString(node->id());
|
| + value->SetString(kIdKey, id);
|
| + }
|
| const std::wstring& title = node->GetTitle();
|
| value->SetString(kNameKey, title);
|
| value->SetString(kDateAddedKey,
|
| @@ -70,13 +108,13 @@
|
| value->SetString(kTypeKey, kTypeURL);
|
| std::wstring url = UTF8ToWide(node->GetURL().possibly_invalid_spec());
|
| value->SetString(kURLKey, url);
|
| - UpdateChecksumWithUrlNode(title, url);
|
| + UpdateChecksumWithUrlNode(id, title, url);
|
| } else {
|
| value->SetString(kTypeKey, kTypeFolder);
|
| value->SetString(kDateModifiedKey,
|
| Int64ToWString(node->date_group_modified().
|
| ToInternalValue()));
|
| - UpdateChecksumWithFolderNode(title);
|
| + UpdateChecksumWithFolderNode(id, title);
|
|
|
| ListValue* child_values = new ListValue();
|
| value->Set(kChildrenKey, child_values);
|
| @@ -162,6 +200,15 @@
|
| const DictionaryValue& value,
|
| BookmarkNode* parent,
|
| BookmarkNode* node) {
|
| + std::string id_string;
|
| + int id = 0;
|
| + if (persist_ids_) {
|
| + if (value.GetString(kIdKey, &id_string))
|
| + if (!StringToInt(id_string, &id))
|
| + return false;
|
| + id = id_generator_.GetUniqueID(id);
|
| + }
|
| +
|
| std::wstring title;
|
| if (!value.GetString(kNameKey, &title))
|
| return false;
|
| @@ -185,11 +232,15 @@
|
| return false;
|
| // TODO(sky): this should ignore the node if not a valid URL.
|
| if (!node)
|
| - node = new BookmarkNode(model, GURL(WideToUTF8(url_string)));
|
| + node = new BookmarkNode(model, id, GURL(WideToUTF8(url_string)));
|
| + else
|
| + NOTREACHED(); // In case of a URL type node should always be NULL.
|
| +
|
| +
|
| if (parent)
|
| parent->Add(parent->GetChildCount(), node);
|
| node->type_ = history::StarredEntry::URL;
|
| - UpdateChecksumWithUrlNode(title, url_string);
|
| + UpdateChecksumWithUrlNode(id_string, title, url_string);
|
| } else {
|
| std::wstring last_modified_date;
|
| if (!value.GetString(kDateModifiedKey, &last_modified_date))
|
| @@ -202,8 +253,15 @@
|
| if (child_values->GetType() != Value::TYPE_LIST)
|
| return false;
|
|
|
| - if (!node)
|
| - node = new BookmarkNode(model, GURL());
|
| + if (!node) {
|
| + node = new BookmarkNode(model, id, GURL());
|
| + } else if (persist_ids_) {
|
| + // If a new node is not created, explicitly assign persisted ID to the
|
| + // existing node.
|
| + DCHECK(id != 0);
|
| + node->set_id(id);
|
| + }
|
| +
|
| node->type_ = history::StarredEntry::USER_GROUP;
|
| node->date_group_modified_ = Time::FromInternalValue(
|
| StringToInt64(WideToUTF16Hack(last_modified_date)));
|
| @@ -211,7 +269,7 @@
|
| if (parent)
|
| parent->Add(parent->GetChildCount(), node);
|
|
|
| - UpdateChecksumWithFolderNode(title);
|
| + UpdateChecksumWithFolderNode(id_string, title);
|
| if (!DecodeChildren(model, *static_cast<ListValue*>(child_values), node))
|
| return false;
|
| }
|
| @@ -230,14 +288,18 @@
|
| MD5Update(&md5_context_, str.data(), str.length() * sizeof(wchar_t));
|
| }
|
|
|
| -void BookmarkCodec::UpdateChecksumWithUrlNode(const std::wstring& title,
|
| +void BookmarkCodec::UpdateChecksumWithUrlNode(const std::string& id,
|
| + const std::wstring& title,
|
| const std::wstring& url) {
|
| + UpdateChecksum(id);
|
| UpdateChecksum(title);
|
| UpdateChecksum(kTypeURL);
|
| UpdateChecksum(url);
|
| }
|
|
|
| -void BookmarkCodec::UpdateChecksumWithFolderNode(const std::wstring& title) {
|
| +void BookmarkCodec::UpdateChecksumWithFolderNode(const std::string& id,
|
| + const std::wstring& title) {
|
| + UpdateChecksum(id);
|
| UpdateChecksum(title);
|
| UpdateChecksum(kTypeFolder);
|
| }
|
|
|