entry.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright 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. 4 5#include "sync/syncable/entry.h" 6 7#include <iomanip> 8 9#include "base/json/string_escape.h" 10#include "sync/syncable/blob.h" 11#include "sync/syncable/directory.h" 12#include "sync/syncable/syncable_base_transaction.h" 13#include "sync/syncable/syncable_columns.h" 14 15using std::string; 16 17namespace syncer { 18namespace syncable { 19 20Entry::Entry(BaseTransaction* trans, GetById, const Id& id) 21 : basetrans_(trans) { 22 kernel_ = trans->directory()->GetEntryById(id); 23} 24 25Entry::Entry(BaseTransaction* trans, GetByClientTag, const string& tag) 26 : basetrans_(trans) { 27 kernel_ = trans->directory()->GetEntryByClientTag(tag); 28} 29 30Entry::Entry(BaseTransaction* trans, GetByServerTag, const string& tag) 31 : basetrans_(trans) { 32 kernel_ = trans->directory()->GetEntryByServerTag(tag); 33} 34 35Entry::Entry(BaseTransaction* trans, GetByHandle, int64 metahandle) 36 : basetrans_(trans) { 37 kernel_ = trans->directory()->GetEntryByHandle(metahandle); 38} 39 40Directory* Entry::dir() const { 41 return basetrans_->directory(); 42} 43 44Id Entry::ComputePrevIdFromServerPosition(const Id& parent_id) const { 45 return dir()->ComputePrevIdFromServerPosition(kernel_, parent_id); 46} 47 48DictionaryValue* Entry::ToValue(Cryptographer* cryptographer) const { 49 DictionaryValue* entry_info = new DictionaryValue(); 50 entry_info->SetBoolean("good", good()); 51 if (good()) { 52 entry_info->Set("kernel", kernel_->ToValue(cryptographer)); 53 entry_info->Set("modelType", 54 ModelTypeToValue(GetModelType())); 55 entry_info->SetBoolean("existsOnClientBecauseNameIsNonEmpty", 56 ExistsOnClientBecauseNameIsNonEmpty()); 57 entry_info->SetBoolean("isRoot", IsRoot()); 58 } 59 return entry_info; 60} 61 62const string& Entry::Get(StringField field) const { 63 DCHECK(kernel_); 64 return kernel_->ref(field); 65} 66 67ModelType Entry::GetServerModelType() const { 68 ModelType specifics_type = kernel_->GetServerModelType(); 69 if (specifics_type != UNSPECIFIED) 70 return specifics_type; 71 72 // Otherwise, we don't have a server type yet. That should only happen 73 // if the item is an uncommitted locally created item. 74 // It's possible we'll need to relax these checks in the future; they're 75 // just here for now as a safety measure. 76 DCHECK(Get(IS_UNSYNCED)); 77 DCHECK_EQ(Get(SERVER_VERSION), 0); 78 DCHECK(Get(SERVER_IS_DEL)); 79 // Note: can't enforce !Get(ID).ServerKnows() here because that could 80 // actually happen if we hit AttemptReuniteLostCommitResponses. 81 return UNSPECIFIED; 82} 83 84ModelType Entry::GetModelType() const { 85 ModelType specifics_type = GetModelTypeFromSpecifics(Get(SPECIFICS)); 86 if (specifics_type != UNSPECIFIED) 87 return specifics_type; 88 if (IsRoot()) 89 return TOP_LEVEL_FOLDER; 90 // Loose check for server-created top-level folders that aren't 91 // bound to a particular model type. 92 if (!Get(UNIQUE_SERVER_TAG).empty() && Get(IS_DIR)) 93 return TOP_LEVEL_FOLDER; 94 95 return UNSPECIFIED; 96} 97 98Id Entry::GetPredecessorId() const { 99 return kernel_->ref(PREV_ID); 100} 101 102Id Entry::GetSuccessorId() const { 103 return kernel_->ref(NEXT_ID); 104} 105 106std::ostream& operator<<(std::ostream& s, const Blob& blob) { 107 for (Blob::const_iterator i = blob.begin(); i != blob.end(); ++i) 108 s << std::hex << std::setw(2) 109 << std::setfill('0') << static_cast<unsigned int>(*i); 110 return s << std::dec; 111} 112 113std::ostream& operator<<(std::ostream& os, const Entry& entry) { 114 int i; 115 EntryKernel* const kernel = entry.kernel_; 116 for (i = BEGIN_FIELDS; i < INT64_FIELDS_END; ++i) { 117 os << g_metas_columns[i].name << ": " 118 << kernel->ref(static_cast<Int64Field>(i)) << ", "; 119 } 120 for ( ; i < TIME_FIELDS_END; ++i) { 121 os << g_metas_columns[i].name << ": " 122 << GetTimeDebugString(kernel->ref(static_cast<TimeField>(i))) << ", "; 123 } 124 for ( ; i < ID_FIELDS_END; ++i) { 125 os << g_metas_columns[i].name << ": " 126 << kernel->ref(static_cast<IdField>(i)) << ", "; 127 } 128 os << "Flags: "; 129 for ( ; i < BIT_FIELDS_END; ++i) { 130 if (kernel->ref(static_cast<BitField>(i))) 131 os << g_metas_columns[i].name << ", "; 132 } 133 for ( ; i < STRING_FIELDS_END; ++i) { 134 const std::string& field = kernel->ref(static_cast<StringField>(i)); 135 os << g_metas_columns[i].name << ": " << field << ", "; 136 } 137 for ( ; i < PROTO_FIELDS_END; ++i) { 138 std::string escaped_str; 139 base::JsonDoubleQuote( 140 kernel->ref(static_cast<ProtoField>(i)).SerializeAsString(), 141 false, 142 &escaped_str); 143 os << g_metas_columns[i].name << ": " << escaped_str << ", "; 144 } 145 for ( ; i < ORDINAL_FIELDS_END; ++i) { 146 os << g_metas_columns[i].name << ": " 147 << kernel->ref(static_cast<OrdinalField>(i)).ToDebugString() 148 << ", "; 149 } 150 os << "TempFlags: "; 151 for ( ; i < BIT_TEMPS_END; ++i) { 152 if (kernel->ref(static_cast<BitTemp>(i))) 153 os << "#" << i - BIT_TEMPS_BEGIN << ", "; 154 } 155 return os; 156} 157 158} // namespace syncable 159} // namespace syncer 160