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