aboutsummaryrefslogtreecommitdiff
path: root/zucchini_integration.cc
diff options
context:
space:
mode:
authorSamuel Huang <huangs@chromium.org>2018-06-21 15:50:22 +0000
committerCopybara-Service <copybara-worker@google.com>2021-07-25 19:59:48 -0700
commitf35146e48edca6755e98749a2cb5cc00272d308b (patch)
tree62e88698cbb4f79fea0f7b10326961b0f665e0a8 /zucchini_integration.cc
parent87dabe1110568bd11cd9044b1c5c49ab598bc2ad (diff)
downloadzucchini-f35146e48edca6755e98749a2cb5cc00272d308b.tar.gz
[Zucchini] Refactor Zucchini-gen in zucchini_io layer.
This CL moves Zucchini-gen invocation code from zucchini_commands.cc (in target zucchini) to zucchini_integration.cc (in target zucchini_io) to clean up layering in Zucchini API, i.e.: - zucchini_lib: Operates on buffers only. - zucchini_io: Adds files interface, uses memory-mapped I/O. - zucchini: Stand-alone executable that parses command-line arguments. Other changes: - Rename zucchini_lib functions (zuchcini.h), to dedup names and emphasize that these functions operate on buffers: - GenerateEnsemble() -> GenerateBuffer(), - GenerateEnsembleWithImposedMatches() -> GenerateBufferImposed(), - GenerateRaw() -> GenerateBufferRaw(), - Apply() -> ApplyBuffer(). These renames only affect Zucchini and various tests. - Variable renames and parameter reordering in zucchini_integration.cc. - Remove '-dd' param in help text of Zucchini-detect (was never ported from Trunk, and has been recently deleted there as well). - Replace all base::File&& with base::File. - Miscellaneous cleanup for header include. - Update README.md. Change-Id: I835b80d4d3d7b291fa822a7a89dab225bf9171e9 Reviewed-on: https://chromium-review.googlesource.com/1105625 Reviewed-by: Samuel Huang <huangs@chromium.org> Reviewed-by: Greg Thompson <grt@chromium.org> Commit-Queue: Samuel Huang <huangs@chromium.org> Cr-Commit-Position: refs/heads/master@{#569274} NOKEYCHECK=True GitOrigin-RevId: 9f0f325d6e2595deb8d50c77e0464946f3bf1ec1
Diffstat (limited to 'zucchini_integration.cc')
-rw-r--r--zucchini_integration.cc154
1 files changed, 117 insertions, 37 deletions
diff --git a/zucchini_integration.cc b/zucchini_integration.cc
index 1149658..97790a3 100644
--- a/zucchini_integration.cc
+++ b/zucchini_integration.cc
@@ -19,92 +19,172 @@ struct FileNames {
FileNames() : is_dummy(true) {
// Use fake names.
old_name = old_name.AppendASCII("old_name");
- patch_name = patch_name.AppendASCII("patch_name");
new_name = new_name.AppendASCII("new_name");
+ patch_name = patch_name.AppendASCII("patch_name");
}
FileNames(const base::FilePath& old_name,
- const base::FilePath& patch_name,
- const base::FilePath& new_name)
+ const base::FilePath& new_name,
+ const base::FilePath& patch_name)
: old_name(old_name),
- patch_name(patch_name),
new_name(new_name),
+ patch_name(patch_name),
is_dummy(false) {}
base::FilePath old_name;
- base::FilePath patch_name;
base::FilePath new_name;
+ base::FilePath patch_name;
// A flag to decide whether the filenames are only for error output.
const bool is_dummy;
};
-status::Code ApplyCommon(base::File&& old_file_handle,
- base::File&& patch_file_handle,
- base::File&& new_file_handle,
+status::Code GenerateCommon(base::File old_file,
+ base::File new_file,
+ base::File patch_file,
+ const FileNames& names,
+ bool force_keep,
+ bool is_raw,
+ std::string imposed_matches) {
+ MappedFileReader mapped_old(std::move(old_file));
+ if (mapped_old.HasError()) {
+ LOG(ERROR) << "Error with file " << names.old_name.value() << ": "
+ << mapped_old.error();
+ return status::kStatusFileReadError;
+ }
+
+ MappedFileReader mapped_new(std::move(new_file));
+ if (mapped_new.HasError()) {
+ LOG(ERROR) << "Error with file " << names.new_name.value() << ": "
+ << mapped_new.error();
+ return status::kStatusFileReadError;
+ }
+
+ status::Code result = status::kStatusSuccess;
+ EnsemblePatchWriter patch_writer(mapped_old.region(), mapped_new.region());
+ if (is_raw) {
+ result = GenerateBufferRaw(mapped_old.region(), mapped_new.region(),
+ &patch_writer);
+ } else {
+ result = GenerateBufferImposed(mapped_old.region(), mapped_new.region(),
+ std::move(imposed_matches), &patch_writer);
+ }
+ if (result != status::kStatusSuccess) {
+ LOG(ERROR) << "Fatal error encountered when generating patch.";
+ return result;
+ }
+
+ // By default, delete patch on destruction, to avoid having lingering files in
+ // case of a failure. On Windows deletion can be done by the OS.
+ MappedFileWriter mapped_patch(names.patch_name, std::move(patch_file),
+ patch_writer.SerializedSize());
+ if (mapped_patch.HasError()) {
+ LOG(ERROR) << "Error with file " << names.patch_name.value() << ": "
+ << mapped_patch.error();
+ return status::kStatusFileWriteError;
+ }
+ if (force_keep)
+ mapped_patch.Keep();
+
+ if (!patch_writer.SerializeInto(mapped_patch.region()))
+ return status::kStatusPatchWriteError;
+
+ // Successfully created patch. Explicitly request file to be kept.
+ if (!mapped_patch.Keep())
+ return status::kStatusFileWriteError;
+ return status::kStatusSuccess;
+}
+
+status::Code ApplyCommon(base::File old_file,
+ base::File patch_file,
+ base::File new_file,
const FileNames& names,
bool force_keep) {
- MappedFileReader patch_file(std::move(patch_file_handle));
- if (patch_file.HasError()) {
+ MappedFileReader mapped_patch(std::move(patch_file));
+ if (mapped_patch.HasError()) {
LOG(ERROR) << "Error with file " << names.patch_name.value() << ": "
- << patch_file.error();
+ << mapped_patch.error();
return status::kStatusFileReadError;
}
- auto patch_reader =
- zucchini::EnsemblePatchReader::Create(patch_file.region());
+ auto patch_reader = EnsemblePatchReader::Create(mapped_patch.region());
if (!patch_reader.has_value()) {
LOG(ERROR) << "Error reading patch header.";
return status::kStatusPatchReadError;
}
- MappedFileReader old_file(std::move(old_file_handle));
- if (old_file.HasError()) {
+ MappedFileReader mapped_old(std::move(old_file));
+ if (mapped_old.HasError()) {
LOG(ERROR) << "Error with file " << names.old_name.value() << ": "
- << old_file.error();
+ << mapped_old.error();
return status::kStatusFileReadError;
}
- zucchini::PatchHeader header = patch_reader->header();
+ PatchHeader header = patch_reader->header();
// By default, delete output on destruction, to avoid having lingering files
// in case of a failure. On Windows deletion can be done by the OS.
- base::FilePath file_path;
- if (!names.is_dummy)
- file_path = base::FilePath(names.new_name);
-
- MappedFileWriter new_file(file_path, std::move(new_file_handle),
- header.new_size);
- if (new_file.HasError()) {
+ MappedFileWriter mapped_new(names.new_name, std::move(new_file),
+ header.new_size);
+ if (mapped_new.HasError()) {
LOG(ERROR) << "Error with file " << names.new_name.value() << ": "
- << new_file.error();
+ << mapped_new.error();
return status::kStatusFileWriteError;
}
-
if (force_keep)
- new_file.Keep();
+ mapped_new.Keep();
- zucchini::status::Code result =
- zucchini::Apply(old_file.region(), *patch_reader, new_file.region());
+ status::Code result =
+ ApplyBuffer(mapped_old.region(), *patch_reader, mapped_new.region());
if (result != status::kStatusSuccess) {
LOG(ERROR) << "Fatal error encountered while applying patch.";
return result;
}
- // Successfully patch |new_file|. Explicitly request file to be kept.
- if (!new_file.Keep())
+ // Successfully patch |mapped_new|. Explicitly request file to be kept.
+ if (!mapped_new.Keep())
return status::kStatusFileWriteError;
return status::kStatusSuccess;
}
} // namespace
-status::Code Apply(base::File&& old_file_handle,
- base::File&& patch_file_handle,
- base::File&& new_file_handle,
+status::Code Generate(base::File old_file,
+ base::File new_file,
+ base::File patch_file,
+ bool force_keep,
+ bool is_raw,
+ std::string imposed_matches) {
+ const FileNames file_names;
+ return GenerateCommon(std::move(old_file), std::move(new_file),
+ std::move(patch_file), file_names, force_keep, is_raw,
+ std::move(imposed_matches));
+}
+
+status::Code Generate(const base::FilePath& old_path,
+ const base::FilePath& new_path,
+ const base::FilePath& patch_path,
+ bool force_keep,
+ bool is_raw,
+ std::string imposed_matches) {
+ using base::File;
+ File old_file(old_path, File::FLAG_OPEN | File::FLAG_READ);
+ File new_file(new_path, File::FLAG_OPEN | File::FLAG_READ);
+ File patch_file(patch_path, File::FLAG_CREATE_ALWAYS | File::FLAG_READ |
+ File::FLAG_WRITE | File::FLAG_SHARE_DELETE |
+ File::FLAG_CAN_DELETE_ON_CLOSE);
+ const FileNames file_names(old_path, new_path, patch_path);
+ return GenerateCommon(std::move(old_file), std::move(new_file),
+ std::move(patch_file), file_names, force_keep, is_raw,
+ std::move(imposed_matches));
+}
+
+status::Code Apply(base::File old_file,
+ base::File patch_file,
+ base::File new_file,
bool force_keep) {
const FileNames file_names;
- return ApplyCommon(std::move(old_file_handle), std::move(patch_file_handle),
- std::move(new_file_handle), file_names, force_keep);
+ return ApplyCommon(std::move(old_file), std::move(patch_file),
+ std::move(new_file), file_names, force_keep);
}
status::Code Apply(const base::FilePath& old_path,
@@ -117,7 +197,7 @@ status::Code Apply(const base::FilePath& old_path,
File new_file(new_path, File::FLAG_CREATE_ALWAYS | File::FLAG_READ |
File::FLAG_WRITE | File::FLAG_SHARE_DELETE |
File::FLAG_CAN_DELETE_ON_CLOSE);
- const FileNames file_names(old_path, patch_path, new_path);
+ const FileNames file_names(old_path, new_path, patch_path);
return ApplyCommon(std::move(old_file), std::move(patch_file),
std::move(new_file), file_names, force_keep);
}