summaryrefslogtreecommitdiffstats
path: root/components/bookmarks/browser/bookmark_codec.h
blob: 4697e79f4ded40846000dffc1ab1320c0e0b6dd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_CODEC_H_
#define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_CODEC_H_

#include <stdint.h>
#include <set>
#include <string>

#include "base/macros.h"
#include "base/md5.h"
#include "base/strings/string16.h"
#include "components/bookmarks/browser/bookmark_node.h"

namespace base {
class DictionaryValue;
class ListValue;
class Value;
}

namespace bookmarks {

class BookmarkModel;

// BookmarkCodec is responsible for encoding and decoding the BookmarkModel
// into JSON values. The encoded values are written to disk via the
// BookmarkStorage.
class BookmarkCodec {
 public:
  // Creates an instance of the codec. During decoding, if the IDs in the file
  // are not unique, we will reassign IDs to make them unique. There are no
  // guarantees on how the IDs are reassigned or about doing minimal
  // reassignments to achieve uniqueness.
  BookmarkCodec();
  ~BookmarkCodec();

  // Encodes the model to a JSON value. It's up to the caller to delete the
  // returned object. This is invoked to encode the contents of the bookmark bar
  // model and is currently a convenience to invoking Encode that takes the
  // bookmark bar node and other folder node.
  base::Value* Encode(BookmarkModel* model);

  // Encodes the bookmark bar and other folders returning the JSON value. It's
  // up to the caller to delete the returned object.
  base::Value* Encode(const BookmarkNode* bookmark_bar_node,
                      const BookmarkNode* other_folder_node,
                      const BookmarkNode* mobile_folder_node,
                      const BookmarkNode::MetaInfoMap* model_meta_info_map,
                      int64_t sync_transaction_version);

  // Decodes the previously encoded value to the specified nodes as well as
  // setting |max_node_id| to the greatest node id. Returns true on success,
  // false otherwise. If there is an error (such as unexpected version) all
  // children are removed from the bookmark bar and other folder nodes. On exit
  // |max_node_id| is set to the max id of the nodes.
  bool Decode(BookmarkNode* bb_node,
              BookmarkNode* other_folder_node,
              BookmarkNode* mobile_folder_node,
              int64_t* max_node_id,
              const base::Value& value);

  // Returns the checksum computed during last encoding/decoding call.
  const std::string& computed_checksum() const { return computed_checksum_; }

  // Returns the checksum that's stored in the file. After a call to Encode,
  // the computed and stored checksums are the same since the computed checksum
  // is stored to the file. After a call to decode, the computed checksum can
  // differ from the stored checksum if the file contents were changed by the
  // user.
  const std::string& stored_checksum() const { return stored_checksum_; }

  // Return meta info of bookmark model root.
  const BookmarkNode::MetaInfoMap& model_meta_info_map() const {
    return model_meta_info_map_;
  }

  // Return the sync transaction version of the bookmark model root.
  int64_t model_sync_transaction_version() const {
    return model_sync_transaction_version_;
  }

  // Returns whether the IDs were reassigned during decoding. Always returns
  // false after encoding.
  bool ids_reassigned() const { return ids_reassigned_; }

  // Names of the various keys written to the Value.
  static const char* kRootsKey;
  static const char* kRootFolderNameKey;
  static const char* kOtherBookmarkFolderNameKey;
  static const char* kMobileBookmarkFolderNameKey;
  static const char* kVersionKey;
  static const char* kChecksumKey;
  static const char* kIdKey;
  static const char* kTypeKey;
  static const char* kNameKey;
  static const char* kDateAddedKey;
  static const char* kURLKey;
  static const char* kDateModifiedKey;
  static const char* kChildrenKey;
  static const char* kMetaInfo;
  static const char* kSyncTransactionVersion;

  // Possible values for kTypeKey.
  static const char* kTypeURL;
  static const char* kTypeFolder;

 private:
  // Encodes node and all its children into a Value object and returns it.
  // The caller takes ownership of the returned object.
  base::Value* EncodeNode(const BookmarkNode* node);

  // Encodes the given meta info into a Value object and returns it. The caller
  // takes ownership of the returned object.
  base::Value* EncodeMetaInfo(const BookmarkNode::MetaInfoMap& meta_info_map);

  // Helper to perform decoding.
  bool DecodeHelper(BookmarkNode* bb_node,
                    BookmarkNode* other_folder_node,
                    BookmarkNode* mobile_folder_node,
                    const base::Value& value);

  // Decodes the children of the specified node. Returns true on success.
  bool DecodeChildren(const base::ListValue& child_value_list,
                      BookmarkNode* parent);

  // Reassigns bookmark IDs for all nodes.
  void ReassignIDs(BookmarkNode* bb_node,
                   BookmarkNode* other_node,
                   BookmarkNode* mobile_node);

  // Helper to recursively reassign IDs.
  void ReassignIDsHelper(BookmarkNode* node);

  // Decodes the supplied node from the supplied value. Child nodes are
  // created appropriately by way of DecodeChildren. If node is NULL a new
  // node is created and added to parent (parent must then be non-NULL),
  // otherwise node is used.
  bool DecodeNode(const base::DictionaryValue& value,
                  BookmarkNode* parent,
                  BookmarkNode* node);

  // Decodes the meta info from the supplied value. If the meta info contains
  // a "sync.transaction_version" key, the value of that field will be stored
  // in the sync_transaction_version variable, then deleted. This is for
  // backward-compatibility reasons.
  // meta_info_map and sync_transaction_version must not be NULL.
  bool DecodeMetaInfo(const base::DictionaryValue& value,
                      BookmarkNode::MetaInfoMap* meta_info_map,
                      int64_t* sync_transaction_version);

  // Decodes the meta info from the supplied sub-node dictionary. The values
  // found will be inserted in meta_info_map with the given prefix added to the
  // start of their keys.
  void DecodeMetaInfoHelper(const base::DictionaryValue& dict,
                            const std::string& prefix,
                            BookmarkNode::MetaInfoMap* meta_info_map);

  // Updates the check-sum with the given string.
  void UpdateChecksum(const std::string& str);
  void UpdateChecksum(const base::string16& str);

  // Updates the check-sum with the given contents of URL/folder bookmark node.
  // NOTE: These functions take in individual properties of a bookmark node
  // instead of taking in a BookmarkNode for efficiency so that we don't convert
  // various data-types to UTF16 strings multiple times - once for serializing
  // and once for computing the check-sum.
  // The url parameter should be a valid UTF8 string.
  void UpdateChecksumWithUrlNode(const std::string& id,
                                 const base::string16& title,
                                 const std::string& url);
  void UpdateChecksumWithFolderNode(const std::string& id,
                                    const base::string16& title);

  // Initializes/Finalizes the checksum.
  void InitializeChecksum();
  void FinalizeChecksum();

  // Whether or not IDs were reassigned by the codec.
  bool ids_reassigned_;

  // Whether or not IDs are valid. This is initially true, but set to false
  // if an id is missing or not unique.
  bool ids_valid_;

  // Contains the id of each of the nodes found in the file. Used to determine
  // if we have duplicates.
  std::set<int64_t> ids_;

  // MD5 context used to compute MD5 hash of all bookmark data.
  base::MD5Context md5_context_;

  // Checksums.
  std::string computed_checksum_;
  std::string stored_checksum_;

  // Maximum ID assigned when decoding data.
  int64_t maximum_id_;

  // Meta info set on bookmark model root.
  BookmarkNode::MetaInfoMap model_meta_info_map_;

  // Sync transaction version set on bookmark model root.
  int64_t model_sync_transaction_version_;

  DISALLOW_COPY_AND_ASSIGN(BookmarkCodec);
};

}  // namespace bookmarks

#endif  // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_CODEC_H_