(in-package #:org.shirakumo.zippy)

(define-byte-structure (local-file #x04034B50)
  (version ub16)
  (flags ub16)
  (compression-method ub16)
  (last-modified-time ub16)
  (last-modified-date ub16)
  (crc-32 ub32)
  (compressed-size ub32)
  (uncompressed-size ub32)
  (file-name-length ub16)
  (extra-field-length ub16)
  (file-name ub8 file-name-length)
  (extra ub8 extra-field-length))

(define-byte-structure (data-descriptor #x08074B50)
  (crc-32 ub32)
  (compressed-size ub32)
  (uncompressed-size ub32))

(define-byte-structure (data-descriptor/64 #x08074B50)
  (crc-32 ub32)
  (compressed-size ub64)
  (uncompressed-size ub64))

(define-byte-structure (extra-data #x08064B50)
  (extra-field-length ub32)
  (extra ub8 extra-field-length))

(define-byte-structure (central-directory-entry #x02014B50)
  (version-made ub16)
  (version-needed ub16)
  (flags ub16)
  (compression-method ub16)
  (last-modified-time ub16)
  (last-modified-date ub16)
  (crc-32 ub32)
  (compressed-size ub32)
  (uncompressed-size ub32)
  (file-name-length ub16)
  (extra-field-length ub16)
  (file-comment-length ub16)
  (disk-number-start ub16)
  (internal-file-attributes ub16)
  (external-file-attributes ub32)
  (local-header-offset ub32)
  (file-name ub8 file-name-length)
  (extra ub8 extra-field-length)
  (file-comment ub8 file-comment-length))

(define-byte-structure (digital-signature #x05054B50)
  (size ub16)
  (data ub8 size))

(define-byte-structure (end-of-central-directory/64 #x06064B50)
  (size ub64)
  (version-made ub16)
  (version-needed ub16)
  (number-of-disk ub32)
  (central-directory-disk ub32)
  (disk-entries ub64)
  (central-directory-entries ub64)
  (central-directory-size ub64)
  (central-directory-start ub64)
  (data-sector ub8 (- size 44)))

(define-byte-structure (end-of-central-directory-locator/64 #x07064B50)
  (central-directory-disk ub32)
  (central-directory-start ub64)
  (number-of-disks ub32))

(define-byte-structure (end-of-central-directory #x06054B50)
  (number-of-disk ub16)
  (central-directory-disk ub16)
  (disk-entries ub16)
  (central-directory-entries ub16)
  (central-directory-size ub32)
  (central-directory-start ub32)
  (file-comment-length ub16)
  (file-comment ub8 file-comment-length))

(define-byte-structure decryption-header
  (iv-size ub16)
  (iv ub8 iv-size)
  (size ub32)
  (format ub16)
  (encryption-algorithm ub16)
  (bit-length ub16)
  (flags ub16)
  (random-data-size ub16)
  (random-data ub8 random-data-size)
  (reserved-size ub32)
  (reserved ub8 reserved-size)
  (validation-size ub16)
  (validation ub8 validation-size)
  (crc ub32))

;;; Extensible data fields
(define-byte-structure (zip64-extended-information #x00001)
  (size ub16)
  (original-size ub64)
  (compressed-size ub64)
  (header-offset ub64)
  (starting-disk ub32))

(define-byte-structure (os/2 #x00009)
  (size ub16)
  (uncompressed-size ub32)
  (compression-type ub16)
  (crc ub32)
  (data ub8 (- size 10)))

(define-byte-structure (ntfs #x000A)
  (size ub16)
  (reserved ub32)
  (data ub8 (- size 4)))

(define-byte-structure (openvms #x000C)
  (size ub16)
  (crc ub32)
  (data ub8 (- size 4)))

(define-byte-structure (unix #x000D)
  (size ub16)
  (atime ub32)
  (mtime ub32)
  (uid ub16)
  (gid ub16)
  (data ub8 (- size 12)))

(define-byte-structure (patch-descriptor #x000F)
  (size ub16)
  (version ub16)
  (flags ub32)
  (old-size ub32)
  (old-crc ub32)
  (new-size ub32)
  (new-crc ub32))

(define-byte-structure (pkcs7-store #x0014)
  (size ub16)
  (data ub8 size))

(define-byte-structure (x509-file #x0015)
  (size ub16)
  (data ub8 size))

(define-byte-structure (x509-central-directory #x0016)
  (size ub16)
  (data ub8 size))

(define-byte-structure (encryption-header #x0017)
  (size ub16)
  (format ub16)
  (encryption-algorithm ub16)
  (bit-length ub16)
  (flags ub16)
  (certificate ub8 (- size 8)))

(define-byte-structure (record-management-controls #x0018)
  (size ub16)
  (data ub8 size))

(define-byte-structure (pkcs7-encryption-recipient-certificate-list #x0019)
  (size ub16)
  (version ub16)
  (store ub8 (- size 2)))

(define-byte-structure (mvs #x0065)
  (size ub16)
  (id ub32)
  (data ub8 (- size 4)))

(define-byte-structure (policy-decryption-key-record #x0021)
  (size ub16)
  (data ub8 size))

(define-byte-structure (key-provider-record #x0022)
  (size ub16)
  (data ub8 size))

(define-byte-structure (policy-key-data-record #x0023)
  (size ub16)
  (data ub8 size))


;;; Third-Party Extra Fields
;;; Note: the APPNOTE.TXT mentions many more mappings as 'registered'
;;;       but does not note their internal structure. We just omit
;;;       them here.
(define-byte-structure (zipit-macintosh-long #x2605)
  (size ub16)
  (signature #x5A504954)
  (length ub8)
  (file-name ub8 length)
  (file-type ub8 4)
  (creator ub8 4))

(define-byte-structure (zipit-macintosh-short-file #x2705)
  (size ub16)
  (signature #x5A504954)
  (file-type ub8 4)
  (creator ub8 4)
  (flags ub16))

(define-byte-structure (zipit-macintosh-short-dir #x2805)
  (size ub16)
  (signature #x5A504954)
  (flags ub16)
  (view ub16))

(define-byte-structure (infozip-unicode-comment #x6375)
  (size ub16)
  (version ub8)
  (crc-32 ub32)
  (comment ub8 (- size 6)))

(define-byte-structure (infozip-unicode-path #x7075)
  (size ub16)
  (version ub8)
  (crc-32 ub32)
  (name ub8 (- size 6)))

(define-byte-structure (data-stream-alignment #xa11e)
  (size ub16)
  (alignment ub16)
  (padding ub8 (- size 2)))

(define-byte-structure (microsoft-open-packaging-growth-hint #xa220)
  (size ub16)
  (signature ub16)
  (padding-value ub16)
  (padding ub8 (- size 4)))

(define-byte-structure (aes-extra-data #x9901)
  (size ub16)
  (version ub16)
  (vendor ub16)
  (encryption-strength ub8)
  (compression-method ub16))
