// 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 BAZEL_SRC_TOOLS_SINGLEJAR_INPUT_JAR_H_ #define BAZEL_SRC_TOOLS_SINGLEJAR_INPUT_JAR_H_ 1 #define __STDC_FORMAT_MACROS 1 #include #include #include #include "src/tools/singlejar/diag.h" #include "src/tools/singlejar/mapped_file.h" #include "src/tools/singlejar/zip_headers.h" /* * An input jar. The usage pattern is: * InputJar input_jar; * if (!input_jar.Open("path/to/file")) { fail...} * CDH *dir_entry; * LH *local_header; * while (dir_entry = input_jar.NextEntry(&local_header)) { * // process entry. * } * input_jar.Close(); // actually, called by destructor, too. */ class InputJar { public: InputJar() {} ~InputJar() { Close(); } int fd() const { return mapped_file_.fd(); } // Opens the file, memory maps it and locates Central Directory. bool Open(const std::string& path); // Returns the next Central Directory Header or NULL. const CDH *NextEntry(const LH **local_header_ptr) { if (path_.empty()) { diag_errx(1, "%s:%d: call Open() first!", __FILE__, __LINE__); } if (!cdh_->is()) { return nullptr; } const CDH *current_cdh = cdh_; const uint8_t *new_cdr = ziph::byte_ptr(cdh_) + cdh_->size(); if (!mapped_file_.mapped(new_cdr)) { diag_errx( 1, "Bad directory record at offset 0x%" PRIx64 " of %s\n" "file name length = %u, extra_field length = %u, comment length = %u", CentralDirectoryRecordOffset(cdh_), path_.c_str(), cdh_->file_name_length(), cdh_->extra_fields_length(), cdh_->comment_length()); } cdh_ = reinterpret_cast(new_cdr); *local_header_ptr = LocalHeader(current_cdh); return current_cdh; } // Closes the file. bool Close(); uint64_t CentralDirectoryRecordOffset(const void *cdr) const { return mapped_file_.offset(cdr); } const LH *LocalHeader(const CDH *cdh) const { return reinterpret_cast( mapped_file_.address(cdh->local_header_offset() + preamble_size_)); } uint64_t LocalHeaderOffset(const LH *lh) const { return mapped_file_.offset(lh); } const uint8_t *mapped_start() const { return mapped_file_.address(0); } private: std::string path_; MappedFile mapped_file_; const CDH *cdh_; // current directory entry uint64_t preamble_size_; // Bytes before the Zip proper. }; #endif // BAZEL_SRC_TOOLS_SINGLEJAR_INPUT_JAR_H_