1 // Copyright 2014 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 #ifndef COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_CODEC_H_ 6 #define COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_CODEC_H_ 7 8 #include <set> 9 #include <string> 10 11 #include "base/basictypes.h" 12 #include "base/md5.h" 13 #include "base/strings/string16.h" 14 #include "components/bookmarks/browser/bookmark_node.h" 15 16 class BookmarkModel; 17 18 namespace base { 19 class DictionaryValue; 20 class ListValue; 21 class Value; 22 } 23 24 namespace bookmarks { 25 26 // BookmarkCodec is responsible for encoding and decoding the BookmarkModel 27 // into JSON values. The encoded values are written to disk via the 28 // BookmarkStorage. 29 class 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 base::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 base::Value* Encode(const BookmarkNode* bookmark_bar_node, 47 const BookmarkNode* other_folder_node, 48 const BookmarkNode* mobile_folder_node, 49 const BookmarkNode::MetaInfoMap* model_meta_info_map, 50 int64 sync_transaction_version); 51 52 // Decodes the previously encoded value to the specified nodes as well as 53 // setting |max_node_id| to the greatest node id. Returns true on success, 54 // false otherwise. If there is an error (such as unexpected version) all 55 // children are removed from the bookmark bar and other folder nodes. On exit 56 // |max_node_id| is set to the max id of the nodes. 57 bool Decode(BookmarkNode* bb_node, 58 BookmarkNode* other_folder_node, 59 BookmarkNode* mobile_folder_node, 60 int64* max_node_id, 61 const base::Value& value); 62 63 // Returns the checksum computed during last encoding/decoding call. computed_checksum()64 const std::string& computed_checksum() const { return computed_checksum_; } 65 66 // Returns the checksum that's stored in the file. After a call to Encode, 67 // the computed and stored checksums are the same since the computed checksum 68 // is stored to the file. After a call to decode, the computed checksum can 69 // differ from the stored checksum if the file contents were changed by the 70 // user. stored_checksum()71 const std::string& stored_checksum() const { return stored_checksum_; } 72 73 // Return meta info of bookmark model root. model_meta_info_map()74 const BookmarkNode::MetaInfoMap& model_meta_info_map() const { 75 return model_meta_info_map_; 76 } 77 78 // Return the sync transaction version of the bookmark model root. model_sync_transaction_version()79 int64 model_sync_transaction_version() const { 80 return model_sync_transaction_version_; 81 } 82 83 // Returns whether the IDs were reassigned during decoding. Always returns 84 // false after encoding. ids_reassigned()85 bool ids_reassigned() const { return ids_reassigned_; } 86 87 // Names of the various keys written to the Value. 88 static const char* kRootsKey; 89 static const char* kRootFolderNameKey; 90 static const char* kOtherBookmarkFolderNameKey; 91 static const char* kMobileBookmarkFolderNameKey; 92 static const char* kVersionKey; 93 static const char* kChecksumKey; 94 static const char* kIdKey; 95 static const char* kTypeKey; 96 static const char* kNameKey; 97 static const char* kDateAddedKey; 98 static const char* kURLKey; 99 static const char* kDateModifiedKey; 100 static const char* kChildrenKey; 101 static const char* kMetaInfo; 102 static const char* kSyncTransactionVersion; 103 104 // Possible values for kTypeKey. 105 static const char* kTypeURL; 106 static const char* kTypeFolder; 107 108 private: 109 // Encodes node and all its children into a Value object and returns it. 110 // The caller takes ownership of the returned object. 111 base::Value* EncodeNode(const BookmarkNode* node); 112 113 // Encodes the given meta info into a Value object and returns it. The caller 114 // takes ownership of the returned object. 115 base::Value* EncodeMetaInfo(const BookmarkNode::MetaInfoMap& meta_info_map); 116 117 // Helper to perform decoding. 118 bool DecodeHelper(BookmarkNode* bb_node, 119 BookmarkNode* other_folder_node, 120 BookmarkNode* mobile_folder_node, 121 const base::Value& value); 122 123 // Decodes the children of the specified node. Returns true on success. 124 bool DecodeChildren(const base::ListValue& child_value_list, 125 BookmarkNode* parent); 126 127 // Reassigns bookmark IDs for all nodes. 128 void ReassignIDs(BookmarkNode* bb_node, 129 BookmarkNode* other_node, 130 BookmarkNode* mobile_node); 131 132 // Helper to recursively reassign IDs. 133 void ReassignIDsHelper(BookmarkNode* node); 134 135 // Decodes the supplied node from the supplied value. Child nodes are 136 // created appropriately by way of DecodeChildren. If node is NULL a new 137 // node is created and added to parent (parent must then be non-NULL), 138 // otherwise node is used. 139 bool DecodeNode(const base::DictionaryValue& value, 140 BookmarkNode* parent, 141 BookmarkNode* node); 142 143 // Decodes the meta info from the supplied value. If the meta info contains 144 // a "sync.transaction_version" key, the value of that field will be stored 145 // in the sync_transaction_version variable, then deleted. This is for 146 // backward-compatibility reasons. 147 // meta_info_map and sync_transaction_version must not be NULL. 148 bool DecodeMetaInfo(const base::DictionaryValue& value, 149 BookmarkNode::MetaInfoMap* meta_info_map, 150 int64* sync_transaction_version); 151 152 // Decodes the meta info from the supplied sub-node dictionary. The values 153 // found will be inserted in meta_info_map with the given prefix added to the 154 // start of their keys. 155 void DecodeMetaInfoHelper(const base::DictionaryValue& dict, 156 const std::string& prefix, 157 BookmarkNode::MetaInfoMap* meta_info_map); 158 159 // Updates the check-sum with the given string. 160 void UpdateChecksum(const std::string& str); 161 void UpdateChecksum(const base::string16& str); 162 163 // Updates the check-sum with the given contents of URL/folder bookmark node. 164 // NOTE: These functions take in individual properties of a bookmark node 165 // instead of taking in a BookmarkNode for efficiency so that we don't convert 166 // various data-types to UTF16 strings multiple times - once for serializing 167 // and once for computing the check-sum. 168 // The url parameter should be a valid UTF8 string. 169 void UpdateChecksumWithUrlNode(const std::string& id, 170 const base::string16& title, 171 const std::string& url); 172 void UpdateChecksumWithFolderNode(const std::string& id, 173 const base::string16& title); 174 175 // Initializes/Finalizes the checksum. 176 void InitializeChecksum(); 177 void FinalizeChecksum(); 178 179 // Whether or not IDs were reassigned by the codec. 180 bool ids_reassigned_; 181 182 // Whether or not IDs are valid. This is initially true, but set to false 183 // if an id is missing or not unique. 184 bool ids_valid_; 185 186 // Contains the id of each of the nodes found in the file. Used to determine 187 // if we have duplicates. 188 std::set<int64> ids_; 189 190 // MD5 context used to compute MD5 hash of all bookmark data. 191 base::MD5Context md5_context_; 192 193 // Checksums. 194 std::string computed_checksum_; 195 std::string stored_checksum_; 196 197 // Maximum ID assigned when decoding data. 198 int64 maximum_id_; 199 200 // Meta info set on bookmark model root. 201 BookmarkNode::MetaInfoMap model_meta_info_map_; 202 203 // Sync transaction version set on bookmark model root. 204 int64 model_sync_transaction_version_; 205 206 DISALLOW_COPY_AND_ASSIGN(BookmarkCodec); 207 }; 208 209 } // namespace bookmarks 210 211 #endif // COMPONENTS_BOOKMARKS_BROWSER_BOOKMARK_CODEC_H_ 212