Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(40)

Side by Side Diff: chrome/browser/sync/syncable/syncable.cc

Issue 340055: String cleanup in sync code (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/syncable/syncable.h" 5 #include "chrome/browser/sync/syncable/syncable.h"
6 6
7 #include "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #if defined(OS_POSIX) 10 #if defined(OS_POSIX)
11 #include <sys/time.h> 11 #include <sys/time.h>
12 #endif 12 #endif
13 #include <sys/types.h> 13 #include <sys/types.h>
14 #include <time.h> 14 #include <time.h>
15 #if defined(OS_MACOSX) 15 #if defined(OS_MACOSX)
16 #include <CoreFoundation/CoreFoundation.h> 16 #include <CoreFoundation/CoreFoundation.h>
17 #elif defined(OS_WIN) 17 #elif defined(OS_WIN)
18 #include <shlwapi.h> // for PathMatchSpec 18 #include <shlwapi.h> // for PathMatchSpec
19 #endif 19 #endif
20 20
21 #include <algorithm> 21 #include <algorithm>
22 #include <functional> 22 #include <functional>
23 #include <iomanip> 23 #include <iomanip>
24 #include <iterator> 24 #include <iterator>
25 #include <set> 25 #include <set>
26 #include <string> 26 #include <string>
27 27
28 #include "base/hash_tables.h" 28 #include "base/hash_tables.h"
29 #include "base/file_util.h"
29 #include "base/logging.h" 30 #include "base/logging.h"
30 #include "base/perftimer.h" 31 #include "base/perftimer.h"
31 #include "base/scoped_ptr.h" 32 #include "base/scoped_ptr.h"
33 #include "base/string_util.h"
32 #include "base/time.h" 34 #include "base/time.h"
33 #include "chrome/browser/sync/engine/syncer.h" 35 #include "chrome/browser/sync/engine/syncer.h"
34 #include "chrome/browser/sync/engine/syncer_util.h" 36 #include "chrome/browser/sync/engine/syncer_util.h"
35 #include "chrome/browser/sync/protocol/service_constants.h" 37 #include "chrome/browser/sync/protocol/service_constants.h"
36 #include "chrome/browser/sync/syncable/directory_backing_store.h" 38 #include "chrome/browser/sync/syncable/directory_backing_store.h"
37 #include "chrome/browser/sync/syncable/directory_manager.h" 39 #include "chrome/browser/sync/syncable/directory_manager.h"
38 #include "chrome/browser/sync/syncable/syncable-inl.h" 40 #include "chrome/browser/sync/syncable/syncable-inl.h"
39 #include "chrome/browser/sync/syncable/syncable_changes_version.h" 41 #include "chrome/browser/sync/syncable/syncable_changes_version.h"
40 #include "chrome/browser/sync/syncable/syncable_columns.h" 42 #include "chrome/browser/sync/syncable/syncable_columns.h"
41 #include "chrome/browser/sync/util/character_set_converters.h"
42 #include "chrome/browser/sync/util/compat_file.h"
43 #include "chrome/browser/sync/util/crypto_helpers.h" 43 #include "chrome/browser/sync/util/crypto_helpers.h"
44 #include "chrome/browser/sync/util/event_sys-inl.h" 44 #include "chrome/browser/sync/util/event_sys-inl.h"
45 #include "chrome/browser/sync/util/fast_dump.h" 45 #include "chrome/browser/sync/util/fast_dump.h"
46 #include "chrome/browser/sync/util/path_helpers.h" 46 #include "chrome/browser/sync/util/path_helpers.h"
47 47
48 namespace { 48 namespace {
49 enum InvariantCheckLevel { 49 enum InvariantCheckLevel {
50 OFF = 0, 50 OFF = 0,
51 VERIFY_IN_MEMORY = 1, 51 VERIFY_IN_MEMORY = 1,
52 FULL_DB_VERIFICATION = 2 52 FULL_DB_VERIFICATION = 2
(...skipping 30 matching lines...) Expand all
83 #error NEED OS SPECIFIC Now() implementation 83 #error NEED OS SPECIFIC Now() implementation
84 #endif 84 #endif
85 } 85 }
86 86
87 /////////////////////////////////////////////////////////////////////////// 87 ///////////////////////////////////////////////////////////////////////////
88 // Compare functions and hashes for the indices. 88 // Compare functions and hashes for the indices.
89 89
90 // Callback for sqlite3 90 // Callback for sqlite3
91 int ComparePathNames16(void*, int a_bytes, const void* a, int b_bytes, 91 int ComparePathNames16(void*, int a_bytes, const void* a, int b_bytes,
92 const void* b) { 92 const void* b) {
93 #if defined(OS_WIN)
94 DCHECK_EQ(0, a_bytes % 2);
95 DCHECK_EQ(0, b_bytes % 2);
96 int result = CompareString(LOCALE_INVARIANT, NORM_IGNORECASE,
97 static_cast<const PathChar*>(a), a_bytes / 2,
98 static_cast<const PathChar*>(b), b_bytes / 2);
99 CHECK(0 != result) << "Error comparing strings: " << GetLastError();
100 return result - 2; // Convert to -1, 0, 1
101 #elif defined(OS_LINUX)
102 int result = base::strncasecmp(reinterpret_cast<const char *>(a), 93 int result = base::strncasecmp(reinterpret_cast<const char *>(a),
103 reinterpret_cast<const char *>(b), 94 reinterpret_cast<const char *>(b),
104 std::min(a_bytes, b_bytes)); 95 std::min(a_bytes, b_bytes));
105 if (result != 0) { 96 if (result != 0) {
106 return result; 97 return result;
107 } else { 98 } else {
108 return a_bytes > b_bytes ? 1 : b_bytes > a_bytes ? -1 : 0; 99 return a_bytes > b_bytes ? 1 : b_bytes > a_bytes ? -1 : 0;
109 } 100 }
110 #elif defined(OS_MACOSX)
111 CFStringRef a_str;
112 CFStringRef b_str;
113 a_str = CFStringCreateWithBytes(NULL, reinterpret_cast<const UInt8*>(a),
114 a_bytes, kCFStringEncodingUTF8, FALSE);
115 b_str = CFStringCreateWithBytes(NULL, reinterpret_cast<const UInt8*>(b),
116 b_bytes, kCFStringEncodingUTF8, FALSE);
117 CFComparisonResult res;
118 res = CFStringCompare(a_str, b_str, kCFCompareCaseInsensitive);
119 CFRelease(a_str);
120 CFRelease(b_str);
121 return res;
122 #else
123 #error no ComparePathNames16() for your OS
124 #endif
125 } 101 }
126 102
127 template <Int64Field field_index> 103 template <Int64Field field_index>
128 class SameField { 104 class SameField {
129 public: 105 public:
130 inline bool operator()(const syncable::EntryKernel* a, 106 inline bool operator()(const syncable::EntryKernel* a,
131 const syncable::EntryKernel* b) const { 107 const syncable::EntryKernel* b) const {
132 return a->ref(field_index) == b->ref(field_index); 108 return a->ref(field_index) == b->ref(field_index);
133 } 109 }
134 }; 110 };
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 kernel->ref(NAME) : kernel->ref(UNSANITIZED_NAME); 146 kernel->ref(NAME) : kernel->ref(UNSANITIZED_NAME);
171 return Name(kernel->ref(NAME), sync_name_ref, kernel->ref(NON_UNIQUE_NAME)); 147 return Name(kernel->ref(NAME), sync_name_ref, kernel->ref(NON_UNIQUE_NAME));
172 } 148 }
173 149
174 /////////////////////////////////////////////////////////////////////////// 150 ///////////////////////////////////////////////////////////////////////////
175 // Directory 151 // Directory
176 152
177 static const DirectoryChangeEvent kShutdownChangesEvent = 153 static const DirectoryChangeEvent kShutdownChangesEvent =
178 { DirectoryChangeEvent::SHUTDOWN, 0, 0 }; 154 { DirectoryChangeEvent::SHUTDOWN, 0, 0 };
179 155
180 Directory::Kernel::Kernel(const PathString& db_path, 156 Directory::Kernel::Kernel(const FilePath& db_path,
181 const PathString& name, 157 const PathString& name,
182 const KernelLoadInfo& info) 158 const KernelLoadInfo& info)
183 : db_path(db_path), 159 : db_path(db_path),
184 refcount(1), 160 refcount(1),
185 name_(name), 161 name_(name),
186 metahandles_index(new Directory::MetahandlesIndex), 162 metahandles_index(new Directory::MetahandlesIndex),
187 ids_index(new Directory::IdsIndex), 163 ids_index(new Directory::IdsIndex),
188 parent_id_and_names_index(new Directory::ParentIdAndNamesIndex), 164 parent_id_and_names_index(new Directory::ParentIdAndNamesIndex),
189 extended_attributes(new ExtendedAttributes), 165 extended_attributes(new ExtendedAttributes),
190 unapplied_update_metahandles(new MetahandleSet), 166 unapplied_update_metahandles(new MetahandleSet),
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 216
241 // PathMatchSpec strips spaces from the start of pathspec, so we compare those 217 // PathMatchSpec strips spaces from the start of pathspec, so we compare those
242 // ourselves. 218 // ourselves.
243 const PathChar* pathname_ptr = pathname.c_str(); 219 const PathChar* pathname_ptr = pathname.c_str();
244 const PathChar* pathspec_ptr = pathspec.c_str(); 220 const PathChar* pathspec_ptr = pathspec.c_str();
245 221
246 while (*pathname_ptr == ' ' && *pathspec_ptr == ' ') 222 while (*pathname_ptr == ' ' && *pathspec_ptr == ' ')
247 ++pathname_ptr, ++pathspec_ptr; 223 ++pathname_ptr, ++pathspec_ptr;
248 224
249 // If we have more inital spaces in the pathspec than in the pathname then the 225 // If we have more inital spaces in the pathspec than in the pathname then the
250 // result from PathMatchSpec will be erronous. 226 // result from PathMatchSpec will be erroneous.
251 if (*pathspec_ptr == ' ') 227 if (*pathspec_ptr == ' ')
252 return FALSE; 228 return FALSE;
253 229
254 // PathMatchSpec also gets "confused" when there are ';' characters in name or 230 // PathMatchSpec also gets "confused" when there are ';' characters in name or
255 // in spec. So, if we match (f.i.) ";" with ";" PathMatchSpec will return 231 // in spec. So, if we match (f.i.) ";" with ";" PathMatchSpec will return
256 // FALSE (which is wrong). Luckily for us, we can easily fix this by 232 // FALSE (which is wrong). Luckily for us, we can easily fix this by
257 // substituting ';' with ':' which is illegal character in file name and 233 // substituting ';' with ':' which is illegal character in file name and
258 // we're not going to see it there. With ':' in path name and spec 234 // we're not going to see it there. With ':' in path name and spec
259 // PathMatchSpec works fine. 235 // PathMatchSpec works fine.
260 if ((NULL == wcschr(pathname_ptr, L';')) && 236 if ((NULL == strchr(pathname_ptr, ';')) &&
261 (NULL == wcschr(pathspec_ptr, L';'))) { 237 (NULL == strchr(pathspec_ptr, ';'))) {
262 // No ';' in file name and in spec. Just pass it as it is. 238 // No ';' in file name and in spec. Just pass it as it is.
263 return ::PathMatchSpec(pathname_ptr, pathspec_ptr); 239 return ::PathMatchSpecA(pathname_ptr, pathspec_ptr);
264 } 240 }
265 241
266 // We need to subst ';' with ':' in both, name and spec. 242 // We need to subst ';' with ':' in both, name and spec.
267 PathString name_subst(pathname_ptr); 243 PathString name_subst(pathname_ptr);
268 PathString spec_subst(pathspec_ptr); 244 PathString spec_subst(pathspec_ptr);
269 245
270 PathString::size_type index = name_subst.find(L';'); 246 PathString::size_type index = name_subst.find(L';');
271 while (PathString::npos != index) { 247 while (PathString::npos != index) {
272 name_subst[index] = L':'; 248 name_subst[index] = ':';
273 index = name_subst.find(L';', index + 1); 249 index = name_subst.find(';', index + 1);
274 } 250 }
275 251
276 index = spec_subst.find(L';'); 252 index = spec_subst.find(L';');
277 while (PathString::npos != index) { 253 while (PathString::npos != index) {
278 spec_subst[index] = L':'; 254 spec_subst[index] = ':';
279 index = spec_subst.find(L';', index + 1); 255 index = spec_subst.find(';', index + 1);
280 } 256 }
281 257
282 return ::PathMatchSpec(name_subst.c_str(), spec_subst.c_str()); 258 return ::PathMatchSpecA(name_subst.c_str(), spec_subst.c_str());
283 #else 259 #else
284 return 0 == ComparePathNames(pathname, pathspec); 260 return 0 == ComparePathNames(pathname, pathspec);
285 #endif 261 #endif
286 } 262 }
287 263
288 DirOpenResult Directory::Open(const PathString& file_path, 264 DirOpenResult Directory::Open(const FilePath& file_path,
289 const PathString& name) { 265 const PathString& name) {
290 const DirOpenResult result = OpenImpl(file_path, name); 266 const DirOpenResult result = OpenImpl(file_path, name);
291 if (OPENED != result) 267 if (OPENED != result)
292 Close(); 268 Close();
293 return result; 269 return result;
294 } 270 }
295 271
296 void Directory::InitializeIndices() { 272 void Directory::InitializeIndices() {
297 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin(); 273 MetahandlesIndex::iterator it = kernel_->metahandles_index->begin();
298 for (; it != kernel_->metahandles_index->end(); ++it) { 274 for (; it != kernel_->metahandles_index->end(); ++it) {
299 EntryKernel* entry = *it; 275 EntryKernel* entry = *it;
300 if (!entry->ref(IS_DEL)) 276 if (!entry->ref(IS_DEL))
301 kernel_->parent_id_and_names_index->insert(entry); 277 kernel_->parent_id_and_names_index->insert(entry);
302 kernel_->ids_index->insert(entry); 278 kernel_->ids_index->insert(entry);
303 if (entry->ref(IS_UNSYNCED)) 279 if (entry->ref(IS_UNSYNCED))
304 kernel_->unsynced_metahandles->insert(entry->ref(META_HANDLE)); 280 kernel_->unsynced_metahandles->insert(entry->ref(META_HANDLE));
305 if (entry->ref(IS_UNAPPLIED_UPDATE)) 281 if (entry->ref(IS_UNAPPLIED_UPDATE))
306 kernel_->unapplied_update_metahandles->insert(entry->ref(META_HANDLE)); 282 kernel_->unapplied_update_metahandles->insert(entry->ref(META_HANDLE));
307 } 283 }
308 } 284 }
309 285
310 DirectoryBackingStore* Directory::CreateBackingStore( 286 DirectoryBackingStore* Directory::CreateBackingStore(
311 const PathString& dir_name, const PathString& backing_filepath) { 287 const PathString& dir_name, const FilePath& backing_filepath) {
312 return new DirectoryBackingStore(dir_name, backing_filepath); 288 return new DirectoryBackingStore(dir_name, backing_filepath);
313 } 289 }
314 290
315 DirOpenResult Directory::OpenImpl(const PathString& file_path, 291 DirOpenResult Directory::OpenImpl(const FilePath& file_path,
316 const PathString& name) { 292 const PathString& name) {
317 DCHECK_EQ(static_cast<DirectoryBackingStore*>(NULL), store_); 293 DCHECK_EQ(static_cast<DirectoryBackingStore*>(NULL), store_);
318 const PathString db_path = ::GetFullPath(file_path); 294 FilePath db_path(file_path);
295 file_util::AbsolutePath(&db_path);
319 store_ = CreateBackingStore(name, db_path); 296 store_ = CreateBackingStore(name, db_path);
320 297
321 KernelLoadInfo info; 298 KernelLoadInfo info;
322 // Temporary indicies before kernel_ initialized in case Load fails. We 0(1) 299 // Temporary indices before kernel_ initialized in case Load fails. We 0(1)
323 // swap these later. 300 // swap these later.
324 MetahandlesIndex metas_bucket; 301 MetahandlesIndex metas_bucket;
325 ExtendedAttributes xattrs_bucket; 302 ExtendedAttributes xattrs_bucket;
326 DirOpenResult result = store_->Load(&metas_bucket, &xattrs_bucket, &info); 303 DirOpenResult result = store_->Load(&metas_bucket, &xattrs_bucket, &info);
327 if (OPENED != result) 304 if (OPENED != result)
328 return result; 305 return result;
329 306
330 kernel_ = new Kernel(db_path, name, info); 307 kernel_ = new Kernel(db_path, name, info);
331 kernel_->metahandles_index->swap(metas_bucket); 308 kernel_->metahandles_index->swap(metas_bucket);
332 kernel_->extended_attributes->swap(xattrs_bucket); 309 kernel_->extended_attributes->swap(xattrs_bucket);
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 return index->lower_bound(&needle_); 476 return index->lower_bound(&needle_);
500 } 477 }
501 virtual Index::iterator upper_bound(Index* index) { 478 virtual Index::iterator upper_bound(Index* index) {
502 needle_.ref(PARENT_ID) = parent_id_; 479 needle_.ref(PARENT_ID) = parent_id_;
503 needle_.ref(NAME) = pathspec_; 480 needle_.ref(NAME) = pathspec_;
504 return index->upper_bound(&needle_); 481 return index->upper_bound(&needle_);
505 } 482 }
506 const PathString pathspec_; 483 const PathString pathspec_;
507 }; 484 };
508 485
509 // Matches a pathspec with wildcards.
510 struct PartialPathMatcher : public PathMatcher {
511 PartialPathMatcher(const PathString& pathspec,
512 PathString::size_type wildcard, const Id& parent_id)
513 : PathMatcher(parent_id), pathspec_(pathspec) {
514 if (0 == wildcard)
515 return;
516 lesser_.assign(pathspec_.data(), wildcard);
517 greater_.assign(pathspec_.data(), wildcard);
518 // Increment the last letter of greater so we can then less than
519 // compare to it.
520 PathString::size_type i = greater_.size() - 1;
521 do {
522 if (greater_[i] == std::numeric_limits<PathString::value_type>::max()) {
523 greater_.resize(i); // Try the preceding character.
524 if (0 == i--)
525 break;
526 } else {
527 greater_[i] += 1;
528 }
529 // Yes, there are cases where incrementing a character
530 // actually decreases its position in the sort. Example: 9 -> :
531 } while (ComparePathNames(lesser_, greater_) >= 0);
532 }
533
534 virtual MatchType PathMatches(const PathString& path) {
535 return PathNameMatch(path, pathspec_) ? MATCH : NO_MATCH;
536 }
537
538 virtual Index::iterator lower_bound(Index* index) {
539 needle_.ref(PARENT_ID) = parent_id_;
540 needle_.ref(NAME) = lesser_;
541 return index->lower_bound(&needle_);
542 }
543 virtual Index::iterator upper_bound(Index* index) {
544 if (greater_.empty()) {
545 needle_.ref(PARENT_ID) = parent_id_;
546 needle_.ref(NAME).clear();
547 Index::iterator i = index->upper_bound(&needle_),
548 end = index->end();
549 while (i != end && (*i)->ref(PARENT_ID) == parent_id_)
550 ++i;
551 return i;
552 } else {
553 needle_.ref(PARENT_ID) = parent_id_;
554 needle_.ref(NAME) = greater_;
555 return index->lower_bound(&needle_);
556 }
557 }
558
559 const PathString pathspec_;
560 PathString lesser_;
561 PathString greater_;
562 };
563
564
565 void Directory::GetChildHandles(BaseTransaction* trans, const Id& parent_id, 486 void Directory::GetChildHandles(BaseTransaction* trans, const Id& parent_id,
566 Directory::ChildHandles* result) { 487 Directory::ChildHandles* result) {
567 AllPathsMatcher matcher(parent_id); 488 AllPathsMatcher matcher(parent_id);
568 return GetChildHandlesImpl(trans, parent_id, &matcher, result); 489 return GetChildHandlesImpl(trans, parent_id, &matcher, result);
569 } 490 }
570 491
571 void Directory::GetChildHandlesImpl(BaseTransaction* trans, const Id& parent_id, 492 void Directory::GetChildHandlesImpl(BaseTransaction* trans, const Id& parent_id,
572 PathMatcher* matcher, 493 PathMatcher* matcher,
573 Directory::ChildHandles* result) { 494 Directory::ChildHandles* result) {
574 CHECK(this == trans->directory()); 495 CHECK(this == trans->directory());
(...skipping 1076 matching lines...) Expand 10 before | Expand all | Expand 10 after
1651 return true; 1572 return true;
1652 } 1573 }
1653 1574
1654 // returns -1 if s contains any non [0-9] characters 1575 // returns -1 if s contains any non [0-9] characters
1655 static int PathStringToInteger(PathString s) { 1576 static int PathStringToInteger(PathString s) {
1656 PathString::const_iterator i = s.begin(); 1577 PathString::const_iterator i = s.begin();
1657 for (; i != s.end(); ++i) { 1578 for (; i != s.end(); ++i) {
1658 if (PathString::npos == PathString(PSTR("0123456789")).find(*i)) 1579 if (PathString::npos == PathString(PSTR("0123456789")).find(*i))
1659 return -1; 1580 return -1;
1660 } 1581 }
1661 return 1582 return atoi(s.c_str());
1662 #if !PATHSTRING_IS_STD_STRING
1663 _wtoi
1664 #else
1665 atoi
1666 #endif
1667 (s.c_str());
1668 }
1669
1670 static PathString IntegerToPathString(int i) {
1671 const size_t kBufSize = 25;
1672 PathChar buf[kBufSize];
1673 #if !PATHSTRING_IS_STD_STRING
1674 const int radix = 10;
1675 _itow(i, buf, radix);
1676 #else
1677 snprintf(buf, kBufSize, "%d", i);
1678 #endif
1679 return buf;
1680 } 1583 }
1681 1584
1682 // appends ~1 to the end of 's' unless there is already ~#, in which case 1585 // appends ~1 to the end of 's' unless there is already ~#, in which case
1683 // it just increments the number 1586 // it just increments the number
1684 static PathString FixBasenameInCollision(const PathString s) { 1587 static PathString FixBasenameInCollision(const PathString s) {
1685 PathString::size_type last_tilde = s.find_last_of(PSTR('~')); 1588 PathString::size_type last_tilde = s.find_last_of(PSTR('~'));
1686 if (PathString::npos == last_tilde) return s + PSTR("~1"); 1589 if (PathString::npos == last_tilde) return s + PSTR("~1");
1687 if (s.size() == (last_tilde + 1)) return s + PSTR("1"); 1590 if (s.size() == (last_tilde + 1)) return s + PSTR("1");
1688 // we have ~, but not necessarily ~# (for some number >= 0). check for that 1591 // we have ~, but not necessarily ~# (for some number >= 0). check for that
1689 int n; 1592 int n;
1690 if ((n = PathStringToInteger(s.substr(last_tilde + 1))) != -1) { 1593 if ((n = PathStringToInteger(s.substr(last_tilde + 1))) != -1) {
1691 n++; 1594 n++;
1692 PathString pre_number = s.substr(0, last_tilde + 1); 1595 PathString pre_number = s.substr(0, last_tilde + 1);
1693 return pre_number + IntegerToPathString(n); 1596 return pre_number + IntToString(n);
1694 } else { 1597 } else {
1695 // we have a ~, but not a number following it, so we'll add another 1598 // we have a ~, but not a number following it, so we'll add another
1696 // ~ and this time, a number 1599 // ~ and this time, a number
1697 return s + PSTR("~1"); 1600 return s + PSTR("~1");
1698 } 1601 }
1699 } 1602 }
1700 1603
1701 void DBName::MakeNoncollidingForEntry(BaseTransaction* trans, 1604 void DBName::MakeNoncollidingForEntry(BaseTransaction* trans,
1702 const Id& parent_id, 1605 const Id& parent_id,
1703 Entry* e) { 1606 Entry* e) {
(...skipping 13 matching lines...) Expand all
1717 if (!same_path_entry.good() || (e && same_path_entry.Get(ID) == e->Get(ID))) 1620 if (!same_path_entry.good() || (e && same_path_entry.Get(ID) == e->Get(ID)))
1718 break; 1621 break;
1719 // There was a collision, so fix the name. 1622 // There was a collision, so fix the name.
1720 basename = FixBasenameInCollision(basename); 1623 basename = FixBasenameInCollision(basename);
1721 } 1624 }
1722 // Set our value to the new value. This invalidates desired_name. 1625 // Set our value to the new value. This invalidates desired_name.
1723 PathString new_value = basename + dotextension; 1626 PathString new_value = basename + dotextension;
1724 swap(new_value); 1627 swap(new_value);
1725 } 1628 }
1726 1629
1727 PathString GetFullPath(BaseTransaction* trans, const Entry& e) {
1728 PathString result;
1729 #if defined(COMPILER_MSVC)
1730 result.reserve(MAX_PATH);
1731 #endif
1732 ReverseAppend(e.Get(NAME), &result);
1733 Id id = e.Get(PARENT_ID);
1734 while (!id.IsRoot()) {
1735 result.push_back(kPathSeparator[0]);
1736 Entry ancestor(trans, GET_BY_ID, id);
1737 if (!ancestor.good()) {
1738 // This can happen if the parent folder got deleted before the entry.
1739 LOG(WARNING) << "Cannot get full path of " << e
1740 << "\nbecause an ancestor folder has been deleted.";
1741 result.clear();
1742 return result;
1743 }
1744 ReverseAppend(ancestor.Get(NAME), &result);
1745 id = ancestor.Get(PARENT_ID);
1746 }
1747 result.push_back(kPathSeparator[0]);
1748 reverse(result.begin(), result.end());
1749 return result;
1750 }
1751
1752 const Blob* GetExtendedAttributeValue(const Entry& e, 1630 const Blob* GetExtendedAttributeValue(const Entry& e,
1753 const PathString& attribute_name) { 1631 const PathString& attribute_name) {
1754 ExtendedAttributeKey key(e.Get(META_HANDLE), attribute_name); 1632 ExtendedAttributeKey key(e.Get(META_HANDLE), attribute_name);
1755 ExtendedAttribute extended_attribute(e.trans(), GET_BY_HANDLE, key); 1633 ExtendedAttribute extended_attribute(e.trans(), GET_BY_HANDLE, key);
1756 if (extended_attribute.good() && !extended_attribute.is_deleted()) 1634 if (extended_attribute.good() && !extended_attribute.is_deleted())
1757 return &extended_attribute.value(); 1635 return &extended_attribute.value();
1758 return NULL; 1636 return NULL;
1759 } 1637 }
1760 1638
1761 // This function sets only the flags needed to get this entry to sync. 1639 // This function sets only the flags needed to get this entry to sync.
(...skipping 19 matching lines...) Expand all
1781 } 1659 }
1782 1660
1783 inline FastDump& operator<<(FastDump& dump, const DumpColon&) { 1661 inline FastDump& operator<<(FastDump& dump, const DumpColon&) {
1784 dump.out_->sputn(": ", 2); 1662 dump.out_->sputn(": ", 2);
1785 return dump; 1663 return dump;
1786 } 1664 }
1787 1665
1788 std::ostream& operator<<(std::ostream& stream, const syncable::Entry& entry) { 1666 std::ostream& operator<<(std::ostream& stream, const syncable::Entry& entry) {
1789 // Using ostreams directly here is dreadfully slow, because a mutex is 1667 // Using ostreams directly here is dreadfully slow, because a mutex is
1790 // acquired for every <<. Users noticed it spiking CPU. 1668 // acquired for every <<. Users noticed it spiking CPU.
1791 using browser_sync::ToUTF8;
1792 using syncable::BitField; 1669 using syncable::BitField;
1793 using syncable::BitTemp; 1670 using syncable::BitTemp;
1794 using syncable::BlobField; 1671 using syncable::BlobField;
1795 using syncable::EntryKernel; 1672 using syncable::EntryKernel;
1796 using syncable::g_metas_columns; 1673 using syncable::g_metas_columns;
1797 using syncable::IdField; 1674 using syncable::IdField;
1798 using syncable::Int64Field; 1675 using syncable::Int64Field;
1799 using syncable::StringField; 1676 using syncable::StringField;
1800 using syncable::BEGIN_FIELDS; 1677 using syncable::BEGIN_FIELDS;
1801 using syncable::BIT_FIELDS_END; 1678 using syncable::BIT_FIELDS_END;
(...skipping 14 matching lines...) Expand all
1816 for ( ; i < ID_FIELDS_END; ++i) { 1693 for ( ; i < ID_FIELDS_END; ++i) {
1817 s << g_metas_columns[i].name << colon 1694 s << g_metas_columns[i].name << colon
1818 << kernel->ref(static_cast<IdField>(i)) << separator; 1695 << kernel->ref(static_cast<IdField>(i)) << separator;
1819 } 1696 }
1820 s << "Flags: "; 1697 s << "Flags: ";
1821 for ( ; i < BIT_FIELDS_END; ++i) { 1698 for ( ; i < BIT_FIELDS_END; ++i) {
1822 if (kernel->ref(static_cast<BitField>(i))) 1699 if (kernel->ref(static_cast<BitField>(i)))
1823 s << g_metas_columns[i].name << separator; 1700 s << g_metas_columns[i].name << separator;
1824 } 1701 }
1825 for ( ; i < STRING_FIELDS_END; ++i) { 1702 for ( ; i < STRING_FIELDS_END; ++i) {
1826 ToUTF8 field(kernel->ref(static_cast<StringField>(i))); 1703 const PathString& field = kernel->ref(static_cast<StringField>(i));
1827 s << g_metas_columns[i].name << colon << field.get_string() << separator; 1704 s << g_metas_columns[i].name << colon << field << separator;
1828 } 1705 }
1829 for ( ; i < BLOB_FIELDS_END; ++i) { 1706 for ( ; i < BLOB_FIELDS_END; ++i) {
1830 s << g_metas_columns[i].name << colon 1707 s << g_metas_columns[i].name << colon
1831 << kernel->ref(static_cast<BlobField>(i)) << separator; 1708 << kernel->ref(static_cast<BlobField>(i)) << separator;
1832 } 1709 }
1833 s << "TempFlags: "; 1710 s << "TempFlags: ";
1834 for ( ; i < BIT_TEMPS_END; ++i) { 1711 for ( ; i < BIT_TEMPS_END; ++i) {
1835 if (kernel->ref(static_cast<BitTemp>(i))) 1712 if (kernel->ref(static_cast<BitTemp>(i)))
1836 s << "#" << i - BIT_TEMPS_BEGIN << separator; 1713 s << "#" << i - BIT_TEMPS_BEGIN << separator;
1837 } 1714 }
1838 return stream; 1715 return stream;
1839 } 1716 }
1840 1717
1841 std::ostream& operator<<(std::ostream& s, const syncable::Blob& blob) { 1718 std::ostream& operator<<(std::ostream& s, const syncable::Blob& blob) {
1842 for (syncable::Blob::const_iterator i = blob.begin(); i != blob.end(); ++i) 1719 for (syncable::Blob::const_iterator i = blob.begin(); i != blob.end(); ++i)
1843 s << std::hex << std::setw(2) 1720 s << std::hex << std::setw(2)
1844 << std::setfill('0') << static_cast<unsigned int>(*i); 1721 << std::setfill('0') << static_cast<unsigned int>(*i);
1845 return s << std::dec; 1722 return s << std::dec;
1846 } 1723 }
1847 1724
1848 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) { 1725 FastDump& operator<<(FastDump& dump, const syncable::Blob& blob) {
1849 if (blob.empty()) 1726 if (blob.empty())
1850 return dump; 1727 return dump;
1851 string buffer(HexEncode(&blob[0], blob.size())); 1728 string buffer(HexEncode(&blob[0], blob.size()));
1852 dump.out_->sputn(buffer.c_str(), buffer.size()); 1729 dump.out_->sputn(buffer.c_str(), buffer.size());
1853 return dump; 1730 return dump;
1854 } 1731 }
OLDNEW
« no previous file with comments | « chrome/browser/sync/syncable/syncable.h ('k') | chrome/browser/sync/syncable/syncable_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698