blob: 7abf9b06ec7643fcc2aefb3daac3da5ed7cedc31 [file] [log] [blame]
// 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(const ChangeList& other) = default;
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(const FileChange& other) = default;
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