diff options
Diffstat (limited to 'components/drive/file_change.cc')
-rw-r--r-- | components/drive/file_change.cc | 154 |
1 files changed, 154 insertions, 0 deletions
diff --git a/components/drive/file_change.cc b/components/drive/file_change.cc new file mode 100644 index 0000000..0bdd7bc --- /dev/null +++ b/components/drive/file_change.cc @@ -0,0 +1,154 @@ +// 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 <sstream> + +#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 |