Index: third_party/courgette/ensemble.cc |
=================================================================== |
--- third_party/courgette/ensemble.cc (revision 0) |
+++ third_party/courgette/ensemble.cc (revision 0) |
@@ -0,0 +1,102 @@ |
+// Copyright (c) 2009 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. |
+ |
+// *** File comments |
+ |
+#include "third_party/courgette/ensemble.h" |
+ |
+#include "base/basictypes.h" |
+#include "base/logging.h" |
+#include "base/string_util.h" |
+ |
+#include "third_party/courgette/image_info.h" |
+#include "third_party/courgette/region.h" |
+#include "third_party/courgette/streams.h" |
+#include "third_party/courgette/simple_delta.h" |
+ |
+namespace courgette { |
+ |
+Element::Element(Kind kind, Ensemble* ensemble, const Region& region) |
+ : kind_(kind), ensemble_(ensemble), region_(region) { |
+} |
+ |
+std::string Element::Name() const { |
+ return ensemble_->name() + "(" |
+ + IntToString(kind()) + "," |
+ + Uint64ToString(offset_in_ensemble()) + "," |
+ + Uint64ToString(region().length()) + ")"; |
+} |
+ |
+// A subclass of Element that has a PEInfo. |
+class ElementWinPE : public Element { |
+ public: |
+ ElementWinPE(Kind kind, Ensemble* ensemble, const Region& region, |
+ PEInfo* info) |
+ : Element(kind, ensemble, region), |
+ pe_info_(info) { |
+ } |
+ |
+ virtual PEInfo* GetPEInfo() const { return pe_info_; } |
+ |
+ protected: |
+ ~ElementWinPE() { delete pe_info_; } |
+ |
+ private: |
+ PEInfo* pe_info_; // Owned by |this|. |
+}; |
+ |
+// Scans the Ensemble's region, sniffing out Elements. We assume that the |
+// elements do not overlap. |
+Status Ensemble::FindEmbeddedElements() { |
+ size_t length = region_.length(); |
+ const uint8* start = region_.start(); |
+ |
+ size_t position = 0; |
+ while (position < length) { |
+ // Quick test; Windows executables begin with 'MZ'. |
+ if (start[position] == 'M' && |
+ position + 1 < length && start[position + 1] == 'Z') { |
+ courgette::PEInfo *info = new courgette::PEInfo(); |
+ info->Init(start + position, length - position); |
+ if (info->ParseHeader()) { |
+ Region region(start + position, info->length()); |
+ |
+ if (info->has_text_section()) { |
+ Element* element = new ElementWinPE(Element::WIN32_X86_WITH_CODE, |
+ this, region, info); |
+ owned_elements_.push_back(element); |
+ elements_.push_back(element); |
+ position += region.length(); |
+ continue; |
+ } |
+ |
+ // If we had a clever transformation for resource-only executables we |
+ // should identify the suitable elements here: |
+ if (!info->has_text_section() && false) { |
+ Element* element = new ElementWinPE(Element::WIN32_NOCODE, |
+ this, region, info); |
+ owned_elements_.push_back(element); |
+ elements_.push_back(element); |
+ position += region.length(); |
+ continue; |
+ } |
+ } |
+ delete info; |
+ } |
+ |
+ // This is where to add new formats, e.g. Linux executables, Dalvik |
+ // executables etc. |
+ |
+ // No Element found at current position. |
+ ++position; |
+ } |
+ return C_OK; |
+} |
+ |
+Ensemble::~Ensemble() { |
+ for (size_t i = 0; i < owned_elements_.size(); ++i) |
+ delete owned_elements_[i]; |
+} |
+ |
+} // namespace |