extensionview: Update loadNextSrc comments.
[chromium-blink-merge.git] / sync / syncable / entry_kernel.cc
blobd73acafd850f76d58590ed2a70cb17fe976b0fb9
1 // Copyright (c) 2012 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.
5 #include "sync/syncable/entry_kernel.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "sync/protocol/proto_value_conversions.h"
9 #include "sync/syncable/syncable_enum_conversions.h"
10 #include "sync/util/cryptographer.h"
12 namespace syncer {
13 namespace syncable {
15 EntryKernel::EntryKernel() : dirty_(false) {
16 // Everything else should already be default-initialized.
17 for (int i = 0; i < INT64_FIELDS_COUNT; ++i) {
18 int64_fields[i] = 0;
22 EntryKernel::~EntryKernel() {}
24 ModelType EntryKernel::GetModelType() const {
25 ModelType specifics_type = GetModelTypeFromSpecifics(ref(SPECIFICS));
26 if (specifics_type != UNSPECIFIED)
27 return specifics_type;
28 if (ref(ID).IsRoot())
29 return TOP_LEVEL_FOLDER;
30 // Loose check for server-created top-level folders that aren't
31 // bound to a particular model type.
32 if (!ref(UNIQUE_SERVER_TAG).empty() && ref(SERVER_IS_DIR))
33 return TOP_LEVEL_FOLDER;
35 return UNSPECIFIED;
38 ModelType EntryKernel::GetServerModelType() const {
39 ModelType specifics_type = GetModelTypeFromSpecifics(ref(SERVER_SPECIFICS));
40 if (specifics_type != UNSPECIFIED)
41 return specifics_type;
42 if (ref(ID).IsRoot())
43 return TOP_LEVEL_FOLDER;
44 // Loose check for server-created top-level folders that aren't
45 // bound to a particular model type.
46 if (!ref(UNIQUE_SERVER_TAG).empty() && ref(SERVER_IS_DIR))
47 return TOP_LEVEL_FOLDER;
49 return UNSPECIFIED;
52 bool EntryKernel::ShouldMaintainPosition() const {
53 // We maintain positions for all bookmarks, except those that are
54 // server-created top-level folders.
55 return TypeSupportsOrdering(GetModelTypeFromSpecifics(ref(SPECIFICS))) &&
56 !(!ref(UNIQUE_SERVER_TAG).empty() && ref(IS_DIR));
59 bool EntryKernel::ShouldMaintainHierarchy() const {
60 // We maintain hierarchy for bookmarks and top-level folders,
61 // but no other types. Note that the Nigori node consists of a single
62 // top-level folder, so it's included in this set.
63 return TypeSupportsHierarchy(GetModelTypeFromSpecifics(ref(SPECIFICS))) ||
64 (!ref(UNIQUE_SERVER_TAG).empty());
67 namespace {
69 // Utility function to loop through a set of enum values and add the
70 // field keys/values in the kernel to the given dictionary.
72 // V should be convertible to Value.
73 template <class T, class U, class V>
74 void SetFieldValues(const EntryKernel& kernel,
75 base::DictionaryValue* dictionary_value,
76 const char* (*enum_key_fn)(T),
77 V* (*enum_value_fn)(U),
78 int field_key_min, int field_key_max) {
79 DCHECK_LE(field_key_min, field_key_max);
80 for (int i = field_key_min; i <= field_key_max; ++i) {
81 T field = static_cast<T>(i);
82 const std::string& key = enum_key_fn(field);
83 V* value = enum_value_fn(kernel.ref(field));
84 dictionary_value->Set(key, value);
88 void SetEncryptableProtoValues(
89 const EntryKernel& kernel,
90 Cryptographer* cryptographer,
91 base::DictionaryValue* dictionary_value,
92 int field_key_min, int field_key_max) {
93 DCHECK_LE(field_key_min, field_key_max);
94 for (int i = field_key_min; i <= field_key_max; ++i) {
95 ProtoField field = static_cast<ProtoField>(i);
96 const std::string& key = GetProtoFieldString(field);
98 scoped_ptr<base::DictionaryValue> value;
99 sync_pb::EntitySpecifics decrypted;
100 const sync_pb::EncryptedData& encrypted = kernel.ref(field).encrypted();
101 if (cryptographer &&
102 kernel.ref(field).has_encrypted() &&
103 cryptographer->CanDecrypt(encrypted) &&
104 cryptographer->Decrypt(encrypted, &decrypted)) {
105 value = EntitySpecificsToValue(decrypted);
106 value->SetBoolean("encrypted", true);
107 } else {
108 value = EntitySpecificsToValue(kernel.ref(field));
110 dictionary_value->Set(key, value.Pass());
114 // Helper functions for SetFieldValues().
116 base::StringValue* Int64ToValue(int64 i) {
117 return new base::StringValue(base::Int64ToString(i));
120 base::StringValue* TimeToValue(const base::Time& t) {
121 return new base::StringValue(GetTimeDebugString(t));
124 base::StringValue* IdToValue(const Id& id) {
125 return id.ToValue();
128 base::FundamentalValue* BooleanToValue(bool bool_val) {
129 return new base::FundamentalValue(bool_val);
132 base::StringValue* StringToValue(const std::string& str) {
133 return new base::StringValue(str);
136 base::StringValue* UniquePositionToValue(const UniquePosition& pos) {
137 return new base::StringValue(pos.ToDebugString());
140 base::StringValue* AttachmentMetadataToValue(
141 const sync_pb::AttachmentMetadata& a) {
142 return new base::StringValue(a.SerializeAsString());
145 } // namespace
147 base::DictionaryValue* EntryKernel::ToValue(
148 Cryptographer* cryptographer) const {
149 base::DictionaryValue* kernel_info = new base::DictionaryValue();
150 kernel_info->SetBoolean("isDirty", is_dirty());
151 ModelType dataType = GetServerModelType();
152 if (!IsRealDataType(dataType))
153 dataType = GetModelType();
154 kernel_info->Set("modelType", ModelTypeToValue(dataType));
156 // Int64 fields.
157 SetFieldValues(*this, kernel_info,
158 &GetMetahandleFieldString, &Int64ToValue,
159 INT64_FIELDS_BEGIN, META_HANDLE);
160 SetFieldValues(*this, kernel_info,
161 &GetBaseVersionString, &Int64ToValue,
162 META_HANDLE + 1, BASE_VERSION);
163 SetFieldValues(*this, kernel_info,
164 &GetInt64FieldString, &Int64ToValue,
165 BASE_VERSION + 1, INT64_FIELDS_END - 1);
167 // Time fields.
168 SetFieldValues(*this, kernel_info,
169 &GetTimeFieldString, &TimeToValue,
170 TIME_FIELDS_BEGIN, TIME_FIELDS_END - 1);
172 // ID fields.
173 SetFieldValues(*this, kernel_info,
174 &GetIdFieldString, &IdToValue,
175 ID_FIELDS_BEGIN, ID_FIELDS_END - 1);
177 // Bit fields.
178 SetFieldValues(*this, kernel_info,
179 &GetIndexedBitFieldString, &BooleanToValue,
180 BIT_FIELDS_BEGIN, INDEXED_BIT_FIELDS_END - 1);
181 SetFieldValues(*this, kernel_info,
182 &GetIsDelFieldString, &BooleanToValue,
183 INDEXED_BIT_FIELDS_END, IS_DEL);
184 SetFieldValues(*this, kernel_info,
185 &GetBitFieldString, &BooleanToValue,
186 IS_DEL + 1, BIT_FIELDS_END - 1);
188 // String fields.
190 // Pick out the function overload we want.
191 SetFieldValues(*this, kernel_info,
192 &GetStringFieldString, &StringToValue,
193 STRING_FIELDS_BEGIN, STRING_FIELDS_END - 1);
196 // Proto fields.
197 SetEncryptableProtoValues(*this, cryptographer, kernel_info,
198 PROTO_FIELDS_BEGIN, PROTO_FIELDS_END - 1);
200 // UniquePosition fields
201 SetFieldValues(*this, kernel_info,
202 &GetUniquePositionFieldString, &UniquePositionToValue,
203 UNIQUE_POSITION_FIELDS_BEGIN, UNIQUE_POSITION_FIELDS_END - 1);
205 // AttachmentMetadata fields
206 SetFieldValues(*this,
207 kernel_info,
208 &GetAttachmentMetadataFieldString,
209 &AttachmentMetadataToValue,
210 ATTACHMENT_METADATA_FIELDS_BEGIN,
211 ATTACHMENT_METADATA_FIELDS_END - 1);
213 // Bit temps.
214 SetFieldValues(*this, kernel_info,
215 &GetBitTempString, &BooleanToValue,
216 BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1);
218 return kernel_info;
221 base::ListValue* EntryKernelMutationMapToValue(
222 const EntryKernelMutationMap& mutations) {
223 base::ListValue* list = new base::ListValue();
224 for (EntryKernelMutationMap::const_iterator it = mutations.begin();
225 it != mutations.end(); ++it) {
226 list->Append(EntryKernelMutationToValue(it->second));
228 return list;
231 base::DictionaryValue* EntryKernelMutationToValue(
232 const EntryKernelMutation& mutation) {
233 base::DictionaryValue* dict = new base::DictionaryValue();
234 dict->Set("original", mutation.original.ToValue(NULL));
235 dict->Set("mutated", mutation.mutated.ToValue(NULL));
236 return dict;
239 } // namespace syncer
240 } // namespace syncable