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 "base/platform_file.h" | 7 #include "base/platform_file.h" |
| 8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/stringprintf.h" | 9 #include "base/stringprintf.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 210 // We need to first restore the file name based on the title before going | 210 // We need to first restore the file name based on the title before going |
| 211 // through name de-duplication again when it is added to another directory. | 211 // through name de-duplication again when it is added to another directory. |
| 212 entry->SetBaseNameFromTitle(); | 212 entry->SetBaseNameFromTitle(); |
| 213 | 213 |
| 214 // Do file name de-duplication - find files with the same name and | 214 // Do file name de-duplication - find files with the same name and |
| 215 // append a name modifier to the name. | 215 // append a name modifier to the name. |
| 216 int max_modifier = 1; | 216 int max_modifier = 1; |
| 217 FilePath full_file_name(entry->base_name()); | 217 FilePath full_file_name(entry->base_name()); |
| 218 const std::string extension = full_file_name.Extension(); | 218 const std::string extension = full_file_name.Extension(); |
| 219 const std::string file_name = full_file_name.RemoveExtension().value(); | 219 const std::string file_name = full_file_name.RemoveExtension().value(); |
| 220 while (FindChild(full_file_name.value())) { | 220 while (!FindChild(full_file_name.value()).empty()) { |
| 221 if (!extension.empty()) { | 221 if (!extension.empty()) { |
| 222 full_file_name = FilePath(base::StringPrintf("%s (%d)%s", | 222 full_file_name = FilePath(base::StringPrintf("%s (%d)%s", |
| 223 file_name.c_str(), | 223 file_name.c_str(), |
| 224 ++max_modifier, | 224 ++max_modifier, |
| 225 extension.c_str())); | 225 extension.c_str())); |
| 226 } else { | 226 } else { |
| 227 full_file_name = FilePath(base::StringPrintf("%s (%d)", | 227 full_file_name = FilePath(base::StringPrintf("%s (%d)", |
| 228 file_name.c_str(), | 228 file_name.c_str(), |
| 229 ++max_modifier)); | 229 ++max_modifier)); |
| 230 } | 230 } |
| 231 } | 231 } |
| 232 entry->set_base_name(full_file_name.value()); | 232 entry->set_base_name(full_file_name.value()); |
| 233 | 233 |
| 234 DVLOG(1) << "AddEntry: dir = " << GetFilePath().value() | 234 DVLOG(1) << "AddEntry: dir = " << GetFilePath().value() |
| 235 << ", file = " + entry->base_name() | 235 << ", file = " + entry->base_name() |
| 236 << ", parent resource = " << entry->parent_resource_id() | 236 << ", parent resource = " << entry->parent_resource_id() |
| 237 << ", resource = " + entry->resource_id(); | 237 << ", resource = " + entry->resource_id(); |
| 238 | 238 |
| 239 // Add entry to resource map. | 239 // Add entry to resource map. |
| 240 directory_service_->AddEntryToResourceMap(entry); | 240 directory_service_->AddEntryToResourceMap(entry); |
| 241 | 241 |
| 242 // Setup child and parent links. | 242 // Setup child and parent links. |
| 243 AddChild(entry); | 243 if (entry->AsGDataFile()) |
| 244 child_files_.insert(std::make_pair(entry->base_name(), | |
| 245 entry->resource_id())); | |
| 246 | |
| 247 if (entry->AsGDataDirectory()) | |
| 248 child_directories_.insert(std::make_pair(entry->base_name(), | |
| 249 entry->resource_id())); | |
| 244 entry->SetParent(this); | 250 entry->SetParent(this); |
| 245 } | 251 } |
| 246 | 252 |
| 247 bool GDataDirectory::TakeOverEntries(GDataDirectory* dir) { | 253 void GDataDirectory::TakeOverEntries(GDataDirectory* dir) { |
| 248 for (GDataFileCollection::const_iterator iter = dir->child_files_.begin(); | 254 for (GDataChildMap::const_iterator iter = dir->child_files_.begin(); |
| 249 iter != dir->child_files_.end(); ++iter) { | 255 iter != dir->child_files_.end(); ++iter) { |
|
satorux1
2012/08/20 16:40:08
maybe add:
const std::string& resource_id = ite
achuithb
2012/08/20 21:14:57
I've added a method TakeOverEntry instead to avoid
| |
| 250 GDataEntry* entry = iter->second; | 256 GDataEntry* entry = directory_service_->GetEntryByResourceId(iter->second); |
| 251 directory_service_->RemoveEntryFromResourceMap(entry->resource_id()); | 257 DCHECK(entry); |
| 258 directory_service_->RemoveEntryFromResourceMap(iter->second); | |
| 252 entry->SetParent(NULL); | 259 entry->SetParent(NULL); |
| 253 AddEntry(entry); | 260 AddEntry(entry); |
| 254 } | 261 } |
| 255 dir->child_files_.clear(); | 262 dir->child_files_.clear(); |
| 256 | 263 |
| 257 for (GDataDirectoryCollection::iterator iter = | 264 for (GDataChildMap::iterator iter = dir->child_directories_.begin(); |
| 258 dir->child_directories_.begin(); | |
| 259 iter != dir->child_directories_.end(); ++iter) { | 265 iter != dir->child_directories_.end(); ++iter) { |
| 260 GDataEntry* entry = iter->second; | 266 GDataEntry* entry = directory_service_->GetEntryByResourceId(iter->second); |
| 261 directory_service_->RemoveEntryFromResourceMap(entry->resource_id()); | 267 DCHECK(entry); |
| 268 directory_service_->RemoveEntryFromResourceMap(iter->second); | |
| 262 entry->SetParent(NULL); | 269 entry->SetParent(NULL); |
| 263 AddEntry(entry); | 270 AddEntry(entry); |
| 264 } | 271 } |
| 265 dir->child_directories_.clear(); | 272 dir->child_directories_.clear(); |
| 266 return true; | |
| 267 } | 273 } |
| 268 | 274 |
| 269 void GDataDirectory::RemoveEntry(GDataEntry* entry) { | 275 void GDataDirectory::RemoveEntry(GDataEntry* entry) { |
| 270 DCHECK(entry); | 276 DCHECK(entry); |
| 271 | 277 |
| 272 RemoveChild(entry); | 278 RemoveChild(entry); |
| 273 delete entry; | 279 delete entry; |
| 274 } | 280 } |
| 275 | 281 |
| 276 GDataEntry* GDataDirectory::FindChild( | 282 const std::string& GDataDirectory::FindChild( |
|
satorux1
2012/08/20 16:40:08
I'd just return const std::string rather than a re
achuithb
2012/08/20 21:14:57
Done.
| |
| 277 const FilePath::StringType& file_name) const { | 283 const FilePath::StringType& file_name) const { |
| 278 GDataFileCollection::const_iterator iter = child_files_.find(file_name); | 284 GDataChildMap::const_iterator iter = child_files_.find(file_name); |
| 279 if (iter != child_files_.end()) | 285 if (iter != child_files_.end()) |
| 280 return iter->second; | 286 return iter->second; |
| 281 | 287 |
| 282 GDataDirectoryCollection::const_iterator itd = | 288 iter = child_directories_.find(file_name); |
| 283 child_directories_.find(file_name); | 289 if (iter != child_directories_.end()) |
| 284 if (itd != child_directories_.end()) | 290 return iter->second; |
| 285 return itd->second; | |
| 286 | 291 |
| 287 return NULL; | 292 return EmptyString(); |
| 288 } | |
| 289 | |
| 290 void GDataDirectory::AddChild(GDataEntry* entry) { | |
| 291 DCHECK(entry); | |
| 292 | |
| 293 if (entry->AsGDataFile()) | |
| 294 child_files_.insert(std::make_pair(entry->base_name(), | |
| 295 entry->AsGDataFile())); | |
| 296 | |
| 297 if (entry->AsGDataDirectory()) | |
| 298 child_directories_.insert(std::make_pair(entry->base_name(), | |
| 299 entry->AsGDataDirectory())); | |
| 300 } | 293 } |
| 301 | 294 |
| 302 void GDataDirectory::RemoveChild(GDataEntry* entry) { | 295 void GDataDirectory::RemoveChild(GDataEntry* entry) { |
| 303 DCHECK(entry); | 296 DCHECK(entry); |
| 304 | 297 |
| 305 const std::string& base_name(entry->base_name()); | 298 const std::string& base_name(entry->base_name()); |
| 306 // entry must be present in this directory. | 299 // entry must be present in this directory. |
| 307 DCHECK_EQ(entry, FindChild(base_name)); | 300 DCHECK_EQ(entry->resource_id(), FindChild(base_name)); |
| 308 // Remove entry from resource map first. | 301 // Remove entry from resource map first. |
| 309 directory_service_->RemoveEntryFromResourceMap(entry->resource_id()); | 302 directory_service_->RemoveEntryFromResourceMap(entry->resource_id()); |
| 310 | 303 |
| 311 // Then delete it from tree. | 304 // Then delete it from tree. |
| 312 child_files_.erase(base_name); | 305 child_files_.erase(base_name); |
| 313 child_directories_.erase(base_name); | 306 child_directories_.erase(base_name); |
| 314 | 307 |
| 315 entry->SetParent(NULL); | 308 entry->SetParent(NULL); |
| 316 } | 309 } |
| 317 | 310 |
| 318 void GDataDirectory::RemoveChildren() { | 311 void GDataDirectory::RemoveChildren() { |
| 319 RemoveChildFiles(); | 312 RemoveChildFiles(); |
| 320 RemoveChildDirectories(); | 313 RemoveChildDirectories(); |
| 321 } | 314 } |
| 322 | 315 |
| 323 void GDataDirectory::RemoveChildFiles() { | 316 void GDataDirectory::RemoveChildFiles() { |
| 324 DVLOG(1) << "RemoveChildFiles " << resource_id(); | 317 DVLOG(1) << "RemoveChildFiles " << resource_id(); |
| 325 for (GDataFileCollection::const_iterator iter = child_files_.begin(); | 318 for (GDataChildMap::const_iterator iter = child_files_.begin(); |
| 326 iter != child_files_.end(); ++iter) { | 319 iter != child_files_.end(); ++iter) { |
| 327 directory_service_->RemoveEntryFromResourceMap(iter->second->resource_id()); | 320 GDataEntry* child = directory_service_->GetEntryByResourceId(iter->second); |
|
satorux1
2012/08/20 16:40:08
DCHECK(child); ?
achuithb
2012/08/20 21:14:57
Done.
| |
| 321 directory_service_->RemoveEntryFromResourceMap(iter->second); | |
| 322 delete child; | |
| 328 } | 323 } |
| 329 STLDeleteValues(&child_files_); | |
| 330 child_files_.clear(); | 324 child_files_.clear(); |
| 331 } | 325 } |
| 332 | 326 |
| 333 void GDataDirectory::RemoveChildDirectories() { | 327 void GDataDirectory::RemoveChildDirectories() { |
| 334 for (GDataDirectoryCollection::iterator iter = child_directories_.begin(); | 328 std::set<GDataDirectory*> child_directories; |
| 329 for (GDataChildMap::iterator iter = child_directories_.begin(); | |
| 335 iter != child_directories_.end(); ++iter) { | 330 iter != child_directories_.end(); ++iter) { |
| 336 GDataDirectory* dir = iter->second; | 331 GDataDirectory* dir = directory_service_->GetEntryByResourceId( |
| 332 iter->second)->AsGDataDirectory(); | |
| 333 DCHECK(dir); | |
| 337 // Remove directories recursively. | 334 // Remove directories recursively. |
| 338 dir->RemoveChildren(); | 335 dir->RemoveChildren(); |
| 339 directory_service_->RemoveEntryFromResourceMap(dir->resource_id()); | 336 directory_service_->RemoveEntryFromResourceMap(iter->second); |
| 337 delete dir; | |
| 340 } | 338 } |
| 341 STLDeleteValues(&child_directories_); | |
| 342 child_directories_.clear(); | 339 child_directories_.clear(); |
| 343 } | 340 } |
| 344 | 341 |
| 345 void GDataDirectory::GetChildDirectoryPaths(std::set<FilePath>* child_dirs) { | 342 void GDataDirectory::GetChildDirectoryPaths(std::set<FilePath>* child_dirs) { |
| 346 for (GDataDirectoryCollection::const_iterator it = child_directories_.begin(); | 343 for (GDataChildMap::const_iterator iter = child_directories_.begin(); |
| 347 it != child_directories_.end(); ++it) { | 344 iter != child_directories_.end(); ++iter) { |
| 348 GDataDirectory* child_dir = it->second; | 345 GDataDirectory* dir = directory_service_->GetEntryByResourceId( |
| 349 child_dirs->insert(child_dir->GetFilePath()); | 346 iter->second)->AsGDataDirectory(); |
| 350 child_dir->GetChildDirectoryPaths(child_dirs); | 347 DCHECK(dir); |
| 348 child_dirs->insert(dir->GetFilePath()); | |
| 349 dir->GetChildDirectoryPaths(child_dirs); | |
| 351 } | 350 } |
| 352 } | 351 } |
| 353 | 352 |
| 354 // Convert to/from proto. | 353 // Convert to/from proto. |
| 355 | 354 |
| 356 // static | 355 // static |
| 357 void GDataEntry::ConvertProtoToPlatformFileInfo( | 356 void GDataEntry::ConvertProtoToPlatformFileInfo( |
| 358 const PlatformFileInfoProto& proto, | 357 const PlatformFileInfoProto& proto, |
| 359 base::PlatformFileInfo* file_info) { | 358 base::PlatformFileInfo* file_info) { |
| 360 file_info->size = proto.size(); | 359 file_info->size = proto.size(); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 463 | 462 |
| 464 // The states of the directory should be updated after children are | 463 // The states of the directory should be updated after children are |
| 465 // handled successfully, so that incomplete states are not left. | 464 // handled successfully, so that incomplete states are not left. |
| 466 GDataEntry::FromProto(proto.gdata_entry()); | 465 GDataEntry::FromProto(proto.gdata_entry()); |
| 467 } | 466 } |
| 468 | 467 |
| 469 void GDataDirectory::ToProto(GDataDirectoryProto* proto) const { | 468 void GDataDirectory::ToProto(GDataDirectoryProto* proto) const { |
| 470 GDataEntry::ToProto(proto->mutable_gdata_entry()); | 469 GDataEntry::ToProto(proto->mutable_gdata_entry()); |
| 471 DCHECK(proto->gdata_entry().file_info().is_directory()); | 470 DCHECK(proto->gdata_entry().file_info().is_directory()); |
| 472 | 471 |
| 473 for (GDataFileCollection::const_iterator iter = child_files_.begin(); | 472 for (GDataChildMap::const_iterator iter = child_files_.begin(); |
| 474 iter != child_files_.end(); ++iter) { | 473 iter != child_files_.end(); ++iter) { |
| 475 GDataFile* file = iter->second; | 474 GDataFile* file = directory_service_->GetEntryByResourceId( |
| 475 iter->second)->AsGDataFile(); | |
| 476 DCHECK(file); | |
| 476 file->ToProto(proto->add_child_files()); | 477 file->ToProto(proto->add_child_files()); |
| 477 } | 478 } |
| 478 for (GDataDirectoryCollection::const_iterator iter = | 479 for (GDataChildMap::const_iterator iter = child_directories_.begin(); |
| 479 child_directories_.begin(); | |
| 480 iter != child_directories_.end(); ++iter) { | 480 iter != child_directories_.end(); ++iter) { |
| 481 GDataDirectory* dir = iter->second; | 481 GDataDirectory* dir = directory_service_->GetEntryByResourceId( |
| 482 iter->second)->AsGDataDirectory(); | |
| 483 DCHECK(dir); | |
| 482 dir->ToProto(proto->add_child_directories()); | 484 dir->ToProto(proto->add_child_directories()); |
| 483 } | 485 } |
| 484 } | 486 } |
| 485 | 487 |
| 486 scoped_ptr<GDataEntryProtoVector> GDataDirectory::ToProtoVector() const { | 488 scoped_ptr<GDataEntryProtoVector> GDataDirectory::ToProtoVector() const { |
| 487 scoped_ptr<GDataEntryProtoVector> entries(new GDataEntryProtoVector); | 489 scoped_ptr<GDataEntryProtoVector> entries(new GDataEntryProtoVector); |
| 488 for (GDataFileCollection::const_iterator iter = child_files_.begin(); | 490 // Use ToProtoFull, as we don't want to include children in |proto|. |
| 491 for (GDataChildMap::const_iterator iter = child_files_.begin(); | |
| 489 iter != child_files_.end(); ++iter) { | 492 iter != child_files_.end(); ++iter) { |
| 490 GDataEntryProto proto; | 493 GDataEntryProto proto; |
| 491 iter->second->ToProto(&proto); | 494 directory_service_->GetEntryByResourceId(iter->second)->ToProtoFull(&proto); |
| 492 entries->push_back(proto); | 495 entries->push_back(proto); |
| 493 } | 496 } |
| 494 for (GDataDirectoryCollection::const_iterator iter = | 497 for (GDataChildMap::const_iterator iter = child_directories_.begin(); |
| 495 child_directories_.begin(); | |
| 496 iter != child_directories_.end(); ++iter) { | 498 iter != child_directories_.end(); ++iter) { |
| 497 GDataEntryProto proto; | 499 GDataEntryProto proto; |
| 498 // Convert to GDataEntry, as we don't want to include children in |proto|. | 500 directory_service_->GetEntryByResourceId(iter->second)->ToProtoFull(&proto); |
| 499 static_cast<const GDataEntry*>(iter->second)->ToProtoFull(&proto); | |
| 500 entries->push_back(proto); | 501 entries->push_back(proto); |
| 501 } | 502 } |
| 502 | 503 |
| 503 return entries.Pass(); | 504 return entries.Pass(); |
| 504 } | 505 } |
| 505 | 506 |
| 506 void GDataEntry::SerializeToString(std::string* serialized_proto) const { | 507 void GDataEntry::SerializeToString(std::string* serialized_proto) const { |
| 507 const GDataFile* file = AsGDataFileConst(); | 508 const GDataFile* file = AsGDataFileConst(); |
| 508 const GDataDirectory* dir = AsGDataDirectoryConst(); | 509 const GDataDirectory* dir = AsGDataDirectoryConst(); |
| 509 | 510 |
| 510 if (file) { | 511 if (file) { |
| 511 GDataEntryProto entry_proto; | 512 GDataEntryProto entry_proto; |
| 512 file->ToProto(&entry_proto); | 513 file->ToProto(&entry_proto); |
| 513 const bool ok = entry_proto.SerializeToString(serialized_proto); | 514 const bool ok = entry_proto.SerializeToString(serialized_proto); |
| 514 DCHECK(ok); | 515 DCHECK(ok); |
| 515 } else if (dir) { | 516 } else if (dir) { |
| 516 GDataDirectoryProto dir_proto; | 517 GDataDirectoryProto dir_proto; |
| 517 dir->ToProto(&dir_proto); | 518 dir->ToProto(&dir_proto); |
| 518 const bool ok = dir_proto.SerializeToString(serialized_proto); | 519 const bool ok = dir_proto.SerializeToString(serialized_proto); |
| 519 DCHECK(ok); | 520 DCHECK(ok); |
| 520 } | 521 } |
| 521 } | 522 } |
| 522 | 523 |
| 523 } // namespace gdata | 524 } // namespace gdata |
| OLD | NEW |