1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// BookmarkCodec is responsible for encoding and decoding the BookmarkModel
6// into JSON values. The encoded values are written to disk via the
7// BookmarkService.
8
9#ifndef CHROME_BROWSER_BOOKMARKS_BOOKMARK_CODEC_H_
10#define CHROME_BROWSER_BOOKMARKS_BOOKMARK_CODEC_H_
11#pragma once
12
13#include <set>
14#include <string>
15
16#include "base/basictypes.h"
17#include "base/md5.h"
18#include "base/string16.h"
19
20class BookmarkModel;
21class BookmarkNode;
22class DictionaryValue;
23class ListValue;
24class Value;
25
26// BookmarkCodec is responsible for encoding/decoding bookmarks into JSON
27// values. BookmarkCodec is used by BookmarkService.
28
29class BookmarkCodec {
30 public:
31  // Creates an instance of the codec. During decoding, if the IDs in the file
32  // are not unique, we will reassign IDs to make them unique. There are no
33  // guarantees on how the IDs are reassigned or about doing minimal
34  // reassignments to achieve uniqueness.
35  BookmarkCodec();
36  ~BookmarkCodec();
37
38  // Encodes the model to a JSON value. It's up to the caller to delete the
39  // returned object. This is invoked to encode the contents of the bookmark bar
40  // model and is currently a convenience to invoking Encode that takes the
41  // bookmark bar node and other folder node.
42  Value* Encode(BookmarkModel* model);
43
44  // Encodes the bookmark bar and other folders returning the JSON value. It's
45  // up to the caller to delete the returned object.
46  // This method is public for use by StarredURLDatabase in migrating the
47  // bookmarks out of the database.
48  Value* Encode(const BookmarkNode* bookmark_bar_node,
49                const BookmarkNode* other_folder_node);
50
51  // Decodes the previously encoded value to the specified nodes as well as
52  // setting |max_node_id| to the greatest node id. Returns true on success,
53  // false otherwise. If there is an error (such as unexpected version) all
54  // children are removed from the bookmark bar and other folder nodes. On exit
55  // |max_node_id| is set to the max id of the nodes.
56  bool Decode(BookmarkNode* bb_node,
57              BookmarkNode* other_folder_node,
58              int64* max_node_id,
59              const Value& value);
60
61  // Returns the checksum computed during last encoding/decoding call.
62  const std::string& computed_checksum() const { return computed_checksum_; }
63
64  // Returns the checksum that's stored in the file. After a call to Encode,
65  // the computed and stored checksums are the same since the computed checksum
66  // is stored to the file. After a call to decode, the computed checksum can
67  // differ from the stored checksum if the file contents were changed by the
68  // user.
69  const std::string& stored_checksum() const { return stored_checksum_; }
70
71  // Returns whether the IDs were reassigned during decoding. Always returns
72  // false after encoding.
73  bool ids_reassigned() const { return ids_reassigned_; }
74
75  // Names of the various keys written to the Value.
76  static const char* kRootsKey;
77  static const char* kRootFolderNameKey;
78  static const char* kOtherBookmarkFolderNameKey;
79  static const char* kVersionKey;
80  static const char* kChecksumKey;
81  static const char* kIdKey;
82  static const char* kTypeKey;
83  static const char* kNameKey;
84  static const char* kDateAddedKey;
85  static const char* kURLKey;
86  static const char* kDateModifiedKey;
87  static const char* kChildrenKey;
88
89  // Possible values for kTypeKey.
90  static const char* kTypeURL;
91  static const char* kTypeFolder;
92
93 private:
94  // Encodes node and all its children into a Value object and returns it.
95  // The caller takes ownership of the returned object.
96  Value* EncodeNode(const BookmarkNode* node);
97
98  // Helper to perform decoding.
99  bool DecodeHelper(BookmarkNode* bb_node,
100                    BookmarkNode* other_folder_node,
101                    const Value& value);
102
103  // Decodes the children of the specified node. Returns true on success.
104  bool DecodeChildren(const ListValue& child_value_list,
105                      BookmarkNode* parent);
106
107  // Reassigns bookmark IDs for all nodes.
108  void ReassignIDs(BookmarkNode* bb_node, BookmarkNode* other_node);
109
110  // Helper to recursively reassign IDs.
111  void ReassignIDsHelper(BookmarkNode* node);
112
113  // Decodes the supplied node from the supplied value. Child nodes are
114  // created appropriately by way of DecodeChildren. If node is NULL a new
115  // node is created and added to parent (parent must then be non-NULL),
116  // otherwise node is used.
117  bool DecodeNode(const DictionaryValue& value,
118                  BookmarkNode* parent,
119                  BookmarkNode* node);
120
121  // Updates the check-sum with the given string.
122  void UpdateChecksum(const std::string& str);
123  void UpdateChecksum(const string16& str);
124
125  // Updates the check-sum with the given contents of URL/folder bookmark node.
126  // NOTE: These functions take in individual properties of a bookmark node
127  // instead of taking in a BookmarkNode for efficiency so that we don't convert
128  // various data-types to UTF16 strings multiple times - once for serializing
129  // and once for computing the check-sum.
130  // The url parameter should be a valid UTF8 string.
131  void UpdateChecksumWithUrlNode(const std::string& id,
132                                 const string16& title,
133                                 const std::string& url);
134  void UpdateChecksumWithFolderNode(const std::string& id,
135                                    const string16& title);
136
137  // Initializes/Finalizes the checksum.
138  void InitializeChecksum();
139  void FinalizeChecksum();
140
141  // Whether or not IDs were reassigned by the codec.
142  bool ids_reassigned_;
143
144  // Whether or not IDs are valid. This is initially true, but set to false
145  // if an id is missing or not unique.
146  bool ids_valid_;
147
148  // Contains the id of each of the nodes found in the file. Used to determine
149  // if we have duplicates.
150  std::set<int64> ids_;
151
152  // MD5 context used to compute MD5 hash of all bookmark data.
153  MD5Context md5_context_;
154
155  // Checksums.
156  std::string computed_checksum_;
157  std::string stored_checksum_;
158
159  // Maximum ID assigned when decoding data.
160  int64 maximum_id_;
161
162  DISALLOW_COPY_AND_ASSIGN(BookmarkCodec);
163};
164
165#endif  // CHROME_BROWSER_BOOKMARKS_BOOKMARK_CODEC_H_
166