#pragma once #include #include #define ZIP_FOOTER_MAGIC 0x06054b50 // "PK\5\6" #define ZIP_CENTRAL_MAGIC 0x02014b50 // "PK\1\2" #define ZIP_HEADER_MAGIC 0x04034b50 // "PK\3\4" struct zip_file *zip_index(char *const restrict file, size_t const size, int *const restrict /* _Nullable */ error); char const *const zip_error(int const code); // error messages do NOT have any newlines struct zip_index { struct zip_central *central; struct zip_header *header; void *data; uint8_t *filename; size_t filename_length; uint16_t flags; uint16_t method; uint32_t crc32; uint32_t compressed_size; uint32_t original_size; }; struct zip_file { size_t file_count; struct zip_index files[]; }; struct dos_date { uint16_t second: 5, minute: 6, hour: 5; uint16_t day: 5, month: 4, year: 7; }; struct __attribute__((__packed__)) zip_footer { uint32_t magic; uint16_t disk_no; uint16_t central_disk_no; uint16_t headers_no; uint16_t headers_no_total; uint32_t headers_size; uint32_t headers_addr; uint16_t comment_length; uint8_t comment[]; }; struct __attribute__((__packed__)) zip_central { uint32_t magic; uint16_t ver_used; uint16_t ver_needed; uint16_t flags; uint16_t method; struct dos_date mtime; uint32_t checksum; uint32_t compressed_size; uint32_t original_size; uint16_t filename_length; uint16_t extra_length; uint16_t comment_length; uint16_t file_disk_no; uint16_t internal_attr; uint32_t external_attr; uint32_t file_addr; uint8_t filename[]; }; struct __attribute__((__packed__)) zip_header { uint32_t magic; uint16_t ver_needed; uint16_t flags; uint16_t method; struct dos_date mtime; uint32_t checksum; uint32_t compressed_size; uint32_t original_size; uint16_t filename_length; uint16_t extra_length; uint8_t filename[]; };