// Copyright 2016 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef SRC_TOOLS_SINGLEJAR_COMBINERS_H_ #define SRC_TOOLS_SINGLEJAR_COMBINERS_H_ 1 #include #include #include #include #include #include "src/tools/singlejar/transient_bytes.h" #include "src/tools/singlejar/zip_headers.h" // An interface for combining the files. class Combiner { public: virtual ~Combiner(); // Merges the contents of the given Zip entry to this instance. virtual bool Merge(const CDH *cdh, const LH *lh) = 0; // Returns a point to the buffer containing Local Header followed by the // payload. The caller is responsible of freeing the buffer. If `compress' // is not set, the payload is a copy of the bytes held by this combiner. // Otherwise the payload is compressed, provided that the compressed data // is smaller than the original. virtual void *OutputEntry(bool compress) = 0; }; // An output jar entry consisting of a concatenation of the input jar // entries. Byte sequences can be appended to it, too. class Concatenator : public Combiner { public: Concatenator(const std::string &filename, bool insert_newlines = true) : filename_(filename), insert_newlines_(insert_newlines) {} ~Concatenator() override; bool Merge(const CDH *cdh, const LH *lh) override; void *OutputEntry(bool compress) override; void Append(const char *s, size_t n) { CreateBuffer(); buffer_->Append(reinterpret_cast(s), n); } void Append(const char *s) { Append(s, strlen(s)); } void Append(const std::string &str) { Append(str.c_str(), str.size()); } const std::string &filename() const { return filename_; } private: void CreateBuffer() { if (!buffer_.get()) { buffer_.reset(new TransientBytes()); } } const std::string filename_; std::unique_ptr buffer_; std::unique_ptr inflater_; bool insert_newlines_; }; // The combiner that does nothing. Useful to represent for instance directory // entries: once a directory entry has been created and added to the output // jar, the subsequent entries are ignored on input, and nothing is output. class NullCombiner : public Combiner { public: ~NullCombiner() override; bool Merge(const CDH *cdh, const LH *lh) override; void *OutputEntry(bool compress) override; }; // Combines the contents of the multiple input entries which are XML // files into a single XML output entry with given top level XML tag. class XmlCombiner : public Combiner { public: XmlCombiner(const std::string &filename, const std::string &xml_tag) : filename_(filename), start_tag_("<" + xml_tag + ">"), end_tag_("") {} ~XmlCombiner() override; bool Merge(const CDH *cdh, const LH *lh) override; void *OutputEntry(bool compress) override; const std::string filename() const { return filename_; } private: const std::string filename_; const std::string start_tag_; const std::string end_tag_; std::unique_ptr concatenator_; std::unique_ptr inflater_; }; // A wrapper around Concatenator allowing to append // NAME=VALUE // lines to the contents. // NOTE that it does not allow merging existing entries. class PropertyCombiner : public Concatenator { public: PropertyCombiner(const std::string &filename) : Concatenator(filename) {} ~PropertyCombiner(); bool Merge(const CDH *cdh, const LH *lh) override; void AddProperty(const char *key, const char *value) { // TODO(asmundak): deduplicate properties. Append(key); Append("=", 1); Append(value); Append("\n", 1); } void AddProperty(const std::string &key, const std::string &value) { // TODO(asmundak): deduplicate properties. Append(key); Append("=", 1); Append(value); Append("\n", 1); } }; #endif // SRC_TOOLS_SINGLEJAR_COMBINERS_H_