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.
5 #include "sync/syncable/entry.h"
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"
21 Entry::Entry(BaseTransaction
* trans
, GetById
, const Id
& id
)
23 kernel_
= trans
->directory()->GetEntryById(id
);
26 Entry::Entry(BaseTransaction
* trans
, GetByClientTag
, const string
& tag
)
28 kernel_
= trans
->directory()->GetEntryByClientTag(tag
);
31 Entry::Entry(BaseTransaction
* trans
, GetTypeRoot
, ModelType type
)
33 const std::string
& tag
= ModelTypeToRootTag(type
);
34 kernel_
= trans
->directory()->GetEntryByServerTag(tag
);
37 Entry::Entry(BaseTransaction
* trans
, GetByHandle
, int64 metahandle
)
39 kernel_
= trans
->directory()->GetEntryByHandle(metahandle
);
42 Entry::Entry(BaseTransaction
* trans
, GetByServerTag
, const string
& tag
)
44 kernel_
= trans
->directory()->GetEntryByServerTag(tag
);
47 Directory
* Entry::dir() const {
48 return basetrans_
->directory();
51 base::DictionaryValue
* Entry::ToValue(Cryptographer
* cryptographer
) const {
52 base::DictionaryValue
* entry_info
= new base::DictionaryValue();
53 entry_info
->SetBoolean("good", 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());
65 bool Entry::GetSyncing() const {
67 return kernel_
->ref(SYNCING
);
70 bool Entry::GetDirtySync() const {
72 return kernel_
->ref(DIRTY_SYNC
);
75 ModelType
Entry::GetServerModelType() const {
76 ModelType specifics_type
= kernel_
->GetServerModelType();
77 if (specifics_type
!= UNSPECIFIED
)
78 return specifics_type
;
80 // Otherwise, we don't have a server type yet. That should only happen
81 // if the item is an uncommitted locally created item.
82 // It's possible we'll need to relax these checks in the future; they're
83 // just here for now as a safety measure.
84 DCHECK(GetIsUnsynced());
85 DCHECK_EQ(GetServerVersion(), 0);
86 DCHECK(GetServerIsDel());
87 // Note: can't enforce !GetId().ServerKnows() here because that could
88 // actually happen if we hit AttemptReuniteLostCommitResponses.
92 ModelType
Entry::GetModelType() const {
93 ModelType specifics_type
= GetModelTypeFromSpecifics(GetSpecifics());
94 if (specifics_type
!= UNSPECIFIED
)
95 return specifics_type
;
97 return TOP_LEVEL_FOLDER
;
98 // Loose check for server-created top-level folders that aren't
99 // bound to a particular model type.
100 if (!GetUniqueServerTag().empty() && GetIsDir())
101 return TOP_LEVEL_FOLDER
;
106 Id
Entry::GetPredecessorId() const {
107 return dir()->GetPredecessorId(kernel_
);
110 Id
Entry::GetSuccessorId() const {
111 return dir()->GetSuccessorId(kernel_
);
114 Id
Entry::GetFirstChildId() const {
115 return dir()->GetFirstChildId(basetrans_
, kernel_
);
118 void Entry::GetChildHandles(std::vector
<int64
>* result
) const {
119 dir()->GetChildHandlesById(basetrans_
, GetId(), result
);
122 int Entry::GetTotalNodeCount() const {
123 return dir()->GetTotalNodeCount(basetrans_
, kernel_
);
126 int Entry::GetPositionIndex() const {
127 return dir()->GetPositionIndex(basetrans_
, kernel_
);
130 bool Entry::ShouldMaintainPosition() const {
131 return kernel_
->ShouldMaintainPosition();
134 bool Entry::ShouldMaintainHierarchy() const {
135 return kernel_
->ShouldMaintainHierarchy();
138 std::ostream
& operator<<(std::ostream
& s
, const Blob
& blob
) {
139 for (Blob::const_iterator i
= blob
.begin(); i
!= blob
.end(); ++i
)
140 s
<< std::hex
<< std::setw(2)
141 << std::setfill('0') << static_cast<unsigned int>(*i
);
142 return s
<< std::dec
;
145 std::ostream
& operator<<(std::ostream
& os
, const Entry
& entry
) {
147 EntryKernel
* const kernel
= entry
.kernel_
;
148 for (i
= BEGIN_FIELDS
; i
< INT64_FIELDS_END
; ++i
) {
149 os
<< g_metas_columns
[i
].name
<< ": "
150 << kernel
->ref(static_cast<Int64Field
>(i
)) << ", ";
152 for ( ; i
< TIME_FIELDS_END
; ++i
) {
153 os
<< g_metas_columns
[i
].name
<< ": "
154 << GetTimeDebugString(kernel
->ref(static_cast<TimeField
>(i
))) << ", ";
156 for ( ; i
< ID_FIELDS_END
; ++i
) {
157 os
<< g_metas_columns
[i
].name
<< ": "
158 << kernel
->ref(static_cast<IdField
>(i
)) << ", ";
161 for ( ; i
< BIT_FIELDS_END
; ++i
) {
162 if (kernel
->ref(static_cast<BitField
>(i
)))
163 os
<< g_metas_columns
[i
].name
<< ", ";
165 for ( ; i
< STRING_FIELDS_END
; ++i
) {
166 const std::string
& field
= kernel
->ref(static_cast<StringField
>(i
));
167 os
<< g_metas_columns
[i
].name
<< ": " << field
<< ", ";
169 for ( ; i
< PROTO_FIELDS_END
; ++i
) {
170 std::string escaped_str
= base::EscapeBytesAsInvalidJSONString(
171 kernel
->ref(static_cast<ProtoField
>(i
)).SerializeAsString(),
173 os
<< g_metas_columns
[i
].name
<< ": " << escaped_str
<< ", ";
175 for ( ; i
< UNIQUE_POSITION_FIELDS_END
; ++i
) {
176 os
<< g_metas_columns
[i
].name
<< ": "
177 << kernel
->ref(static_cast<UniquePositionField
>(i
)).ToDebugString()
180 for ( ; i
< ATTACHMENT_METADATA_FIELDS_END
; ++i
) {
181 std::string escaped_str
= base::EscapeBytesAsInvalidJSONString(
182 kernel
->ref(static_cast<AttachmentMetadataField
>(i
))
183 .SerializeAsString(),
185 os
<< g_metas_columns
[i
].name
<< ": " << escaped_str
<< ", ";
188 for ( ; i
< BIT_TEMPS_END
; ++i
) {
189 if (kernel
->ref(static_cast<BitTemp
>(i
)))
190 os
<< "#" << i
- BIT_TEMPS_BEGIN
<< ", ";
195 } // namespace syncable
196 } // namespace syncer