// 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_ZIP_HEADERS_H_
#define BAZEL_SRC_TOOLS_SINGLEJAR_ZIP_HEADERS_H_

/*
 * Zip file headers, as described in .ZIP File Format Specification
 * http://www.pkware.com/documents/casestudies/APPNOTE.TXT
 */

#include <stdlib.h>
#include <string.h>

#include <cinttypes>

#if defined(__linux__)
#include <endian.h>
#elif defined(__FreeBSD__)
#include <sys/endian.h>
#elif defined(__APPLE__) || defined(_WIN32)
// Hopefully OSX and Windows will keep running solely on little endian CPUs, so:
#define le16toh(x) (x)
#define le32toh(x) (x)
#define le64toh(x) (x)
#define htole16(x) (x)
#define htole32(x) (x)
#define htole64(x) (x)
#else
#error "This platform is not supported."
#endif

#include <string>
#include <type_traits>

#if defined(_MSC_VER) && !defined(__clang__)
#pragma pack(push, 1)
#define attr_packed
#else
#define attr_packed  __attribute__((packed))
#endif

class ziph {
 public:
  static const uint8_t *byte_ptr(const void *ptr) {
    return reinterpret_cast<const uint8_t *>(ptr);
  }

  /* Utility functions to handle Zip64 extensions. Size and position fields in
   * the Zip headers are 32-bit wide. If field's value does not fit into 32
   * bits (more precisely, it is >= 0xFFFFFFFF), the field contains 0xFFFFFFFF
   * and the actual value is saved in the corresponding 64-bit extension field.
   * The first function returns true if there is an extension for the given
   * field value, and the second returns true if given field value needs
   * extension.
   */
  static bool zfield_has_ext64(uint32_t v) { return v == 0xFFFFFFFF; }
  static bool zfield_needs_ext64(uint64_t v) { return v >= 0xFFFFFFFF; }
};

/* Overall .ZIP file format (section 4.3.6), and the corresponding classes
 *    [local file header 1]                          class LH
 *    [encryption header 1]
 *    [file data 1]
 *    [data descriptor 1]
 *    .
 *    .
 *    .
 *    [local file header n]
 *    [encryption header n]
 *    [file data n]
 *    [data descriptor n]
 *    [archive decryption header]
 *    [archive extra data record]
 *    [central directory header 1]                   class CDH
 *    .
 *    .
 *    .
 *    [central directory header n]
 *    [zip64 end of central directory record]        class ECD64
 *    [zip64 end of central directory locator]       class ECDLocator
 *    [end of central directory record]              class ECD
 */

class ExtraField {
 public:
  static const ExtraField *find(uint16_t tag, const uint8_t *start,
                                const uint8_t *end) {
    while (start < end) {
      auto extra_field = reinterpret_cast<const ExtraField *>(start);
      if (extra_field->is(tag)) {
        return extra_field;
      }
      start = ziph::byte_ptr(start) + extra_field->size();
    }
    return nullptr;
  }
  bool is(uint16_t tag) const { return htole16(tag_) == tag; }
  bool is_zip64() const { return is(1); }
  bool is_unix_time() const { return is(0x5455); }
  void signature(uint16_t tag) { tag_ = le16toh(tag); }

  uint16_t payload_size() const { return le16toh(payload_size_); }
  void payload_size(uint16_t v) { payload_size_ = htole16(v); }

  uint16_t size() const { return sizeof(ExtraField) + payload_size(); }

  const ExtraField *next() const {
    return reinterpret_cast<const ExtraField *>(ziph::byte_ptr(this) + size());
  }

 protected:
  uint16_t tag_;
  uint16_t payload_size_;
} attr_packed;

static_assert(4 == sizeof(ExtraField),
              "ExtraField class fields layout is incorrect.");

/* Zip64 Extra Field (section 4.5.3 of the .ZIP format spec)
 *
 * It is present if a value of a uncompressed_size/compressed_size/file_offset
 * exceeds 32 bits. It consists of a 4-byte header followed by
 * [64-bit uncompressed_size] [64-bit compressed_size] [64-bit file_offset]
 * Only the entities whose value exceed 32 bits are present, and the present
 * ones are always in the order shown above. The originating 32-bit field
 * contains 0xFFFFFFFF to indicate that the value is 64-bit and is in
 * Zip64 Extra Field. Section 4.5.3 of the spec mentions that Zip64 extra field
 * of the Local Header MUST have both uncompressed and compressed sizes present.
 */
class Zip64ExtraField : public ExtraField {
 public:
  static const Zip64ExtraField *find(const uint8_t *start, const uint8_t *end) {
    return reinterpret_cast<const Zip64ExtraField *>(
        ExtraField::find(1, start, end));
  }

  bool is() const { return is_zip64(); }
  void signature() { ExtraField::signature(1); }

  // The value of i-th attribute
  uint64_t attr64(int index) const { return le64toh(attr_[index]); }
  void attr64(int index, uint64_t v) { attr_[index] = htole64(v); }

  // Attribute count
  int attr_count() const { return payload_size() / sizeof(attr_[0]); }
  void attr_count(int n) { payload_size(n * sizeof(attr_[0])); }

  // Space needed for this field to accommodate n_attr attributes
  static uint16_t space_needed(int n_attrs) {
    return n_attrs > 0 ? sizeof(Zip64ExtraField) + n_attrs * sizeof(uint64_t)
                       : 0;
  }

 private:
  uint64_t attr_[];
} attr_packed;
static_assert(4 == sizeof(Zip64ExtraField),
              "Zip64ExtraField class fields layout is incorrect.");

/* Extended Timestamp Extra Field.
 * This field in the Central Directory Header contains only the modification
 * time, whereas in the Local Header up to three timestamps (modification.
 * access, creation) may be present.
 * The time values are in standard Unix signed-long format, indicating the
 * number of seconds since 1 January 1970 00:00:00.  The times are relative to
 * Coordinated Universal Time (UTC).
 */
class UnixTimeExtraField : public ExtraField {
 public:
  static const UnixTimeExtraField *find(const uint8_t *start,
                                        const uint8_t *end) {
    return reinterpret_cast<const UnixTimeExtraField *>(
        ExtraField::find(0x5455, start, end));
  }
  bool is() const { return is_unix_time(); }
  void signature() { ExtraField::signature(0x5455); }

  void flags(uint8_t v) { flags_ = v; }
  bool has_modification_time() const { return flags_ & 1; }
  bool has_access_time() const { return flags_ & 2; }
  bool has_creation_time() const { return flags_ & 4; }

  uint32_t timestamp(int index) const { return le32toh(timestamp_[index]); }
  void timestamp(int index, uint32_t v) { timestamp_[index] = htole32(v); }

  int timestamp_count() const {
    return (payload_size() - sizeof(flags_)) / sizeof(timestamp_[0]);
  }

 private:
  uint8_t flags_;
  uint32_t timestamp_[];
} attr_packed;
static_assert(5 == sizeof(UnixTimeExtraField),
              "UnixTimeExtraField layout is incorrect");

/* Local Header precedes each archive file data (section 4.3.7).  */
class LH {
 public:
  bool is() const { return 0x04034b50 == le32toh(signature_); }
  void signature() { signature_ = htole32(0x04034b50); }

  uint16_t version() const { return le16toh(version_); }
  void version(uint16_t v) { version_ = htole16(v); }

  void bit_flag(uint16_t v) { bit_flag_ = htole16(v); }
  uint16_t bit_flag() const { return le16toh(bit_flag_); }

  uint16_t compression_method() const { return le16toh(compression_method_); }
  void compression_method(uint16_t v) { compression_method_ = htole16(v); }

  uint16_t last_mod_file_time() const { return le16toh(last_mod_file_time_); }
  void last_mod_file_time(uint16_t v) { last_mod_file_time_ = htole16(v); }

  uint16_t last_mod_file_date() const { return le16toh(last_mod_file_date_); }
  void last_mod_file_date(uint16_t v) { last_mod_file_date_ = htole16(v); }

  uint32_t crc32() const { return le32toh(crc32_); }
  void crc32(uint32_t v) { crc32_ = htole32(v); }

  size_t compressed_file_size() const {
    size_t size32 = compressed_file_size32();
    if (ziph::zfield_has_ext64(size32)) {
      const Zip64ExtraField *z64 = zip64_extra_field();
      return z64 == nullptr ? 0xFFFFFFFF : z64->attr64(1);
    }
    return size32;
  }
  size_t compressed_file_size32() const {
    return le32toh(compressed_file_size32_);
  }
  void compressed_file_size32(uint32_t v) {
    compressed_file_size32_ = htole32(v);
  }

  size_t uncompressed_file_size() const {
    size_t size32 = uncompressed_file_size32();
    if (ziph::zfield_has_ext64(size32)) {
      const Zip64ExtraField *z64 = zip64_extra_field();
      return z64 == nullptr ? 0xFFFFFFFF : z64->attr64(0);
    }
    return size32;
  }
  size_t uncompressed_file_size32() const {
    return le32toh(uncompressed_file_size32_);
  }
  void uncompressed_file_size32(uint32_t v) {
    uncompressed_file_size32_ = htole32(v);
  }

  uint16_t file_name_length() const { return le16toh(file_name_length_); }
  const char *file_name() const { return file_name_; }
  void file_name(const char *filename, uint16_t len) {
    file_name_length_ = htole16(len);
    if (len) {
      memcpy(file_name_, filename, file_name_length_);
    }
  }
  bool file_name_is(const char *name) const {
    size_t name_len = strlen(name);
    return file_name_length() == name_len &&
           0 == strncmp(file_name(), name, name_len);
  }
  std::string file_name_string() const {
    return std::string(file_name(), file_name_length());
  }

  uint16_t extra_fields_length() const { return le16toh(extra_fields_length_); }
  const uint8_t *extra_fields() const {
    return ziph::byte_ptr(file_name_ + file_name_length());
  }
  uint8_t *extra_fields() {
    return reinterpret_cast<uint8_t *>(file_name_) + file_name_length();
  }
  void extra_fields(const uint8_t *data, uint16_t data_length) {
    extra_fields_length_ = htole16(data_length);
    if (data_length) {
      memcpy(extra_fields(), data, data_length);
    }
  }

  size_t size() const {
    return sizeof(LH) + file_name_length() + extra_fields_length();
  }
  const uint8_t *data() const { return extra_fields() + extra_fields_length(); }
  uint8_t *data() { return extra_fields() + extra_fields_length(); }

  size_t in_zip_size() const {
    return compression_method() ? compressed_file_size()
                                : uncompressed_file_size();
  }

  const Zip64ExtraField *zip64_extra_field() const {
    return Zip64ExtraField::find(extra_fields(),
                                 extra_fields() + extra_fields_length());
  }

  const UnixTimeExtraField *unix_time_extra_field() const {
    return UnixTimeExtraField::find(extra_fields(),
                                    extra_fields() + extra_fields_length());
  }

 private:
  uint32_t signature_;
  uint16_t version_;
  uint16_t bit_flag_;
  uint16_t compression_method_;
  uint16_t last_mod_file_time_;
  uint16_t last_mod_file_date_;
  uint32_t crc32_;
  uint32_t compressed_file_size32_;
  uint32_t uncompressed_file_size32_;
  uint16_t file_name_length_;
  uint16_t extra_fields_length_;
  char file_name_[0];
  // Followed by extra_fields.
} attr_packed;
static_assert(30 == sizeof(LH), "The fields layout for class LH is incorrect");

/* Data descriptor Record:
 *    4.3.9  Data descriptor:
 *
 *      crc-32                          4 bytes
 *      compressed size                 4 bytes
 *       uncompressed size               4 bytes
 *
 *    4.3.9.1 This descriptor MUST exist if bit 3 of the general purpose bit
 *    flag is set (see below).  It is byte aligned and immediately follows the
 *    last byte of compressed data. This descriptor SHOULD be used only when it
 *    was not possible to seek in the output .ZIP file, e.g., when the output
 *    .ZIP file was standard output or a non-seekable device.  For ZIP64(tm)
 *    format archives, the compressed and uncompressed sizes are 8 bytes each.
 *
 *    4.3.9.2 When compressing files, compressed and uncompressed sizes should
 *    be stored in ZIP64 format (as 8 byte values) when a file's size exceeds
 *    0xFFFFFFFF.   However ZIP64 format may be used regardless of the size of a
 *    file.  When extracting, if the zip64 extended information extra field is
 *    present for the file the compressed and uncompressed sizes will be 8 byte
 *    values.
 *
 *    4.3.9.3 Although not originally assigned a signature, the value 0x08074b50
 *    has commonly been adopted as a signature value for the data descriptor
 *    record.  Implementers should be aware that ZIP files may be encountered
 *    with or without this signature marking data descriptors and SHOULD account
 *    for either case when reading ZIP files to ensure compatibility.
 */
class DDR {
 public:
  size_t size(bool compressed_size_is_64bits,
              bool original_size_is_64bits) const {
    return (0x08074b50 == le32toh(optional_signature_) ? 8 : 4) +
           (compressed_size_is_64bits ? 8 : 4) +
           (original_size_is_64bits ? 8 : 4);
  }

 private:
  uint32_t optional_signature_;
} attr_packed;

/* Central Directory Header.  */
class CDH {
 public:
  void signature() { signature_ = htole32(0x02014b50); }
  bool is() const { return 0x02014b50 == le32toh(signature_); }

  uint16_t version() const { return le16toh(version_); }
  void version(uint16_t v) { version_ = htole16(v); }

  uint16_t version_to_extract() const { return le16toh(version_to_extract_); }
  void version_to_extract(uint16_t v) { version_to_extract_ = htole16(v); }

  void bit_flag(uint16_t v) { bit_flag_ = htole16(v); }
  uint16_t bit_flag() const { return le16toh(bit_flag_); }

  uint16_t compression_method() const { return le16toh(compression_method_); }
  void compression_method(uint16_t v) { compression_method_ = htole16(v); }

  uint16_t last_mod_file_time() const { return le16toh(last_mod_file_time_); }
  void last_mod_file_time(uint16_t v) { last_mod_file_time_ = htole16(v); }

  uint16_t last_mod_file_date() const { return le16toh(last_mod_file_date_); }
  void last_mod_file_date(uint16_t v) { last_mod_file_date_ = htole16(v); }

  void crc32(uint32_t v) { crc32_ = htole32(v); }
  uint32_t crc32() const { return le32toh(crc32_); }

  size_t compressed_file_size() const {
    size_t size32 = compressed_file_size32();
    if (ziph::zfield_has_ext64(size32)) {
      const Zip64ExtraField *z64 = zip64_extra_field();
      return z64 == nullptr ? 0xFFFFFFFF
                            : z64->attr64(ziph::zfield_has_ext64(
                                  uncompressed_file_size32()));
    }
    return size32;
  }
  size_t compressed_file_size32() const {
    return le32toh(compressed_file_size32_);
  }
  void compressed_file_size32(uint32_t v) {
    compressed_file_size32_ = htole32(v);
  }

  size_t uncompressed_file_size() const {
    uint32_t size32 = uncompressed_file_size32();
    if (ziph::zfield_has_ext64(size32)) {
      const Zip64ExtraField *z64 = zip64_extra_field();
      return z64 == nullptr ? 0xFFFFFFFF : z64->attr64(0);
    }
    return size32;
  }
  size_t uncompressed_file_size32() const {
    return le32toh(uncompressed_file_size32_);
  }

  void uncompressed_file_size32(uint32_t v) {
    uncompressed_file_size32_ = htole32(v);
  }

  uint16_t file_name_length() const { return le16toh(file_name_length_); }
  const char *file_name() const { return file_name_; }
  void file_name(const char *filename, uint16_t filename_len) {
    file_name_length_ = htole16(filename_len);
    if (filename_len) {
      memcpy(file_name_, filename, filename_len);
    }
  }
  bool file_name_is(const char *name) const {
    size_t name_len = strlen(name);
    return file_name_length() == name_len &&
           0 == strncmp(file_name(), name, name_len);
  }
  std::string file_name_string() const {
    return std::string(file_name(), file_name_length());
  }

  uint16_t extra_fields_length() const { return le16toh(extra_fields_length_); }
  const uint8_t *extra_fields() const {
    return ziph::byte_ptr(file_name_ + file_name_length());
  }
  uint8_t *extra_fields() {
    return reinterpret_cast<uint8_t *>(file_name_) + file_name_length();
  }
  void extra_fields(const uint8_t *data, uint16_t data_length) {
    extra_fields_length_ = htole16(data_length);
    if (data_length && data != extra_fields()) {
      memcpy(extra_fields(), data, data_length);
    }
  }

  uint16_t comment_length() const { return le16toh(comment_length_); }
  void comment_length(uint16_t v) { comment_length_ = htole16(v); }

  uint16_t start_disk_nr() const { return le16toh(start_disk_nr_); }
  void start_disk_nr(uint16_t v) { start_disk_nr_ = htole16(v); }

  uint16_t internal_attributes() const { return le16toh(internal_attributes_); }
  void internal_attributes(uint16_t v) { internal_attributes_ = htole16(v); }

  uint32_t external_attributes() const { return le32toh(external_attributes_); }
  void external_attributes(uint32_t v) { external_attributes_ = htole32(v); }

  uint64_t local_header_offset() const {
    uint32_t size32 = local_header_offset32();
    if (ziph::zfield_has_ext64(size32)) {
      const Zip64ExtraField *z64 = zip64_extra_field();
      int attr_no = ziph::zfield_has_ext64(uncompressed_file_size32());
      if (ziph::zfield_has_ext64(compressed_file_size32())) {
        ++attr_no;
      }
      return z64 == nullptr ? 0xFFFFFFFF : z64->attr64(attr_no);
    }
    return size32;
  }

  uint32_t local_header_offset32() const {
    return le32toh(local_header_offset32_);
  }
  void local_header_offset32(uint32_t v) {
    local_header_offset32_ = htole32(v);
  }
  bool no_size_in_local_header() const { return bit_flag() & 0x08; }
  size_t size() const {
    return sizeof(*this) + file_name_length() + extra_fields_length() +
           comment_length();
  }

  const Zip64ExtraField *zip64_extra_field() const {
    return Zip64ExtraField::find(extra_fields(),
                                 extra_fields() + extra_fields_length());
  }

  const UnixTimeExtraField *unix_time_extra_field() const {
    return UnixTimeExtraField::find(extra_fields(),
                                    extra_fields() + extra_fields_length());
  }

 private:
  uint32_t signature_;
  uint16_t version_;
  uint16_t version_to_extract_;
  uint16_t bit_flag_;
  uint16_t compression_method_;
  uint16_t last_mod_file_time_;
  uint16_t last_mod_file_date_;
  uint32_t crc32_;
  uint32_t compressed_file_size32_;
  uint32_t uncompressed_file_size32_;
  uint16_t file_name_length_;
  uint16_t extra_fields_length_;
  uint16_t comment_length_;
  uint16_t start_disk_nr_;
  uint16_t internal_attributes_;
  uint32_t external_attributes_;
  uint32_t local_header_offset32_;
  char file_name_[0];
  // Followed by extra fields and then comment.
} attr_packed;
static_assert(46 == sizeof(CDH), "Class CDH fields layout is incorrect.");

/* Zip64 End of Central Directory Locator.  */
class ECD64Locator {
 public:
  void signature() { signature_ = htole32(0x07064b50); }
  bool is() const { return 0x07064b50 == le32toh(signature_); }

  void ecd64_disk_nr(uint32_t nr) { ecd64_disk_nr_ = htole32(nr); }
  uint32_t ecd64_disk_nr() const { return le32toh(ecd64_disk_nr_); }

  void ecd64_offset(uint64_t v) { ecd64_offset_ = htole64(v); }
  uint64_t ecd64_offset() const { return le64toh(ecd64_offset_); }

  void total_disks(uint32_t v) { total_disks_ = htole32(v); }
  uint32_t total_disks() const { return le32toh(total_disks_); }

 private:
  uint32_t signature_;
  uint32_t ecd64_disk_nr_;
  uint64_t ecd64_offset_;
  uint32_t total_disks_;
} attr_packed;
static_assert(20 == sizeof(ECD64Locator),
              "ECD64Locator class fields layout is incorrect.");

/* End of Central Directory.  */
class ECD {
 public:
  void signature() { signature_ = htole32(0x06054b50); }
  bool is() const { return 0x06054b50 == le32toh(signature_); }

  void this_disk_nr(uint16_t v) { this_disk_nr_ = htole16(v); }
  uint16_t this_disk_nr() const { return le16toh(this_disk_nr_); }

  void cen_disk_nr(uint16_t v) { cen_disk_nr_ = htole16(v); }
  uint16_t cen_disk_nr() const { return le16toh(cen_disk_nr_); }

  void this_disk_entries16(uint16_t v) { this_disk_entries16_ = htole16(v); }
  uint16_t this_disk_entries16() const { return le16toh(this_disk_entries16_); }

  void total_entries16(uint16_t v) { total_entries16_ = htole16(v); }
  uint16_t total_entries16() const { return le16toh(total_entries16_); }

  void cen_size32(uint32_t v) { cen_size32_ = htole32(v); }
  uint32_t cen_size32() const { return le32toh(cen_size32_); }

  void cen_offset32(uint32_t v) { cen_offset32_ = htole32(v); }
  uint32_t cen_offset32() const { return le32toh(cen_offset32_); }

  void comment(uint8_t *data, uint16_t data_size) {
    comment_length_ = htole16(data_size);
    if (data_size) {
      memcpy(comment_, data, data_size);
    }
  }
  uint16_t comment_length() const { return le16toh(comment_length_); }
  const uint8_t *comment() const { return comment_; }

  uint64_t ecd64_offset() const {
    const ECD64Locator *locator = reinterpret_cast<const ECD64Locator *>(
        ziph::byte_ptr(this) - sizeof(ECD64Locator));
    return locator->is() ? locator->ecd64_offset() : 0xFFFFFFFFFFFFFFFF;
  }

 private:
  uint32_t signature_;
  uint16_t this_disk_nr_;
  uint16_t cen_disk_nr_;
  uint16_t this_disk_entries16_;
  uint16_t total_entries16_;
  uint32_t cen_size32_;
  uint32_t cen_offset32_;
  uint16_t comment_length_;
  uint8_t comment_[0];
} attr_packed;
static_assert(22 == sizeof(ECD), "ECD class fields layout is incorrect.");

/* Zip64 end of central directory.  */
class ECD64 {
 public:
  bool is() const { return 0x06064b50 == le32toh(signature_); }
  void signature() { signature_ = htole32(0x06064b50); }

  void remaining_size(uint64_t v) { remaining_size_ = htole64(v); }
  uint64_t remaining_size() const { return le64toh(remaining_size_); }

  void version(uint16_t v) { version_ = htole16(v); }
  uint16_t version() const { return le16toh(version_); }

  void version_to_extract(uint16_t v) { version_to_extract_ = htole16(v); }
  uint16_t version_to_extract() const { return le16toh(version_to_extract_); }

  void this_disk_nr(uint32_t v) { this_disk_nr_ = htole32(v); }
  uint32_t this_disk_nr() const { return le32toh(this_disk_nr_); }

  void cen_disk_nr(uint32_t v) { cen_disk_nr_ = htole32(v); }
  uint32_t cen_disk_nr() const { return le32toh(cen_disk_nr_); }

  void this_disk_entries(uint64_t v) { this_disk_entries_ = htole64(v); }
  uint64_t this_disk_entries() const { return le64toh(this_disk_entries_); }

  void total_entries(uint64_t v) { total_entries_ = htole64(v); }
  uint64_t total_entries() const { return le64toh(total_entries_); }

  void cen_size(uint64_t v) { cen_size_ = htole64(v); }
  uint64_t cen_size() const { return le64toh(cen_size_); }

  void cen_offset(uint64_t v) { cen_offset_ = htole64(v); }
  uint64_t cen_offset() const { return le64toh(cen_offset_); }

 private:
  uint32_t signature_;
  uint64_t remaining_size_;
  uint16_t version_;
  uint16_t version_to_extract_;
  uint32_t this_disk_nr_;
  uint32_t cen_disk_nr_;
  uint64_t this_disk_entries_;
  uint64_t total_entries_;
  uint64_t cen_size_;
  uint64_t cen_offset_;
} attr_packed;
static_assert(56 == sizeof(ECD64), "ECD64 class fields layout is incorrect.");

#if defined(_MSC_VER) && !defined(__clang__)
#pragma pack(pop)
#endif

#undef attr_packed

#endif  // BAZEL_SRC_TOOLS_SINGLEJAR_ZIP_HEADERS_H_
