| Index: courgette/courgette_flow.h
|
| diff --git a/courgette/courgette_flow.h b/courgette/courgette_flow.h
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..9b8cb889126fd1e29c4e86a459aa945c84bee781
|
| --- /dev/null
|
| +++ b/courgette/courgette_flow.h
|
| @@ -0,0 +1,144 @@
|
| +// 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.
|
| +
|
| +#ifndef COURGETTE_COURGETTE_FLOW_H_
|
| +#define COURGETTE_COURGETTE_FLOW_H_
|
| +
|
| +#include <memory>
|
| +#include <string>
|
| +
|
| +#include "base/macros.h"
|
| +#include "courgette/courgette.h"
|
| +#include "courgette/region.h"
|
| +#include "courgette/streams.h"
|
| +
|
| +namespace courgette {
|
| +
|
| +class AssemblyProgram;
|
| +class EncodedProgram;
|
| +
|
| +// An adaptor for Region as BasicBuffer.
|
| +class RegionBuffer : public BasicBuffer {
|
| + public:
|
| + explicit RegionBuffer(const Region& region) : region_(region) {}
|
| + ~RegionBuffer() override {}
|
| +
|
| + // BasicBuffer:
|
| + const uint8_t* data() const override { return region_.start(); }
|
| + size_t length() const override { return region_.length(); }
|
| +
|
| + private:
|
| + Region region_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(RegionBuffer);
|
| +};
|
| +
|
| +// CourgetteFlow stores Courgette data arranged into groups, and exposes
|
| +// "commands" that operate on them. On the first occurrence of an error, the
|
| +// Courgette error code is recorded, error messages are generated and stored,
|
| +// and all subsequent commands become no-op. This allows callers to concisely
|
| +// specify high-level logic with minimal code for error handling.
|
| +class CourgetteFlow {
|
| + public:
|
| + // A group of Courgette data, for a single executable. Takes negligible space
|
| + // when unused.
|
| + struct Data {
|
| + Data();
|
| + ~Data();
|
| +
|
| + std::unique_ptr<AssemblyProgram> program;
|
| + std::unique_ptr<EncodedProgram> encoded;
|
| + SinkStreamSet sinks;
|
| + SourceStreamSet sources;
|
| + };
|
| +
|
| + // Group enumeration into |data_*_| fields.
|
| + enum Group {
|
| + ONLY, // The only file processed.
|
| + OLD, // The "old" file during patching.
|
| + NEW, // The "new" file during patching.
|
| + };
|
| +
|
| + CourgetteFlow();
|
| + ~CourgetteFlow();
|
| +
|
| + static const char* name(Group group);
|
| + Data* data(Group group); // Allows caller to modify.
|
| + bool ok();
|
| + bool failed();
|
| + Status status();
|
| + const std::string& message();
|
| +
|
| + // Commands that perform no-op on error. This allows caller to concisely
|
| + // specify high-level logic, and perform a single error check at the end. Care
|
| + // must be taken w.r.t. error handling if |data()| is harvested between
|
| + // commands.
|
| +
|
| + // Reads |buffer| to initialize |data(group)->sources|.
|
| + void ReadSourceStreamSetFromBuffer(Group group, const BasicBuffer& buffer);
|
| +
|
| + // Reads |buffer| to initialize |data(group)->program|, passing |annotate| as
|
| + // initialization parameter (true if AdjustNewAssemblyProgramToMatchOld() gets
|
| + // called later).
|
| + void ReadAssemblyProgramFromBuffer(Group group,
|
| + const BasicBuffer& buffer,
|
| + bool annotate);
|
| +
|
| + // Reads |opt_sources| if given, or else |data(group)->sources| to initialize
|
| + // |data(group).encoded|.
|
| + void ReadEncodedProgramFromSourceStreamSet(
|
| + Group group,
|
| + SourceStreamSet* opt_sources = nullptr);
|
| +
|
| + // Uses |data(group)->program| to initialize |data(group)->encoded|.
|
| + void CreateEncodedProgramFromAssemblyProgram(Group group);
|
| +
|
| + // Serializese |data(group)->sinks| to |sink|.
|
| + void WriteSinkStreamFromSinkStreamSet(Group group, SinkStream* sink);
|
| +
|
| + // Serializes |data(group)->encoded| to |opt_sinks| if given, or else to
|
| + // |data(group)->sinks|.
|
| + void WriteSinkStreamSetFromEncodedProgram(Group group,
|
| + SinkStreamSet* opt_sinks = nullptr);
|
| +
|
| + // Converts |data(group)->encoded| to an exectuable and writes the result to
|
| + // |sink|.
|
| + void WriteExecutableFromEncodedProgram(Group group, SinkStream* sink);
|
| +
|
| + // Adjusts |data(NEW)->program| Labels to match |data(OLD)->program| Labels.
|
| + void AdjustNewAssemblyProgramToMatchOld();
|
| +
|
| + // Destructor commands to reduce memory usage.
|
| +
|
| + void DestroyAssemblyProgram(Group group);
|
| +
|
| + void DestroyEncodedProgram(Group group);
|
| +
|
| + private:
|
| + // Utilities to process return values from Courgette functions, and assign
|
| + // |status_| and |message_|. Usage:
|
| + // if (!check(some_courgette_function(param1, ...)))
|
| + // setMessage("format string %s...", value1, ...);
|
| +
|
| + // Reassigns |status_|, and returns true if |C_OK|.
|
| + bool check(Status new_status);
|
| +
|
| + // check() alternative for functions that return true on succes. On failure
|
| + // assigns |status_| to |failure_mode|.
|
| + bool check(bool success, Status failure_mode);
|
| +
|
| + void setMessage(const char* format, ...);
|
| +
|
| + Status status_ = C_OK;
|
| + std::string message_;
|
| + Data data_only_;
|
| + Data data_old_;
|
| + Data data_new_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(CourgetteFlow);
|
| +};
|
| +
|
| +} // namespace courgette
|
| +
|
| +#endif // COURGETTE_COURGETTE_FLOW_H_
|
|
|