summaryrefslogtreecommitdiffstats
path: root/components/drive/file_change.cc
diff options
context:
space:
mode:
Diffstat (limited to 'components/drive/file_change.cc')
-rw-r--r--components/drive/file_change.cc154
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