[M108 Migration][HBBTV] Implement ewk_context_register_jsplugin_mime_types API
[platform/framework/web/chromium-efl.git] / courgette / courgette_flow.cc
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "courgette/courgette_flow.h"
6
7 #include <stdarg.h>
8
9 #include <memory>
10
11 #include "base/check.h"
12 #include "base/files/file_path.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/notreached.h"
15 #include "base/strings/stringprintf.h"
16 #include "courgette/assembly_program.h"
17 #include "courgette/disassembler.h"
18 #include "courgette/encoded_program.h"
19 #include "courgette/program_detector.h"
20
21 namespace courgette {
22
23 /******** CourgetteFlow::Data ********/
24
25 CourgetteFlow::Data::Data() = default;
26
27 CourgetteFlow::Data::~Data() = default;
28
29 /******** CourgetteFlow ********/
30
31 CourgetteFlow::CourgetteFlow() = default;
32
33 CourgetteFlow::~CourgetteFlow() = default;
34
35 // static
36 const char* CourgetteFlow::name(Group group) {
37   switch (group) {
38     case ONLY:
39       return "input";
40     case OLD:
41       return "'old' input";
42     case NEW:
43       return "'new' input";
44     default:
45       NOTREACHED();
46       break;
47   }
48   return nullptr;
49 }
50
51 CourgetteFlow::Data* CourgetteFlow::data(Group group) {
52   switch (group) {
53     case ONLY:
54       return &data_only_;
55     case OLD:
56       return &data_old_;
57     case NEW:
58       return &data_new_;
59     default:
60       NOTREACHED();
61       break;
62   }
63   return nullptr;
64 }
65
66 bool CourgetteFlow::ok() {
67   return status_ == C_OK;
68 }
69
70 bool CourgetteFlow::failed() {
71   return status_ != C_OK;
72 }
73
74 Status CourgetteFlow::status() {
75   return status_;
76 }
77
78 const std::string& CourgetteFlow::message() {
79   return message_;
80 }
81
82 void CourgetteFlow::ReadSourceStreamSetFromBuffer(Group group,
83                                                   const BasicBuffer& buffer) {
84   if (failed())
85     return;
86   Data* d = data(group);
87   if (!check(d->sources.Init(buffer.data(), buffer.length()),
88              C_GENERAL_ERROR)) {
89     setMessage("Cannot read %s as SourceStreamSet.", name(group));
90   }
91 }
92
93 void CourgetteFlow::ReadDisassemblerFromBuffer(Group group,
94                                                const BasicBuffer& buffer) {
95   if (failed())
96     return;
97   Data* d = data(group);
98   d->disassembler = DetectDisassembler(buffer.data(), buffer.length());
99   if (!check(d->disassembler.get() != nullptr, C_INPUT_NOT_RECOGNIZED))
100     setMessage("Cannot detect program for %s.", name(group));
101 }
102
103 void CourgetteFlow::ReadEncodedProgramFromSourceStreamSet(
104     Group group,
105     SourceStreamSet* opt_sources /* nullptr */) {
106   if (failed())
107     return;
108   Data* d = data(group);
109   SourceStreamSet* sources = opt_sources ? opt_sources : &d->sources;
110   if (!check(ReadEncodedProgram(sources, &d->encoded)))
111     setMessage("Cannot read %s as encoded program.", name(group));
112 }
113
114 void CourgetteFlow::CreateAssemblyProgramFromDisassembler(Group group,
115                                                           bool annotate) {
116   if (failed())
117     return;
118   Data* d = data(group);
119   d->program = d->disassembler->CreateProgram(annotate);
120   if (!check(d->program.get() != nullptr, C_DISASSEMBLY_FAILED))
121     setMessage("Cannot create AssemblyProgram for %s.", name(group));
122 }
123
124 void CourgetteFlow::CreateEncodedProgramFromDisassemblerAndAssemblyProgram(
125     Group group) {
126   if (failed())
127     return;
128   Data* d = data(group);
129   d->encoded = std::make_unique<EncodedProgram>();
130   if (!check(d->disassembler->DisassembleAndEncode(d->program.get(),
131                                                    d->encoded.get()))) {
132     setMessage("Cannot disassemble to form EncodedProgram for %s.",
133                name(group));
134   }
135 }
136
137 void CourgetteFlow::WriteSinkStreamFromSinkStreamSet(Group group,
138                                                      SinkStream* sink) {
139   DCHECK(sink);
140   if (failed())
141     return;
142   if (!check(data(group)->sinks.CopyTo(sink), C_GENERAL_ERROR))
143     setMessage("Cannnot combine serialized streams for %s.", name(group));
144 }
145
146 void CourgetteFlow::WriteSinkStreamSetFromEncodedProgram(
147     Group group,
148     SinkStreamSet* opt_sinks /* nullptr */) {
149   if (failed())
150     return;
151   Data* d = data(group);
152   SinkStreamSet* sinks = opt_sinks ? opt_sinks : &d->sinks;
153   if (!check(WriteEncodedProgram(d->encoded.get(), sinks)))
154     setMessage("Cannot serialize encoded %s.", name(group));
155 }
156
157 void CourgetteFlow::WriteExecutableFromEncodedProgram(Group group,
158                                                       SinkStream* sink) {
159   DCHECK(sink);
160   if (failed())
161     return;
162   if (!check(Assemble(data(group)->encoded.get(), sink)))
163     setMessage("Cannot assemble %s.", name(group));
164 }
165
166 void CourgetteFlow::AdjustNewAssemblyProgramToMatchOld() {
167   if (failed())
168     return;
169   if (!check(Adjust(*data_old_.program, data_new_.program.get())))
170     setMessage("Cannot adjust %s to match %s.", name(OLD), name(NEW));
171 }
172
173 void CourgetteFlow::DestroyDisassembler(Group group) {
174   if (failed())
175     return;
176   data(group)->disassembler.reset();
177 }
178
179 void CourgetteFlow::DestroyAssemblyProgram(Group group) {
180   if (failed())
181     return;
182   data(group)->program.reset();
183 }
184
185 void CourgetteFlow::DestroyEncodedProgram(Group group) {
186   if (failed())
187     return;
188   data(group)->encoded.reset();
189 }
190
191 bool CourgetteFlow::check(Status new_status) {
192   if (new_status == C_OK)
193     return true;
194   status_ = new_status;
195   return false;
196 }
197
198 bool CourgetteFlow::check(bool success, Status failure_mode) {
199   if (success)
200     return true;
201   status_ = failure_mode;
202   return false;
203 }
204
205 void CourgetteFlow::setMessage(const char* format, ...) {
206   va_list args;
207   va_start(args, format);
208   message_ = base::StringPrintV(format, args);
209   va_end(args);
210 }
211
212 }  // namespace courgette