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