| // Copyright (c) 2012 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. |
| |
| #include "sync/syncable/entry_kernel.h" |
| |
| #include "base/string_number_conversions.h" |
| #include "sync/protocol/proto_value_conversions.h" |
| #include "sync/syncable/syncable_enum_conversions.h" |
| |
| namespace syncer { |
| namespace syncable { |
| |
| EntryKernel::EntryKernel() : dirty_(false) { |
| // Everything else should already be default-initialized. |
| for (int i = INT64_FIELDS_BEGIN; i < INT64_FIELDS_END; ++i) { |
| int64_fields[i] = 0; |
| } |
| } |
| |
| EntryKernel::~EntryKernel() {} |
| |
| ModelType EntryKernel::GetServerModelType() const { |
| ModelType specifics_type = GetModelTypeFromSpecifics(ref(SERVER_SPECIFICS)); |
| if (specifics_type != UNSPECIFIED) |
| return specifics_type; |
| if (ref(ID).IsRoot()) |
| return TOP_LEVEL_FOLDER; |
| // Loose check for server-created top-level folders that aren't |
| // bound to a particular model type. |
| if (!ref(UNIQUE_SERVER_TAG).empty() && ref(SERVER_IS_DIR)) |
| return TOP_LEVEL_FOLDER; |
| |
| return UNSPECIFIED; |
| } |
| |
| namespace { |
| |
| // Utility function to loop through a set of enum values and add the |
| // field keys/values in the kernel to the given dictionary. |
| // |
| // V should be convertible to Value. |
| template <class T, class U, class V> |
| void SetFieldValues(const EntryKernel& kernel, |
| DictionaryValue* dictionary_value, |
| const char* (*enum_key_fn)(T), |
| V* (*enum_value_fn)(U), |
| int field_key_min, int field_key_max) { |
| DCHECK_LE(field_key_min, field_key_max); |
| for (int i = field_key_min; i <= field_key_max; ++i) { |
| T field = static_cast<T>(i); |
| const std::string& key = enum_key_fn(field); |
| V* value = enum_value_fn(kernel.ref(field)); |
| dictionary_value->Set(key, value); |
| } |
| } |
| |
| // Helper functions for SetFieldValues(). |
| |
| StringValue* Int64ToValue(int64 i) { |
| return Value::CreateStringValue(base::Int64ToString(i)); |
| } |
| |
| StringValue* TimeToValue(const base::Time& t) { |
| return Value::CreateStringValue(GetTimeDebugString(t)); |
| } |
| |
| StringValue* IdToValue(const Id& id) { |
| return id.ToValue(); |
| } |
| |
| } // namespace |
| |
| DictionaryValue* EntryKernel::ToValue() const { |
| DictionaryValue* kernel_info = new DictionaryValue(); |
| kernel_info->SetBoolean("isDirty", is_dirty()); |
| kernel_info->Set("serverModelType", ModelTypeToValue(GetServerModelType())); |
| |
| // Int64 fields. |
| SetFieldValues(*this, kernel_info, |
| &GetMetahandleFieldString, &Int64ToValue, |
| INT64_FIELDS_BEGIN, META_HANDLE); |
| SetFieldValues(*this, kernel_info, |
| &GetBaseVersionString, &Int64ToValue, |
| META_HANDLE + 1, BASE_VERSION); |
| SetFieldValues(*this, kernel_info, |
| &GetInt64FieldString, &Int64ToValue, |
| BASE_VERSION + 1, INT64_FIELDS_END - 1); |
| |
| // Time fields. |
| SetFieldValues(*this, kernel_info, |
| &GetTimeFieldString, &TimeToValue, |
| TIME_FIELDS_BEGIN, TIME_FIELDS_END - 1); |
| |
| // ID fields. |
| SetFieldValues(*this, kernel_info, |
| &GetIdFieldString, &IdToValue, |
| ID_FIELDS_BEGIN, ID_FIELDS_END - 1); |
| |
| // Bit fields. |
| SetFieldValues(*this, kernel_info, |
| &GetIndexedBitFieldString, &Value::CreateBooleanValue, |
| BIT_FIELDS_BEGIN, INDEXED_BIT_FIELDS_END - 1); |
| SetFieldValues(*this, kernel_info, |
| &GetIsDelFieldString, &Value::CreateBooleanValue, |
| INDEXED_BIT_FIELDS_END, IS_DEL); |
| SetFieldValues(*this, kernel_info, |
| &GetBitFieldString, &Value::CreateBooleanValue, |
| IS_DEL + 1, BIT_FIELDS_END - 1); |
| |
| // String fields. |
| { |
| // Pick out the function overload we want. |
| StringValue* (*string_to_value)(const std::string&) = |
| &Value::CreateStringValue; |
| SetFieldValues(*this, kernel_info, |
| &GetStringFieldString, string_to_value, |
| STRING_FIELDS_BEGIN, STRING_FIELDS_END - 1); |
| } |
| |
| // Proto fields. |
| SetFieldValues(*this, kernel_info, |
| &GetProtoFieldString, &EntitySpecificsToValue, |
| PROTO_FIELDS_BEGIN, PROTO_FIELDS_END - 1); |
| |
| // Bit temps. |
| SetFieldValues(*this, kernel_info, |
| &GetBitTempString, &Value::CreateBooleanValue, |
| BIT_TEMPS_BEGIN, BIT_TEMPS_END - 1); |
| |
| return kernel_info; |
| } |
| |
| ListValue* EntryKernelMutationMapToValue( |
| const EntryKernelMutationMap& mutations) { |
| ListValue* list = new ListValue(); |
| for (EntryKernelMutationMap::const_iterator it = mutations.begin(); |
| it != mutations.end(); ++it) { |
| list->Append(EntryKernelMutationToValue(it->second)); |
| } |
| return list; |
| } |
| |
| DictionaryValue* EntryKernelMutationToValue( |
| const EntryKernelMutation& mutation) { |
| DictionaryValue* dict = new DictionaryValue(); |
| dict->Set("original", mutation.original.ToValue()); |
| dict->Set("mutated", mutation.mutated.ToValue()); |
| return dict; |
| } |
| |
| } // namespace syncer |
| } // namespace syncable |