OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #ifndef COURGETTE_COURGETTE_FLOW_H_ |
| 6 #define COURGETTE_COURGETTE_FLOW_H_ |
| 7 |
| 8 #include <memory> |
| 9 #include <string> |
| 10 |
| 11 #include "base/macros.h" |
| 12 #include "courgette/courgette.h" |
| 13 #include "courgette/region.h" |
| 14 #include "courgette/streams.h" |
| 15 |
| 16 namespace courgette { |
| 17 |
| 18 class AssemblyProgram; |
| 19 class EncodedProgram; |
| 20 |
| 21 // An adaptor for Region as BasicBuffer. |
| 22 class RegionBuffer : public BasicBuffer { |
| 23 public: |
| 24 explicit RegionBuffer(const Region& region) : region_(region) {} |
| 25 ~RegionBuffer() override {} |
| 26 |
| 27 // BasicBuffer: |
| 28 const uint8_t* data() const override { return region_.start(); } |
| 29 size_t length() const override { return region_.length(); } |
| 30 |
| 31 private: |
| 32 Region region_; |
| 33 |
| 34 DISALLOW_COPY_AND_ASSIGN(RegionBuffer); |
| 35 }; |
| 36 |
| 37 // CourgetteFlow stores Courgette data arranged into groups, and exposes |
| 38 // "commands" that operate on them. On the first occurrence of an error, the |
| 39 // Courgette error code is recorded, error messages are generated and stored, |
| 40 // and all subsequent commands become no-op. This allows callers to concisely |
| 41 // specify high-level logic with minimal code for error handling. |
| 42 class CourgetteFlow { |
| 43 public: |
| 44 // A group of Courgette data, for a single executable. Takes negligible space |
| 45 // when unused. |
| 46 struct Data { |
| 47 Data(); |
| 48 ~Data(); |
| 49 |
| 50 std::unique_ptr<AssemblyProgram> program; |
| 51 std::unique_ptr<EncodedProgram> encoded; |
| 52 SinkStreamSet sinks; |
| 53 SourceStreamSet sources; |
| 54 }; |
| 55 |
| 56 // Group enumeration into |data_*_| fields. |
| 57 enum Group { |
| 58 ONLY, // The only file processed. |
| 59 OLD, // The "old" file during patching. |
| 60 NEW, // The "new" file during patching. |
| 61 }; |
| 62 |
| 63 CourgetteFlow(); |
| 64 ~CourgetteFlow(); |
| 65 |
| 66 static const char* name(Group group); |
| 67 Data* data(Group group); // Allows caller to modify. |
| 68 bool ok(); |
| 69 bool failed(); |
| 70 Status status(); |
| 71 const std::string& message(); |
| 72 |
| 73 // Commands that perform no-op on error. This allows caller to concisely |
| 74 // specify high-level logic, and perform a single error check at the end. Care |
| 75 // must be taken w.r.t. error handling if |data()| is harvested between |
| 76 // commands. |
| 77 |
| 78 // Reads |buffer| to initialize |data(group)->sources|. |
| 79 void ReadSourceStreamSetFromBuffer(Group group, const BasicBuffer& buffer); |
| 80 |
| 81 // Reads |buffer| to initialize |data(group)->program|, passing |annotate| as |
| 82 // initialization parameter (true if AdjustNewAssemblyProgramToMatchOld() gets |
| 83 // called later). |
| 84 void ReadAssemblyProgramFromBuffer(Group group, |
| 85 const BasicBuffer& buffer, |
| 86 bool annotate); |
| 87 |
| 88 // Reads |opt_sources| if given, or else |data(group)->sources| to initialize |
| 89 // |data(group).encoded|. |
| 90 void ReadEncodedProgramFromSourceStreamSet( |
| 91 Group group, |
| 92 SourceStreamSet* opt_sources = nullptr); |
| 93 |
| 94 // Uses |data(group)->program| to initialize |data(group)->encoded|. |
| 95 void CreateEncodedProgramFromAssemblyProgram(Group group); |
| 96 |
| 97 // Serializese |data(group)->sinks| to |sink|. |
| 98 void WriteSinkStreamFromSinkStreamSet(Group group, SinkStream* sink); |
| 99 |
| 100 // Serializes |data(group)->encoded| to |opt_sinks| if given, or else to |
| 101 // |data(group)->sinks|. |
| 102 void WriteSinkStreamSetFromEncodedProgram(Group group, |
| 103 SinkStreamSet* opt_sinks = nullptr); |
| 104 |
| 105 // Converts |data(group)->encoded| to an exectuable and writes the result to |
| 106 // |sink|. |
| 107 void WriteExecutableFromEncodedProgram(Group group, SinkStream* sink); |
| 108 |
| 109 // Adjusts |data(NEW)->program| Labels to match |data(OLD)->program| Labels. |
| 110 void AdjustNewAssemblyProgramToMatchOld(); |
| 111 |
| 112 // Destructor commands to reduce memory usage. |
| 113 |
| 114 void DestroyAssemblyProgram(Group group); |
| 115 |
| 116 void DestroyEncodedProgram(Group group); |
| 117 |
| 118 private: |
| 119 // Utilities to process return values from Courgette functions, and assign |
| 120 // |status_| and |message_|. Usage: |
| 121 // if (!check(some_courgette_function(param1, ...))) |
| 122 // setMessage("format string %s...", value1, ...); |
| 123 |
| 124 // Reassigns |status_|, and returns true if |C_OK|. |
| 125 bool check(Status new_status); |
| 126 |
| 127 // check() alternative for functions that return true on succes. On failure |
| 128 // assigns |status_| to |failure_mode|. |
| 129 bool check(bool success, Status failure_mode); |
| 130 |
| 131 void setMessage(const char* format, ...); |
| 132 |
| 133 Status status_ = C_OK; |
| 134 std::string message_; |
| 135 Data data_only_; |
| 136 Data data_old_; |
| 137 Data data_new_; |
| 138 |
| 139 DISALLOW_COPY_AND_ASSIGN(CourgetteFlow); |
| 140 }; |
| 141 |
| 142 } // namespace courgette |
| 143 |
| 144 #endif // COURGETTE_COURGETTE_FLOW_H_ |
OLD | NEW |