Chromium Code Reviews| Index: courgette/courgette_flow.cc |
| diff --git a/courgette/courgette_flow.cc b/courgette/courgette_flow.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8e61ee77b52683c24354c49c2d98b5de084b541d |
| --- /dev/null |
| +++ b/courgette/courgette_flow.cc |
| @@ -0,0 +1,187 @@ |
| +// Copyright 2017 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 "courgette/courgette_flow.h" |
| + |
| +#include <stdarg.h> |
| + |
| +#include "base/files/file_path.h" |
| +#include "base/logging.h" |
| +#include "base/memory/ptr_util.h" |
| +#include "base/strings/stringprintf.h" |
| +#include "courgette/assembly_program.h" |
| +#include "courgette/encoded_program.h" |
| +#include "courgette/program_detector.h" |
| + |
| +namespace courgette { |
| + |
| +/******** CourgetteFlow::Data ********/ |
| + |
| +CourgetteFlow::Data::Data() = default; |
| + |
| +CourgetteFlow::Data::~Data() = default; |
| + |
| +/******** CourgetteFlow ********/ |
| + |
| +CourgetteFlow::CourgetteFlow() = default; |
| + |
| +CourgetteFlow::~CourgetteFlow() = default; |
| + |
| +// static |
| +const char* CourgetteFlow::name(Group group) { |
| + switch (group) { |
| + case ONLY: |
| + return "input"; |
| + case OLD: |
| + return "'old' input"; |
| + case NEW: |
| + return "'new' input"; |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| + return nullptr; |
| +} |
| + |
| +CourgetteFlow::Data* CourgetteFlow::data(Group group) { |
| + switch (group) { |
| + case ONLY: |
| + return &data_only_; |
| + case OLD: |
| + return &data_old_; |
| + case NEW: |
| + return &data_new_; |
| + default: |
| + NOTREACHED(); |
| + break; |
| + } |
| + return nullptr; |
| +} |
| + |
| +bool CourgetteFlow::ok() { |
| + return status_ == C_OK; |
| +} |
| + |
| +bool CourgetteFlow::failed() { |
| + return status_ != C_OK; |
| +} |
| + |
| +Status CourgetteFlow::status() { |
| + return status_; |
| +} |
| + |
| +const std::string& CourgetteFlow::message() { |
| + return message_; |
| +} |
| + |
| +void CourgetteFlow::ReadSourceStreamSetFromBuffer(Group group, |
| + const BasicBuffer& buffer) { |
| + if (ok()) { |
|
chrisha
2017/04/24 18:15:49
if (failed())
return;
Then the rest of the logi
huangs
2017/04/24 20:08:14
Initially I did that, then I got spooked by the bu
|
| + Data* d = data(group); |
| + if (!check(d->sources.Init(buffer.data(), buffer.length()), |
| + C_GENERAL_ERROR)) { |
| + setMessage("Cannot read %s as SourceStreamSet.", name(group)); |
| + } |
| + } |
| +} |
| + |
| +void CourgetteFlow::ReadAssemblyProgramFromBuffer(Group group, |
| + const BasicBuffer& buffer, |
| + bool annotate) { |
| + if (ok()) { |
| + Data* d = data(group); |
| + auto parser = annotate ? ParseDetectedExecutableWithAnnotation |
| + : ParseDetectedExecutable; |
| + if (!check(parser(buffer.data(), buffer.length(), &d->program))) |
| + setMessage("Cannot parse %s (code = %d).", name(group), status_); |
| + } |
| +} |
| + |
| +void CourgetteFlow::ReadEncodedProgramFromSourceStreamSet( |
| + Group group, |
| + SourceStreamSet* opt_sources /* nullptr */) { |
| + if (ok()) { |
| + Data* d = data(group); |
| + SourceStreamSet* sources = opt_sources ? opt_sources : &d->sources; |
| + if (!check(ReadEncodedProgram(sources, &d->encoded))) |
| + setMessage("Cannot read %s as encoded program.", name(group)); |
| + } |
| +} |
| + |
| +void CourgetteFlow::CreateEncodedProgramFromAssemblyProgram(Group group) { |
| + if (ok()) { |
| + Data* d = data(group); |
| + if (!check(Encode(*d->program, &d->encoded))) |
| + setMessage("Cannot encode %s (code = %d).", name(group), status_); |
| + } |
| +} |
| + |
| +void CourgetteFlow::WriteSinkStreamFromSinkStreamSet(Group group, |
| + SinkStream* sink) { |
| + DCHECK(sink); |
| + if (ok()) { |
| + if (!check(data(group)->sinks.CopyTo(sink), C_GENERAL_ERROR)) |
| + setMessage("Cannnot combine serialized streams for %s.", name(group)); |
| + } |
| +} |
| + |
| +void CourgetteFlow::WriteSinkStreamSetFromEncodedProgram( |
| + Group group, |
| + SinkStreamSet* opt_sinks /* nullptr */) { |
| + if (ok()) { |
| + Data* d = data(group); |
| + SinkStreamSet* sinks = opt_sinks ? opt_sinks : &d->sinks; |
| + if (!check(WriteEncodedProgram(d->encoded.get(), sinks))) |
| + setMessage("Cannot serialize encoded %s.", name(group)); |
| + } |
| +} |
| + |
| +void CourgetteFlow::WriteExecutableFromEncodedProgram(Group group, |
| + SinkStream* sink) { |
| + DCHECK(sink); |
| + if (ok()) { |
| + if (!check(Assemble(data(group)->encoded.get(), sink))) |
| + setMessage("Cannot assemble %s.", name(group)); |
| + } |
| +} |
| + |
| +void CourgetteFlow::AdjustNewAssemblyProgramToMatchOld() { |
| + if (ok()) { |
| + if (!check(Adjust(*data_old_.program, data_new_.program.get()))) |
| + setMessage("Cannot adjust %s to match %s.", name(OLD), name(NEW)); |
| + } |
| +} |
| + |
| +void CourgetteFlow::DestroyAssemblyProgram(Group group) { |
| + if (ok()) |
| + data(group)->program.reset(); |
| +} |
| + |
| +void CourgetteFlow::DestroyEncodedProgram(Group group) { |
| + if (ok()) |
| + data(group)->encoded.reset(); |
| +} |
| + |
| +bool CourgetteFlow::check(Status new_status) { |
| + if (new_status == C_OK) |
| + return true; |
| + status_ = new_status; |
| + return false; |
| +} |
| + |
| +bool CourgetteFlow::check(bool success, Status failure_mode) { |
| + if (success) |
| + return true; |
| + status_ = failure_mode; |
| + return false; |
| +} |
| + |
| +void CourgetteFlow::setMessage(const char* format, ...) { |
| + va_list args; |
| + va_start(args, format); |
| + message_ = base::StringPrintV(format, args); |
| + va_end(args); |
| +} |
| + |
| +} // namespace courgette |