| Index: chrome/installer/util/file_from_template_work_item.cc
|
| diff --git a/chrome/installer/util/file_from_template_work_item.cc b/chrome/installer/util/file_from_template_work_item.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..2580f6d55e1fc32322a923a0c34194bc37ff4112
|
| --- /dev/null
|
| +++ b/chrome/installer/util/file_from_template_work_item.cc
|
| @@ -0,0 +1,131 @@
|
| +// 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 "chrome/installer/util/file_from_template_work_item.h"
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/file_util.h"
|
| +#include "base/logging.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "base/string_piece.h"
|
| +#include "base/string_split.h"
|
| +
|
| +namespace {
|
| + const char16 kVariableDefiner(L'$');
|
| +} // namespace
|
| +
|
| +FileFromTemplateWorkItem::~FileFromTemplateWorkItem() {
|
| +}
|
| +
|
| +FileFromTemplateWorkItem::FileFromTemplateWorkItem(
|
| + const FilePath& source_path,
|
| + const FilePath& dest_path,
|
| + const FilePath& temp_dir,
|
| + const std::map<string16, string16>& mappings)
|
| + : source_path_(source_path),
|
| + dest_path_(dest_path),
|
| + temp_dir_(temp_dir),
|
| + mappings_(mappings),
|
| + moved_to_backup_(false) {
|
| +}
|
| +
|
| +bool FileFromTemplateWorkItem::Do() {
|
| + if (!file_util::PathExists(source_path_)) {
|
| + LOG(ERROR) << source_path_.value() << " does not exist";
|
| + return false;
|
| + }
|
| +
|
| + // All templates need to end with the .template extension as they are
|
| + // validated in a presubmit check if so.
|
| + DCHECK(source_path_.MatchesExtension(L".template"));
|
| +
|
| + // If |dest_path_| exists, move it to a backup directory to be able to
|
| + // rollback if necessary.
|
| + if (file_util::PathExists(dest_path_)) {
|
| + if (!backup_path_.CreateUniqueTempDirUnderPath(temp_dir_)) {
|
| + PLOG(ERROR) << "Failed to get backup path in folder "
|
| + << temp_dir_.value();
|
| + return false;
|
| + }
|
| + FilePath backup = backup_path_.path().Append(dest_path_.BaseName());
|
| +
|
| + if (file_util::Move(dest_path_, backup)) {
|
| + moved_to_backup_ = true;
|
| + VLOG(1) << "Moved destination " << dest_path_.value()
|
| + << " to backup path " << backup.value();
|
| + } else {
|
| + PLOG(ERROR) << "failed moving " << dest_path_.value()
|
| + << " to " << backup.value();
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + // Proceed with reading the template at |src_path_| and writing the resulting
|
| + // file to |dest_path_|.
|
| + string16 template_str16;
|
| + {
|
| + std::string template_str;
|
| + if (!file_util::ReadFileToString(source_path_, &template_str)) {
|
| + PLOG(ERROR) << "failed to read template file" << source_path_.value();
|
| + return false;
|
| + }
|
| + // We know the template read is correctly formed as it was verified in
|
| + // a presubmit check.
|
| + // TODO (gab): Write the actual presubmit check.
|
| + template_str16 = UTF8ToUTF16(template_str);
|
| + }
|
| +
|
| + // Split the contents on kVariableDefiner such that entries in |contents| will
|
| + // be alternating between template text and template variables to be replaced.
|
| + std::vector<string16> contents;
|
| + base::SplitString(template_str16, kVariableDefiner, &contents);
|
| +
|
| + string16 out_str16;
|
| + // The first string in |contents| is only a variable if the template starts
|
| + // with kVariableDefiner.
|
| + bool is_var = (template_str16[0] == kVariableDefiner);
|
| + for (std::vector<string16>::iterator it = contents.begin();
|
| + it != contents.end(); ++it, is_var = !is_var) {
|
| + if (is_var) {
|
| + if (mappings_.count(*it) == 0) {
|
| + LOG(ERROR) << "Template variable '" << *it
|
| + << "' not found in mappings.";
|
| + return false;
|
| + } else {
|
| + const string16& val = mappings_.find(*it)->second;
|
| + out_str16.append(val);
|
| + VLOG(1) << "FileFromTemplate for " << source_path_.value() << ": '"
|
| + << *it << "' replaced by '" << val << "'.";
|
| + }
|
| + } else {
|
| + out_str16.append(*it);
|
| + }
|
| + }
|
| +
|
| + const std::string out_str(UTF16ToUTF8(out_str16));
|
| + const int out_size = static_cast<int>(out_str.size());
|
| + const int bytes_written =
|
| + file_util::WriteFile(dest_path_, out_str.c_str(), out_size);
|
| + if (bytes_written == out_size) {
|
| + VLOG(1) << "Successfully extracted template from " << source_path_.value()
|
| + << " to " << dest_path_.value();
|
| + return true;
|
| + } else {
|
| + LOG(ERROR) << "Error writing result to " << dest_path_.value();
|
| + if (bytes_written >= 0) {
|
| + LOG(ERROR) << bytes_written << " bytes were written when " << out_size
|
| + << " were expected to be.";
|
| + }
|
| + return false;
|
| + }
|
| +}
|
| +
|
| +void FileFromTemplateWorkItem::Rollback() {
|
| + FilePath backup = backup_path_.path().Append(dest_path_.BaseName());
|
| + if (moved_to_backup_ && !file_util::Move(backup, dest_path_)) {
|
| + LOG(ERROR) << "failed move " << backup.value()
|
| + << " back to " << dest_path_.value();
|
| + }
|
| +}
|
|
|