| // 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 | 
 |  | 
 | #ifndef __STDC_FORMAT_MACROS | 
 | #define __STDC_FORMAT_MACROS 1 | 
 | #endif | 
 |  | 
 | #include <inttypes.h> | 
 | #include <stdlib.h> | 
 |  | 
 | #include <cstddef> | 
 | #include <cstdint> | 
 | #include <string> | 
 |  | 
 | #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(); } | 
 |  | 
 | #ifndef _WIN32 | 
 |   // Not used on Windows, only in Google's own code. Don't add more usage of it. | 
 |   int fd() const { return mapped_file_.fd(); } | 
 | #endif | 
 |  | 
 |   // Opens the file, memory maps it and locates Central Directory. | 
 |   bool Open(const std::string &path); | 
 |  | 
 |   // Creates an input jar from data that's already in memory. | 
 |   // Requires a non-empty path for use in diagnostics. | 
 |   bool Open(const std::string &path, unsigned char *data, size_t length); | 
 |  | 
 |   // Returns the next Central Directory Header or nullptr. | 
 |   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<const CDH *>(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<const LH *>( | 
 |         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: | 
 |   bool LocateCentralDirectory(const std::string &path); | 
 |  | 
 |   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_ |