// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "components/drive/file_change.h" #include #include "base/logging.h" #include "base/strings/stringprintf.h" #include "components/drive/drive.pb.h" namespace drive { FileChange::Change::Change(ChangeType change, FileType file_type) : change_(change), file_type_(file_type) { } std::string FileChange::Change::DebugString() const { const char* change_string = NULL; switch (change()) { case CHANGE_TYPE_ADD_OR_UPDATE: change_string = "ADD_OR_UPDATE"; break; case CHANGE_TYPE_DELETE: change_string = "DELETE"; break; } const char* type_string = "NO_INFO"; switch (file_type()) { case FileChange::FILE_TYPE_FILE: type_string = "FILE"; break; case FileChange::FILE_TYPE_DIRECTORY: type_string = "DIRECTORY"; break; case FILE_TYPE_NO_INFO: // Keeps it as "no_info". break; } return base::StringPrintf("%s:%s", change_string, type_string); } FileChange::ChangeList::ChangeList() { } FileChange::ChangeList::~ChangeList() { } void FileChange::ChangeList::Update(const Change& new_change) { if (list_.empty()) { list_.push_back(new_change); return; } Change& last = list_.back(); if (last.IsFile() != new_change.IsFile()) { list_.push_back(new_change); return; } if (last.change() == new_change.change()) return; // ADD + DELETE on directory -> revert if (!last.IsFile() && last.IsAddOrUpdate() && new_change.IsDelete()) { list_.pop_back(); return; } // DELETE + ADD/UPDATE -> ADD/UPDATE // ADD/UPDATE + DELETE -> DELETE last = new_change; } FileChange::ChangeList FileChange::ChangeList::PopAndGetNewList() const { ChangeList changes; changes.list_ = this->list_; changes.list_.pop_front(); return changes; } std::string FileChange::ChangeList::DebugString() const { std::ostringstream ss; ss << "{ "; for (size_t i = 0; i < list_.size(); ++i) ss << list_[i].DebugString() << ", "; ss << "}"; return ss.str(); } FileChange::FileChange() { } FileChange::~FileChange() {} void FileChange::Update(const base::FilePath file_path, const FileChange::Change& new_change) { map_[file_path].Update(new_change); } void FileChange::Update(const base::FilePath file_path, const FileChange::ChangeList& new_change) { for (ChangeList::List::const_iterator it = new_change.list().begin(); it != new_change.list().end(); it++) { map_[file_path].Update(*it); } } void FileChange::Update(const base::FilePath file_path, FileType file_type, FileChange::ChangeType change) { Update(file_path, FileChange::Change(change, file_type)); } void FileChange::Update(const base::FilePath file_path, const ResourceEntry& entry, FileChange::ChangeType change) { FileType type = !entry.has_file_info() ? FILE_TYPE_NO_INFO : entry.file_info().is_directory() ? FILE_TYPE_DIRECTORY : FILE_TYPE_FILE; Update(file_path, type, change); } void FileChange::Apply(const FileChange& new_changed_files) { for (Map::const_iterator it = new_changed_files.map().begin(); it != new_changed_files.map().end(); it++) { Update(it->first, it->second); } } size_t FileChange::CountDirectory(const base::FilePath& directory_path) const { size_t count = 0; for (Map::const_iterator it = map_.begin(); it != map_.end(); it++) { if (it->first.DirName() == directory_path) count++; } return count; } std::string FileChange::DebugString() const { std::ostringstream ss; ss << "{ "; for (FileChange::Map::const_iterator it = map_.begin(); it != map_.end(); it++) { ss << it->first.value() << ": " << it->second.DebugString() << ", "; } ss << "}"; return ss.str(); } } // namespace drive