Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/chromeos/gdata/gdata_files.h" | 5 #include "chrome/browser/chromeos/gdata/gdata_files.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "base/platform_file.h" | 10 #include "base/platform_file.h" |
| 11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "chrome/browser/chromeos/gdata/find_entry_delegate.h" | 13 #include "chrome/browser/chromeos/gdata/find_entry_delegate.h" |
| 14 #include "chrome/browser/chromeos/gdata/gdata.pb.h" | 14 #include "chrome/browser/chromeos/gdata/gdata.pb.h" |
| 15 #include "chrome/browser/chromeos/gdata/gdata_parser.h" | 15 #include "chrome/browser/chromeos/gdata/gdata_parser.h" |
| 16 #include "chrome/browser/chromeos/gdata/gdata_util.h" | |
| 16 #include "net/base/escape.h" | 17 #include "net/base/escape.h" |
| 17 | 18 |
| 18 namespace gdata { | 19 namespace gdata { |
| 19 namespace { | 20 namespace { |
| 20 | 21 |
| 21 // Content refresh time. | 22 // Content refresh time. |
| 22 #ifndef NDEBUG | 23 #ifndef NDEBUG |
| 23 const int kRefreshTimeInSec = 10; | 24 const int kRefreshTimeInSec = 10; |
| 24 #else | 25 #else |
| 25 const int kRefreshTimeInSec = 5*60; | 26 const int kRefreshTimeInSec = 5*60; |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 } | 312 } |
| 312 entry->set_file_name(full_file_name.value()); | 313 entry->set_file_name(full_file_name.value()); |
| 313 | 314 |
| 314 DVLOG(1) << "AddEntry: dir = " << GetFilePath().value() | 315 DVLOG(1) << "AddEntry: dir = " << GetFilePath().value() |
| 315 << ", file = " + entry->file_name() | 316 << ", file = " + entry->file_name() |
| 316 << ", parent resource = " << entry->parent_resource_id() | 317 << ", parent resource = " << entry->parent_resource_id() |
| 317 << ", resource = " + entry->resource_id(); | 318 << ", resource = " + entry->resource_id(); |
| 318 | 319 |
| 319 | 320 |
| 320 // Add entry to resource map. | 321 // Add entry to resource map. |
| 321 root_->AddEntryToResourceMap(entry); | 322 if (root_) |
| 323 root_->AddEntryToResourceMap(entry); | |
| 324 | |
| 322 // Setup child and parent links. | 325 // Setup child and parent links. |
| 323 AddChild(entry); | 326 AddChild(entry); |
| 324 entry->SetParent(this); | 327 entry->SetParent(this); |
| 325 } | 328 } |
| 326 | 329 |
| 327 bool GDataDirectory::TakeEntry(GDataEntry* entry) { | 330 bool GDataDirectory::TakeEntry(GDataEntry* entry) { |
| 328 DCHECK(entry); | 331 DCHECK(entry); |
| 329 DCHECK(entry->parent()); | 332 DCHECK(entry->parent()); |
| 330 | 333 |
| 331 entry->parent()->RemoveChild(entry); | 334 entry->parent()->RemoveChild(entry); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 390 DCHECK(entry); | 393 DCHECK(entry); |
| 391 | 394 |
| 392 const std::string file_name(entry->file_name()); | 395 const std::string file_name(entry->file_name()); |
| 393 GDataEntry* found_entry = FindChild(file_name); | 396 GDataEntry* found_entry = FindChild(file_name); |
| 394 if (!found_entry) | 397 if (!found_entry) |
| 395 return false; | 398 return false; |
| 396 | 399 |
| 397 DCHECK_EQ(entry, found_entry); | 400 DCHECK_EQ(entry, found_entry); |
| 398 | 401 |
| 399 // Remove entry from resource map first. | 402 // Remove entry from resource map first. |
| 400 root_->RemoveEntryFromResourceMap(entry); | 403 if (root_) |
| 404 root_->RemoveEntryFromResourceMap(entry); | |
| 401 | 405 |
| 402 // Then delete it from tree. | 406 // Then delete it from tree. |
| 403 child_files_.erase(file_name); | 407 child_files_.erase(file_name); |
| 404 child_directories_.erase(file_name); | 408 child_directories_.erase(file_name); |
| 405 | 409 |
| 406 return true; | 410 return true; |
| 407 } | 411 } |
| 408 | 412 |
| 409 void GDataDirectory::RemoveChildren() { | 413 void GDataDirectory::RemoveChildren() { |
| 410 // Remove child files first. | 414 // Remove child files first. |
| 411 for (GDataFileCollection::const_iterator iter = child_files_.begin(); | 415 for (GDataFileCollection::const_iterator iter = child_files_.begin(); |
| 412 iter != child_files_.end(); ++iter) { | 416 iter != child_files_.end(); ++iter) { |
| 413 root_->RemoveEntryFromResourceMap(iter->second); | 417 if (root_) |
| 418 root_->RemoveEntryFromResourceMap(iter->second); | |
| 414 } | 419 } |
| 415 STLDeleteValues(&child_files_); | 420 STLDeleteValues(&child_files_); |
| 416 child_files_.clear(); | 421 child_files_.clear(); |
| 417 | 422 |
| 418 for (GDataDirectoryCollection::iterator iter = child_directories_.begin(); | 423 for (GDataDirectoryCollection::iterator iter = child_directories_.begin(); |
| 419 iter != child_directories_.end(); ++iter) { | 424 iter != child_directories_.end(); ++iter) { |
| 420 GDataDirectory* dir = iter->second; | 425 GDataDirectory* dir = iter->second; |
| 421 // Remove directories recursively. | 426 // Remove directories recursively. |
| 422 dir->RemoveChildren(); | 427 dir->RemoveChildren(); |
| 423 root_->RemoveEntryFromResourceMap(dir); | 428 if (root_) |
| 429 root_->RemoveEntryFromResourceMap(dir); | |
| 424 } | 430 } |
| 425 STLDeleteValues(&child_directories_); | 431 STLDeleteValues(&child_directories_); |
| 426 child_directories_.clear(); | 432 child_directories_.clear(); |
| 427 } | 433 } |
| 428 | 434 |
| 429 // GDataRootDirectory::CacheEntry struct implementation. | 435 // GDataRootDirectory::CacheEntry struct implementation. |
| 430 | 436 |
| 431 std::string GDataRootDirectory::CacheEntry::ToString() const { | 437 std::string GDataRootDirectory::CacheEntry::ToString() const { |
| 432 std::vector<std::string> cache_states; | 438 std::vector<std::string> cache_states; |
| 433 if (GDataFile::IsCachePresent(cache_state)) | 439 if (GDataFile::IsCachePresent(cache_state)) |
| 434 cache_states.push_back("present"); | 440 cache_states.push_back("present"); |
| 435 if (GDataFile::IsCachePinned(cache_state)) | 441 if (GDataFile::IsCachePinned(cache_state)) |
| 436 cache_states.push_back("pinned"); | 442 cache_states.push_back("pinned"); |
| 437 if (GDataFile::IsCacheDirty(cache_state)) | 443 if (GDataFile::IsCacheDirty(cache_state)) |
| 438 cache_states.push_back("dirty"); | 444 cache_states.push_back("dirty"); |
| 439 | 445 |
| 440 return base::StringPrintf("md5=%s, subdir=%s, cache_state=%s", | 446 return base::StringPrintf("md5=%s, subdir=%s, cache_state=%s", |
| 441 md5.c_str(), | 447 md5.c_str(), |
| 442 CacheSubDirectoryTypeToString(sub_dir_type).c_str(), | 448 CacheSubDirectoryTypeToString(sub_dir_type).c_str(), |
| 443 JoinString(cache_states, ',').c_str()); | 449 JoinString(cache_states, ',').c_str()); |
| 444 } | 450 } |
| 445 | 451 |
| 446 // GDataRootDirectory class implementation. | 452 // GDataRootDirectory class implementation. |
| 447 | 453 |
| 448 GDataRootDirectory::GDataRootDirectory() | 454 GDataRootDirectory::GDataRootDirectory() |
| 449 : ALLOW_THIS_IN_INITIALIZER_LIST(GDataDirectory(NULL, this)), | 455 : ALLOW_THIS_IN_INITIALIZER_LIST(GDataDirectory(NULL, this)), |
| 456 fake_search_directory_(new GDataDirectory(NULL, NULL)), | |
| 450 largest_changestamp_(0), serialized_size_(0) { | 457 largest_changestamp_(0), serialized_size_(0) { |
| 451 title_ = kGDataRootDirectory; | 458 title_ = kGDataRootDirectory; |
| 452 SetFileNameFromTitle(); | 459 SetFileNameFromTitle(); |
| 453 } | 460 } |
| 454 | 461 |
| 455 GDataRootDirectory::~GDataRootDirectory() { | 462 GDataRootDirectory::~GDataRootDirectory() { |
| 456 STLDeleteValues(&cache_map_); | 463 STLDeleteValues(&cache_map_); |
| 457 cache_map_.clear(); | 464 cache_map_.clear(); |
| 458 | 465 |
| 459 resource_map_.clear(); | 466 resource_map_.clear(); |
| 460 } | 467 } |
| 461 | 468 |
| 462 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() { | 469 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() { |
| 463 return this; | 470 return this; |
| 464 } | 471 } |
| 465 | 472 |
| 466 void GDataRootDirectory::AddEntryToResourceMap(GDataEntry* entry) { | 473 void GDataRootDirectory::AddEntryToResourceMap(GDataEntry* entry) { |
| 467 // GDataFileSystem has already locked. | 474 // GDataFileSystem has already locked. |
| 468 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); | 475 DVLOG(1) << "AddEntryToResourceMap " << entry->resource_id(); |
| 469 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); | 476 resource_map_.insert(std::make_pair(entry->resource_id(), entry)); |
| 470 } | 477 } |
| 471 | 478 |
| 472 void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) { | 479 void GDataRootDirectory::RemoveEntryFromResourceMap(GDataEntry* entry) { |
| 473 // GDataFileSystem has already locked. | 480 // GDataFileSystem has already locked. |
| 474 resource_map_.erase(entry->resource_id()); | 481 resource_map_.erase(entry->resource_id()); |
| 475 } | 482 } |
| 476 | 483 |
| 484 bool GDataRootDirectory::ModifyFindEntryParamsIfSearchPath( | |
| 485 const FilePath& file_path, | |
| 486 std::vector<FilePath::StringType>* components, | |
| 487 GDataDirectory** current_dir, | |
| 488 FilePath* directory_path) { | |
| 489 DCHECK(current_dir); | |
| 490 DCHECK(components); | |
| 491 DCHECK(components->size() > 3); | |
|
satorux1
2012/05/04 01:48:40
why not DCHEC_EQ(4, components->size())? can this
| |
| 492 DCHECK(components->at(0) == "gdata" && components->at(1) == ".search"); | |
| 493 | |
| 494 FilePath::StringType resource_id; | |
| 495 FilePath::StringType file_name; | |
| 496 util::ParseSearchFileName((*components)[3], &resource_id, &file_name); | |
| 497 if (resource_id.empty() || file_name.empty()) | |
| 498 return false; | |
| 499 | |
| 500 GDataEntry* file_entry = GetEntryByResourceId(resource_id); | |
| 501 if (!file_entry) | |
| 502 return false; | |
| 503 | |
| 504 // If |file_path| is indeed search file path, we should continue search from | |
|
satorux1
2012/05/04 01:53:28
is this comment still relevant? I thought now |fil
| |
| 505 // its parent directory. We have to ammend |components| to be relative to | |
| 506 // the |current_dir| (including the dir itself). | |
| 507 // We continue the search with the entrie's parent instead of the entry itself | |
| 508 // to make sure that the file with id |resource_id| really has the name | |
| 509 // |file_name|. | |
| 510 DCHECK(file_entry->parent()); | |
| 511 *current_dir = file_entry->parent(); | |
| 512 | |
| 513 if ((*current_dir)->parent()) { | |
| 514 *directory_path = (*current_dir)->parent()->GetFilePath(); | |
| 515 } else { | |
| 516 *directory_path = FilePath(); | |
| 517 } | |
| 518 | |
| 519 // Remove "gdata/.search" from path. | |
|
satorux1
2012/05/04 01:48:40
if we know compoentns->size() == 4, then we could
| |
| 520 components->erase(components->begin(), components->begin() + 2); | |
| 521 (*components)[0] = (*current_dir)->file_name(); | |
| 522 (*components)[1] = file_name; | |
| 523 return true; | |
| 524 } | |
| 525 | |
| 477 void GDataRootDirectory::FindEntryByPath( | 526 void GDataRootDirectory::FindEntryByPath( |
| 478 const FilePath& file_path, | 527 const FilePath& file_path, |
| 479 FindEntryDelegate* delegate) { | 528 FindEntryDelegate* delegate) { |
| 480 // GDataFileSystem has already locked. | 529 // GDataFileSystem has already locked. |
| 481 DCHECK(delegate); | 530 DCHECK(delegate); |
| 482 | 531 |
| 483 std::vector<FilePath::StringType> components; | 532 std::vector<FilePath::StringType> components; |
| 484 file_path.GetComponents(&components); | 533 file_path.GetComponents(&components); |
| 485 | 534 |
| 486 GDataDirectory* current_dir = this; | 535 GDataDirectory* current_dir = this; |
| 487 FilePath directory_path; | 536 FilePath directory_path; |
| 537 | |
| 538 util::GDataSearchPathType path_type = | |
| 539 util::GetSearchPathStatusForPathComponents(components); | |
| 540 | |
| 541 if (path_type == util::GDATA_SEARCH_PATH_ROOT || | |
| 542 path_type == util::GDATA_SEARCH_PATH_QUERY) { | |
| 543 delegate->OnDone(base::PLATFORM_FILE_OK, file_path.DirName(), | |
| 544 fake_search_directory_.get()); | |
| 545 return; | |
| 546 | |
| 547 } | |
| 548 | |
| 549 // If the path is under search path, we have to modify paremeters for finding | |
| 550 // the entry. | |
| 551 if (path_type != util::GDATA_SEARCH_PATH_INVALID) { | |
| 552 if (!ModifyFindEntryParamsIfSearchPath(file_path, &components, ¤t_dir, | |
|
satorux1
2012/05/04 01:48:40
Maybe IfSearchPath -> ForSearchPath()? The functio
| |
| 553 &directory_path)) { | |
| 554 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); | |
| 555 return; | |
| 556 } | |
| 557 } | |
| 558 | |
| 488 for (size_t i = 0; i < components.size() && current_dir; i++) { | 559 for (size_t i = 0; i < components.size() && current_dir; i++) { |
| 489 directory_path = directory_path.Append(current_dir->file_name()); | 560 directory_path = directory_path.Append(current_dir->file_name()); |
| 490 | 561 |
| 491 // Last element must match, if not last then it must be a directory. | 562 // Last element must match, if not last then it must be a directory. |
| 492 if (i == components.size() - 1) { | 563 if (i == components.size() - 1) { |
| 493 if (current_dir->file_name() == components[i]) | 564 if (current_dir->file_name() == components[i]) { |
| 494 delegate->OnDone(base::PLATFORM_FILE_OK, directory_path, current_dir); | 565 delegate->OnDone(base::PLATFORM_FILE_OK, directory_path, current_dir); |
| 495 else | 566 } else { |
| 496 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); | 567 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
| 497 | 568 } |
| 498 return; | 569 return; |
| 499 } | 570 } |
| 500 | 571 |
| 501 // Not the last part of the path, search for the next segment. | 572 // Not the last part of the path, search for the next segment. |
| 502 GDataEntry* entry = current_dir->FindChild(components[i + 1]); | 573 GDataEntry* entry = current_dir->FindChild(components[i + 1]); |
| 503 if (!entry) { | 574 if (!entry) { |
| 504 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); | 575 delegate->OnDone(base::PLATFORM_FILE_ERROR_NOT_FOUND, FilePath(), NULL); |
| 505 return; | 576 return; |
| 506 } | 577 } |
| 507 | 578 |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 822 bool ok = proto->ParseFromString(serialized_proto); | 893 bool ok = proto->ParseFromString(serialized_proto); |
| 823 if (ok) { | 894 if (ok) { |
| 824 FromProto(*proto.get()); | 895 FromProto(*proto.get()); |
| 825 set_origin(FROM_CACHE); | 896 set_origin(FROM_CACHE); |
| 826 set_refresh_time(base::Time::Now()); | 897 set_refresh_time(base::Time::Now()); |
| 827 } | 898 } |
| 828 return ok; | 899 return ok; |
| 829 } | 900 } |
| 830 | 901 |
| 831 } // namespace gdata | 902 } // namespace gdata |
| OLD | NEW |