| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2009 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 // The main idea in Courgette is to do patching *under a tranformation*. The | |
| 6 // input is transformed into a new representation, patching occurs in the new | |
| 7 // repesentation, and then the tranform is reversed to get the patched data. | |
| 8 // | |
| 9 // The idea is applied to pieces (or 'Elements') of the whole (or 'Ensemble'). | |
| 10 // Each of the elements has to go through the same set of steps in lock-step, | |
| 11 // but there may be many different kinds of elements, which have different | |
| 12 // transformation. | |
| 13 // | |
| 14 // This file declares all the main types involved in creating and applying a | |
| 15 // patch with this structure. | |
| 16 | |
| 17 #ifndef COURGETTE_ENSEMBLE_H_ | |
| 18 #define COURGETTE_ENSEMBLE_H_ | |
| 19 | |
| 20 #include <vector> | |
| 21 #include <string> | |
| 22 | |
| 23 #include "base/basictypes.h" | |
| 24 | |
| 25 #include "third_party/courgette/courgette.h" | |
| 26 #include "third_party/courgette/region.h" | |
| 27 #include "third_party/courgette/streams.h" | |
| 28 | |
| 29 namespace courgette { | |
| 30 | |
| 31 // Forward declarations: | |
| 32 class Ensemble; | |
| 33 class PEInfo; | |
| 34 | |
| 35 // An Element is a region of an Ensemble with an identifyable kind. | |
| 36 // | |
| 37 class Element { | |
| 38 public: | |
| 39 enum Kind { WIN32_X86_WITH_CODE, WIN32_NOCODE }; | |
| 40 | |
| 41 virtual ~Element() {} | |
| 42 | |
| 43 Kind kind() const { return kind_; } | |
| 44 const Region& region() const { return region_; } | |
| 45 | |
| 46 // The name is used only for debugging and logging. | |
| 47 virtual std::string Name() const; | |
| 48 | |
| 49 // Returns the byte position of this Element relative to the start of | |
| 50 // containing Ensemble. | |
| 51 size_t offset_in_ensemble() const; | |
| 52 | |
| 53 // Some subclasses of Element might have a PEInfo. | |
| 54 virtual PEInfo* GetPEInfo() const { return NULL; } | |
| 55 | |
| 56 protected: | |
| 57 Element(Kind kind, Ensemble* ensemble, const Region& region); | |
| 58 | |
| 59 private: | |
| 60 Kind kind_; | |
| 61 Ensemble* ensemble_; | |
| 62 Region region_; | |
| 63 | |
| 64 DISALLOW_COPY_AND_ASSIGN(Element); | |
| 65 }; | |
| 66 | |
| 67 | |
| 68 class Ensemble { | |
| 69 public: | |
| 70 Ensemble(const Region& region, const char* name) | |
| 71 : region_(region), name_(name) {} | |
| 72 ~Ensemble(); | |
| 73 | |
| 74 const Region& region() const { return region_; } | |
| 75 const std::string& name() const { return name_; } | |
| 76 | |
| 77 // Scans the region to find Elements within the region(). | |
| 78 Status FindEmbeddedElements(); | |
| 79 | |
| 80 // Returns the elements found by 'FindEmbeddedElements'. | |
| 81 const std::vector<Element*>& elements() const { return elements_; } | |
| 82 | |
| 83 | |
| 84 private: | |
| 85 Region region_; // The memory, owned by caller, containing the | |
| 86 // Ensemble's data. | |
| 87 std::string name_; // A debugging/logging name for the Ensemble. | |
| 88 | |
| 89 std::vector<Element*> elements_; // Embedded elements discovered. | |
| 90 std::vector<Element*> owned_elements_; // For deallocation. | |
| 91 | |
| 92 DISALLOW_COPY_AND_ASSIGN(Ensemble); | |
| 93 }; | |
| 94 | |
| 95 inline size_t Element::offset_in_ensemble() const { | |
| 96 return region().start() - ensemble_->region().start(); | |
| 97 } | |
| 98 | |
| 99 // The 'CourgettePatchFile' is class is a 'namespace' for the constants that | |
| 100 // appear in a Courgette patch file. | |
| 101 struct CourgettePatchFile { | |
| 102 // | |
| 103 // The Courgette patch format interleaves the data for N embedded Elements. | |
| 104 // | |
| 105 // Format of a patch file: | |
| 106 // header: | |
| 107 // magic | |
| 108 // version | |
| 109 // source-checksum | |
| 110 // target-checksum | |
| 111 // multiple-streams: | |
| 112 // stream 0: | |
| 113 // number-of-transformed-elements (N) - varint32 | |
| 114 // transformation-1-method-id | |
| 115 // transformation-2-method-id | |
| 116 // ... | |
| 117 // transformation-1-initial-parameters | |
| 118 // transformation-2-initial-parameters | |
| 119 // ... | |
| 120 // stream 1: | |
| 121 // correction: | |
| 122 // transformation-1-parameters | |
| 123 // transformation-2-parameters | |
| 124 // ... | |
| 125 // stream 2: | |
| 126 // correction: | |
| 127 // transformed-element-1 | |
| 128 // transformed-element-2 | |
| 129 // ... | |
| 130 // stream 3: | |
| 131 // correction: | |
| 132 // base-file | |
| 133 // element-1 | |
| 134 // element-2 | |
| 135 // ... | |
| 136 | |
| 137 static const uint32 kMagic = 'C' | ('o' << 8) | ('u' << 16); | |
| 138 | |
| 139 static const uint32 kVersion = 20090320; | |
| 140 | |
| 141 // Transformation method IDs. | |
| 142 enum TransformationMethodId { | |
| 143 T_COURGETTE_WIN32_X86 = 1, // Windows 32 bit 'Portable Executable' x86. | |
| 144 }; | |
| 145 }; | |
| 146 | |
| 147 // For any transform you would implement both a TransformationPatcher and a | |
| 148 // TransformationPatchGenerator. | |
| 149 // | |
| 150 // TransformationPatcher is the interface which abstracts out the actual | |
| 151 // transformation used on an Element. The patching itself happens outside the | |
| 152 // actions of a TransformationPatcher. There are four steps. | |
| 153 // | |
| 154 // The first step is an Init step. The parameters to the Init step identify the | |
| 155 // element, for example, range of locations within the original ensemble that | |
| 156 // correspond to the element. | |
| 157 // | |
| 158 // PredictTransformParameters, explained below. | |
| 159 // | |
| 160 // The two final steps are 'Transform' - to transform the element into a new | |
| 161 // representation, and to 'Reform' - to transform from the new representation | |
| 162 // back to the original form. | |
| 163 // | |
| 164 // The Transform step takes some parameters. This allows the transform to be | |
| 165 // customized to the particular element, or to receive some assistance in the | |
| 166 // analysis required to perform the transform. The transform parameters might | |
| 167 // be extensive but mostly predicable, so preceeding Transform is a | |
| 168 // PredictTransformParameters step. | |
| 169 // | |
| 170 class TransformationPatcher { | |
| 171 public: | |
| 172 virtual ~TransformationPatcher() {} | |
| 173 | |
| 174 // First step: provides parameters for the patching. This would at a minimum | |
| 175 // identify the element within the ensemble being patched. | |
| 176 virtual Status Init(SourceStream* parameter_stream) = 0; | |
| 177 | |
| 178 // Second step: predicts transform parameters. | |
| 179 virtual Status PredictTransformParameters( | |
| 180 SinkStreamSet* predicted_parameters) = 0; | |
| 181 | |
| 182 // Third step: transforms element from original representation into alternate | |
| 183 // representation. | |
| 184 virtual Status Transform(SourceStreamSet* corrected_parameters, | |
| 185 SinkStreamSet* transformed_element) = 0; | |
| 186 | |
| 187 // Final step: transforms element back from alternate representation into | |
| 188 // original representation. | |
| 189 virtual Status Reform(SourceStreamSet* transformed_element, | |
| 190 SinkStream* reformed_element) = 0; | |
| 191 }; | |
| 192 | |
| 193 // TransformationPatchGenerator is the interface which abstracts out the actual | |
| 194 // transformation used (and adjustment used) when differentially compressing one | |
| 195 // Element from the |new_ensemble| against a corresponding element in the | |
| 196 // |old_ensemble|. | |
| 197 // | |
| 198 // This is not a pure interface. There is a small amount of inheritance | |
| 199 // implementation for the fields and actions common to all | |
| 200 // TransformationPatchGenerators. | |
| 201 // | |
| 202 // When TransformationPatchGenerator is subclassed, there will be a | |
| 203 // corresponding subclass of TransformationPatcher. | |
| 204 // | |
| 205 class TransformationPatchGenerator { | |
| 206 public: | |
| 207 TransformationPatchGenerator(Element* old_element, | |
| 208 Element* new_element, | |
| 209 TransformationPatcher* patcher); | |
| 210 | |
| 211 virtual ~TransformationPatchGenerator(); | |
| 212 | |
| 213 // Returns the TransformationMethodId that identies this transformation. | |
| 214 virtual CourgettePatchFile::TransformationMethodId Kind() = 0; | |
| 215 | |
| 216 // Writes the parameters that will be passed to TransformationPatcher::Init. | |
| 217 virtual Status WriteInitialParameters(SinkStream* parameter_stream) = 0; | |
| 218 | |
| 219 // Predicts the transform parameters for the |old_element|. This must match | |
| 220 // exactly the output that will be produced by the PredictTransformParameters | |
| 221 // method of the corresponding subclass of TransformationPatcher. This method | |
| 222 // is not pure. The default implementation delegates to the patcher to | |
| 223 // guarantee matching output. | |
| 224 virtual Status PredictTransformParameters(SinkStreamSet* prediction); | |
| 225 | |
| 226 // Writes the desired parameters for the transform of the old element from the | |
| 227 // file representation to the alternate representation. | |
| 228 virtual Status CorrectedTransformParameters(SinkStreamSet* parameters) = 0; | |
| 229 | |
| 230 // Writes both |old_element| and |new_element| in the new representation. | |
| 231 // |old_corrected_parameters| will match the |corrected_parameters| passed to | |
| 232 // the Transform method of the corresponding sublcass of | |
| 233 // TransformationPatcher. | |
| 234 // | |
| 235 // The output written to |old_transformed_element| must match exactly the | |
| 236 // output written by the Transform method of the corresponding subclass of | |
| 237 // TransformationPatcher. | |
| 238 virtual Status Transform(SourceStreamSet* old_corrected_parameters, | |
| 239 SinkStreamSet* old_transformed_element, | |
| 240 SinkStreamSet* new_transformed_element) = 0; | |
| 241 | |
| 242 // Transforms the new transformed_element back from the alternate | |
| 243 // representation into the original file format. This must match exactly the | |
| 244 // output that will be produced by the corresponding subclass of | |
| 245 // TransformationPatcher::Reform. This method is not pure. The default | |
| 246 // implementation delegates to the patcher. | |
| 247 virtual Status Reform(SourceStreamSet* transformed_element, | |
| 248 SinkStream* reformed_element); | |
| 249 | |
| 250 protected: | |
| 251 Element* old_element_; | |
| 252 Element* new_element_; | |
| 253 TransformationPatcher* patcher_; | |
| 254 }; | |
| 255 | |
| 256 } // namespace | |
| 257 #endif // COURGETTE_ENSEMBLE_H_ | |
| OLD | NEW |