1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "courgette/courgette_flow.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "courgette/assembly_program.h"
14 #include "courgette/disassembler.h"
15 #include "courgette/encoded_program.h"
16 #include "courgette/program_detector.h"
20 /******** CourgetteFlow::Data ********/
22 CourgetteFlow::Data::Data() = default;
24 CourgetteFlow::Data::~Data() = default;
26 /******** CourgetteFlow ********/
28 CourgetteFlow::CourgetteFlow() = default;
30 CourgetteFlow::~CourgetteFlow() = default;
33 const char* CourgetteFlow::name(Group group) {
48 CourgetteFlow::Data* CourgetteFlow::data(Group group) {
63 bool CourgetteFlow::ok() {
64 return status_ == C_OK;
67 bool CourgetteFlow::failed() {
68 return status_ != C_OK;
71 Status CourgetteFlow::status() {
75 const std::string& CourgetteFlow::message() {
79 void CourgetteFlow::ReadSourceStreamSetFromBuffer(Group group,
80 const BasicBuffer& buffer) {
83 Data* d = data(group);
84 if (!check(d->sources.Init(buffer.data(), buffer.length()),
86 setMessage("Cannot read %s as SourceStreamSet.", name(group));
90 void CourgetteFlow::ReadDisassemblerFromBuffer(Group group,
91 const BasicBuffer& buffer) {
94 Data* d = data(group);
95 d->disassembler = DetectDisassembler(buffer.data(), buffer.length());
96 if (!check(d->disassembler.get() != nullptr, C_INPUT_NOT_RECOGNIZED))
97 setMessage("Cannot detect program for %s.", name(group));
100 void CourgetteFlow::ReadEncodedProgramFromSourceStreamSet(
102 SourceStreamSet* opt_sources /* nullptr */) {
105 Data* d = data(group);
106 SourceStreamSet* sources = opt_sources ? opt_sources : &d->sources;
107 if (!check(ReadEncodedProgram(sources, &d->encoded)))
108 setMessage("Cannot read %s as encoded program.", name(group));
111 void CourgetteFlow::CreateAssemblyProgramFromDisassembler(Group group,
115 Data* d = data(group);
116 d->program = d->disassembler->CreateProgram(annotate);
117 if (!check(d->program.get() != nullptr, C_DISASSEMBLY_FAILED))
118 setMessage("Cannot create AssemblyProgram for %s.", name(group));
121 void CourgetteFlow::CreateEncodedProgramFromDisassemblerAndAssemblyProgram(
125 Data* d = data(group);
126 d->encoded.reset(new EncodedProgram());
127 if (!check(d->disassembler->DisassembleAndEncode(d->program.get(),
128 d->encoded.get()))) {
129 setMessage("Cannot disassemble to form EncodedProgram for %s.",
134 void CourgetteFlow::WriteSinkStreamFromSinkStreamSet(Group group,
139 if (!check(data(group)->sinks.CopyTo(sink), C_GENERAL_ERROR))
140 setMessage("Cannnot combine serialized streams for %s.", name(group));
143 void CourgetteFlow::WriteSinkStreamSetFromEncodedProgram(
145 SinkStreamSet* opt_sinks /* nullptr */) {
148 Data* d = data(group);
149 SinkStreamSet* sinks = opt_sinks ? opt_sinks : &d->sinks;
150 if (!check(WriteEncodedProgram(d->encoded.get(), sinks)))
151 setMessage("Cannot serialize encoded %s.", name(group));
154 void CourgetteFlow::WriteExecutableFromEncodedProgram(Group group,
159 if (!check(Assemble(data(group)->encoded.get(), sink)))
160 setMessage("Cannot assemble %s.", name(group));
163 void CourgetteFlow::AdjustNewAssemblyProgramToMatchOld() {
166 if (!check(Adjust(*data_old_.program, data_new_.program.get())))
167 setMessage("Cannot adjust %s to match %s.", name(OLD), name(NEW));
170 void CourgetteFlow::DestroyDisassembler(Group group) {
173 data(group)->disassembler.reset();
176 void CourgetteFlow::DestroyAssemblyProgram(Group group) {
179 data(group)->program.reset();
182 void CourgetteFlow::DestroyEncodedProgram(Group group) {
185 data(group)->encoded.reset();
188 bool CourgetteFlow::check(Status new_status) {
189 if (new_status == C_OK)
191 status_ = new_status;
195 bool CourgetteFlow::check(bool success, Status failure_mode) {
198 status_ = failure_mode;
202 void CourgetteFlow::setMessage(const char* format, ...) {
204 va_start(args, format);
205 message_ = base::StringPrintV(format, args);
209 } // namespace courgette