Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(133)

Side by Side Diff: chrome/browser/bookmarks/bookmark_codec.cc

Issue 99217: Implement ID persistence for bookmarks:... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/bookmarks/bookmark_codec.h" 5 #include "chrome/browser/bookmarks/bookmark_codec.h"
6 6
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 #include "base/values.h" 8 #include "base/values.h"
9 #include "chrome/browser/bookmarks/bookmark_model.h" 9 #include "chrome/browser/bookmarks/bookmark_model.h"
10 #include "chrome/common/l10n_util.h" 10 #include "chrome/common/l10n_util.h"
11 #include "googleurl/src/gurl.h" 11 #include "googleurl/src/gurl.h"
12 #include "grit/generated_resources.h" 12 #include "grit/generated_resources.h"
13 13
14 using base::Time; 14 using base::Time;
15 15
16 UniqueIDGenerator::UniqueIDGenerator() {
17 Reset();
18 }
19
20 int UniqueIDGenerator::GetUniqueID(int id) {
21 if (assigned_ids_.find(id) != assigned_ids_.end())
22 id = current_max_ + 1;
23
24 if (id > current_max_)
25 current_max_ = id;
26
27 assigned_ids_.insert(id);
28 return id;
29 }
30
31 void UniqueIDGenerator::Reset() {
32 current_max_ = 0;
33 assigned_ids_.clear();
34 // 0 should always be considered as an ID that's already generated.
35 assigned_ids_.insert(0);
36 }
37
16 const wchar_t* BookmarkCodec::kRootsKey = L"roots"; 38 const wchar_t* BookmarkCodec::kRootsKey = L"roots";
17 const wchar_t* BookmarkCodec::kRootFolderNameKey = L"bookmark_bar"; 39 const wchar_t* BookmarkCodec::kRootFolderNameKey = L"bookmark_bar";
18 const wchar_t* BookmarkCodec::kOtherBookmarFolderNameKey = L"other"; 40 const wchar_t* BookmarkCodec::kOtherBookmarFolderNameKey = L"other";
19 const wchar_t* BookmarkCodec::kVersionKey = L"version"; 41 const wchar_t* BookmarkCodec::kVersionKey = L"version";
20 const wchar_t* BookmarkCodec::kChecksumKey = L"checksum"; 42 const wchar_t* BookmarkCodec::kChecksumKey = L"checksum";
43 const wchar_t* BookmarkCodec::kIdKey = L"id";
21 const wchar_t* BookmarkCodec::kTypeKey = L"type"; 44 const wchar_t* BookmarkCodec::kTypeKey = L"type";
22 const wchar_t* BookmarkCodec::kNameKey = L"name"; 45 const wchar_t* BookmarkCodec::kNameKey = L"name";
23 const wchar_t* BookmarkCodec::kDateAddedKey = L"date_added"; 46 const wchar_t* BookmarkCodec::kDateAddedKey = L"date_added";
24 const wchar_t* BookmarkCodec::kURLKey = L"url"; 47 const wchar_t* BookmarkCodec::kURLKey = L"url";
25 const wchar_t* BookmarkCodec::kDateModifiedKey = L"date_modified"; 48 const wchar_t* BookmarkCodec::kDateModifiedKey = L"date_modified";
26 const wchar_t* BookmarkCodec::kChildrenKey = L"children"; 49 const wchar_t* BookmarkCodec::kChildrenKey = L"children";
27 const wchar_t* BookmarkCodec::kTypeURL = L"url"; 50 const wchar_t* BookmarkCodec::kTypeURL = L"url";
28 const wchar_t* BookmarkCodec::kTypeFolder = L"folder"; 51 const wchar_t* BookmarkCodec::kTypeFolder = L"folder";
29 52
30 // Current version of the file. 53 // Current version of the file.
31 static const int kCurrentVersion = 1; 54 static const int kCurrentVersion = 1;
32 55
56 BookmarkCodec::BookmarkCodec()
57 : persist_ids_(false) {
58 }
59
60 BookmarkCodec::BookmarkCodec(bool persist_ids)
61 : persist_ids_(persist_ids) {
62 }
63
33 Value* BookmarkCodec::Encode(BookmarkModel* model) { 64 Value* BookmarkCodec::Encode(BookmarkModel* model) {
34 return Encode(model->GetBookmarkBarNode(), model->other_node()); 65 return Encode(model->GetBookmarkBarNode(), model->other_node());
35 } 66 }
36 67
37 Value* BookmarkCodec::Encode(BookmarkNode* bookmark_bar_node, 68 Value* BookmarkCodec::Encode(BookmarkNode* bookmark_bar_node,
38 BookmarkNode* other_folder_node) { 69 BookmarkNode* other_folder_node) {
39 InitializeChecksum(); 70 InitializeChecksum();
40 DictionaryValue* roots = new DictionaryValue(); 71 DictionaryValue* roots = new DictionaryValue();
41 roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node)); 72 roots->Set(kRootFolderNameKey, EncodeNode(bookmark_bar_node));
42 roots->Set(kOtherBookmarFolderNameKey, EncodeNode(other_folder_node)); 73 roots->Set(kOtherBookmarFolderNameKey, EncodeNode(other_folder_node));
43 74
44 DictionaryValue* main = new DictionaryValue(); 75 DictionaryValue* main = new DictionaryValue();
45 main->SetInteger(kVersionKey, kCurrentVersion); 76 main->SetInteger(kVersionKey, kCurrentVersion);
46 FinalizeChecksum(); 77 FinalizeChecksum();
47 // We are going to store the computed checksum. So set stored checksum to be 78 // We are going to store the computed checksum. So set stored checksum to be
48 // the same as computed checksum. 79 // the same as computed checksum.
49 stored_checksum_ = computed_checksum_; 80 stored_checksum_ = computed_checksum_;
50 main->Set(kChecksumKey, Value::CreateStringValue(computed_checksum_)); 81 main->Set(kChecksumKey, Value::CreateStringValue(computed_checksum_));
51 main->Set(kRootsKey, roots); 82 main->Set(kRootsKey, roots);
52 return main; 83 return main;
53 } 84 }
54 85
55 bool BookmarkCodec::Decode(BookmarkModel* model, const Value& value) { 86 bool BookmarkCodec::Decode(BookmarkModel* model, const Value& value) {
87 id_generator_.Reset();
56 stored_checksum_.clear(); 88 stored_checksum_.clear();
57 InitializeChecksum(); 89 InitializeChecksum();
58 bool success = DecodeHelper(model, value); 90 bool success = DecodeHelper(model, value);
59 FinalizeChecksum(); 91 FinalizeChecksum();
92 BookmarkNode::SetNextId(id_generator_.current_max() + 1);
60 return success; 93 return success;
61 } 94 }
62 95
63 Value* BookmarkCodec::EncodeNode(BookmarkNode* node) { 96 Value* BookmarkCodec::EncodeNode(BookmarkNode* node) {
64 DictionaryValue* value = new DictionaryValue(); 97 DictionaryValue* value = new DictionaryValue();
98 std::string id;
99 if (persist_ids_) {
100 id = IntToString(node->id());
101 value->SetString(kIdKey, id);
102 }
65 const std::wstring& title = node->GetTitle(); 103 const std::wstring& title = node->GetTitle();
66 value->SetString(kNameKey, title); 104 value->SetString(kNameKey, title);
67 value->SetString(kDateAddedKey, 105 value->SetString(kDateAddedKey,
68 Int64ToWString(node->date_added().ToInternalValue())); 106 Int64ToWString(node->date_added().ToInternalValue()));
69 if (node->GetType() == history::StarredEntry::URL) { 107 if (node->GetType() == history::StarredEntry::URL) {
70 value->SetString(kTypeKey, kTypeURL); 108 value->SetString(kTypeKey, kTypeURL);
71 std::wstring url = UTF8ToWide(node->GetURL().possibly_invalid_spec()); 109 std::wstring url = UTF8ToWide(node->GetURL().possibly_invalid_spec());
72 value->SetString(kURLKey, url); 110 value->SetString(kURLKey, url);
73 UpdateChecksumWithUrlNode(title, url); 111 UpdateChecksumWithUrlNode(id, title, url);
74 } else { 112 } else {
75 value->SetString(kTypeKey, kTypeFolder); 113 value->SetString(kTypeKey, kTypeFolder);
76 value->SetString(kDateModifiedKey, 114 value->SetString(kDateModifiedKey,
77 Int64ToWString(node->date_group_modified(). 115 Int64ToWString(node->date_group_modified().
78 ToInternalValue())); 116 ToInternalValue()));
79 UpdateChecksumWithFolderNode(title); 117 UpdateChecksumWithFolderNode(id, title);
80 118
81 ListValue* child_values = new ListValue(); 119 ListValue* child_values = new ListValue();
82 value->Set(kChildrenKey, child_values); 120 value->Set(kChildrenKey, child_values);
83 for (int i = 0; i < node->GetChildCount(); ++i) 121 for (int i = 0; i < node->GetChildCount(); ++i)
84 child_values->Append(EncodeNode(node->GetChild(i))); 122 child_values->Append(EncodeNode(node->GetChild(i)));
85 } 123 }
86 return value; 124 return value;
87 } 125 }
88 126
89 bool BookmarkCodec::DecodeHelper(BookmarkModel* model, const Value& value) { 127 bool BookmarkCodec::DecodeHelper(BookmarkModel* model, const Value& value) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 return false; 193 return false;
156 } 194 }
157 } 195 }
158 return true; 196 return true;
159 } 197 }
160 198
161 bool BookmarkCodec::DecodeNode(BookmarkModel* model, 199 bool BookmarkCodec::DecodeNode(BookmarkModel* model,
162 const DictionaryValue& value, 200 const DictionaryValue& value,
163 BookmarkNode* parent, 201 BookmarkNode* parent,
164 BookmarkNode* node) { 202 BookmarkNode* node) {
203 std::string id_string;
204 int id = 0;
205 if (persist_ids_) {
206 if (value.GetString(kIdKey, &id_string))
207 if (!StringToInt(id_string, &id))
208 return false;
209 id = id_generator_.GetUniqueID(id);
210 }
211
165 std::wstring title; 212 std::wstring title;
166 if (!value.GetString(kNameKey, &title)) 213 if (!value.GetString(kNameKey, &title))
167 return false; 214 return false;
168 215
169 // TODO(sky): this should be more flexible. Don't hoark if we can't parse it 216 // TODO(sky): this should be more flexible. Don't hoark if we can't parse it
170 // all. 217 // all.
171 std::wstring date_added_string; 218 std::wstring date_added_string;
172 if (!value.GetString(kDateAddedKey, &date_added_string)) 219 if (!value.GetString(kDateAddedKey, &date_added_string))
173 return false; 220 return false;
174 221
175 std::wstring type_string; 222 std::wstring type_string;
176 if (!value.GetString(kTypeKey, &type_string)) 223 if (!value.GetString(kTypeKey, &type_string))
177 return false; 224 return false;
178 225
179 if (type_string != kTypeURL && type_string != kTypeFolder) 226 if (type_string != kTypeURL && type_string != kTypeFolder)
180 return false; // Unknown type. 227 return false; // Unknown type.
181 228
182 if (type_string == kTypeURL) { 229 if (type_string == kTypeURL) {
183 std::wstring url_string; 230 std::wstring url_string;
184 if (!value.GetString(kURLKey, &url_string)) 231 if (!value.GetString(kURLKey, &url_string))
185 return false; 232 return false;
186 // TODO(sky): this should ignore the node if not a valid URL. 233 // TODO(sky): this should ignore the node if not a valid URL.
187 if (!node) 234 if (!node)
188 node = new BookmarkNode(model, GURL(WideToUTF8(url_string))); 235 node = new BookmarkNode(model, id, GURL(WideToUTF8(url_string)));
236 else
237 NOTREACHED(); // In case of a URL type node should always be NULL.
238
239
189 if (parent) 240 if (parent)
190 parent->Add(parent->GetChildCount(), node); 241 parent->Add(parent->GetChildCount(), node);
191 node->type_ = history::StarredEntry::URL; 242 node->type_ = history::StarredEntry::URL;
192 UpdateChecksumWithUrlNode(title, url_string); 243 UpdateChecksumWithUrlNode(id_string, title, url_string);
193 } else { 244 } else {
194 std::wstring last_modified_date; 245 std::wstring last_modified_date;
195 if (!value.GetString(kDateModifiedKey, &last_modified_date)) 246 if (!value.GetString(kDateModifiedKey, &last_modified_date))
196 return false; 247 return false;
197 248
198 Value* child_values; 249 Value* child_values;
199 if (!value.Get(kChildrenKey, &child_values)) 250 if (!value.Get(kChildrenKey, &child_values))
200 return false; 251 return false;
201 252
202 if (child_values->GetType() != Value::TYPE_LIST) 253 if (child_values->GetType() != Value::TYPE_LIST)
203 return false; 254 return false;
204 255
205 if (!node) 256 if (!node) {
206 node = new BookmarkNode(model, GURL()); 257 node = new BookmarkNode(model, id, GURL());
258 } else if (persist_ids_) {
259 // If a new node is not created, explicitly assign persisted ID to the
260 // existing node.
261 DCHECK(id != 0);
262 node->set_id(id);
263 }
264
207 node->type_ = history::StarredEntry::USER_GROUP; 265 node->type_ = history::StarredEntry::USER_GROUP;
208 node->date_group_modified_ = Time::FromInternalValue( 266 node->date_group_modified_ = Time::FromInternalValue(
209 StringToInt64(WideToUTF16Hack(last_modified_date))); 267 StringToInt64(WideToUTF16Hack(last_modified_date)));
210 268
211 if (parent) 269 if (parent)
212 parent->Add(parent->GetChildCount(), node); 270 parent->Add(parent->GetChildCount(), node);
213 271
214 UpdateChecksumWithFolderNode(title); 272 UpdateChecksumWithFolderNode(id_string, title);
215 if (!DecodeChildren(model, *static_cast<ListValue*>(child_values), node)) 273 if (!DecodeChildren(model, *static_cast<ListValue*>(child_values), node))
216 return false; 274 return false;
217 } 275 }
218 276
219 node->SetTitle(title); 277 node->SetTitle(title);
220 node->date_added_ = Time::FromInternalValue( 278 node->date_added_ = Time::FromInternalValue(
221 StringToInt64(WideToUTF16Hack(date_added_string))); 279 StringToInt64(WideToUTF16Hack(date_added_string)));
222 return true; 280 return true;
223 } 281 }
224 282
225 void BookmarkCodec::UpdateChecksum(const std::string& str) { 283 void BookmarkCodec::UpdateChecksum(const std::string& str) {
226 MD5Update(&md5_context_, str.data(), str.length() * sizeof(char)); 284 MD5Update(&md5_context_, str.data(), str.length() * sizeof(char));
227 } 285 }
228 286
229 void BookmarkCodec::UpdateChecksum(const std::wstring& str) { 287 void BookmarkCodec::UpdateChecksum(const std::wstring& str) {
230 MD5Update(&md5_context_, str.data(), str.length() * sizeof(wchar_t)); 288 MD5Update(&md5_context_, str.data(), str.length() * sizeof(wchar_t));
231 } 289 }
232 290
233 void BookmarkCodec::UpdateChecksumWithUrlNode(const std::wstring& title, 291 void BookmarkCodec::UpdateChecksumWithUrlNode(const std::string& id,
292 const std::wstring& title,
234 const std::wstring& url) { 293 const std::wstring& url) {
294 UpdateChecksum(id);
235 UpdateChecksum(title); 295 UpdateChecksum(title);
236 UpdateChecksum(kTypeURL); 296 UpdateChecksum(kTypeURL);
237 UpdateChecksum(url); 297 UpdateChecksum(url);
238 } 298 }
239 299
240 void BookmarkCodec::UpdateChecksumWithFolderNode(const std::wstring& title) { 300 void BookmarkCodec::UpdateChecksumWithFolderNode(const std::string& id,
301 const std::wstring& title) {
302 UpdateChecksum(id);
241 UpdateChecksum(title); 303 UpdateChecksum(title);
242 UpdateChecksum(kTypeFolder); 304 UpdateChecksum(kTypeFolder);
243 } 305 }
244 306
245 void BookmarkCodec::InitializeChecksum() { 307 void BookmarkCodec::InitializeChecksum() {
246 MD5Init(&md5_context_); 308 MD5Init(&md5_context_);
247 } 309 }
248 310
249 void BookmarkCodec::FinalizeChecksum() { 311 void BookmarkCodec::FinalizeChecksum() {
250 MD5Digest digest; 312 MD5Digest digest;
251 MD5Final(&digest, &md5_context_); 313 MD5Final(&digest, &md5_context_);
252 computed_checksum_ = MD5DigestToBase16(digest); 314 computed_checksum_ = MD5DigestToBase16(digest);
253 } 315 }
254 316
OLDNEW
« no previous file with comments | « chrome/browser/bookmarks/bookmark_codec.h ('k') | chrome/browser/bookmarks/bookmark_codec_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698