#pragma once #include const static uint32_t PK_SIGNATURE_LF_HEADER = 0x04034b50; // PK + 0x0403 const static uint32_t PK_SIGNATURE_CENT_DIR = 0x02014b50; // PK + 0x0201 const static uint32_t PK_SIGNATURE_EO_CDR = 0x06054b50; // PK + 0x0605 const static uint16_t METHOD_UNCOMPRESSED = 0; /** Overall .ZIP file format: [local file header 1] -> "PK" + 0x4b50 + ... [encryption header 1] [file data 1] [data descriptor 1] . . . [local file header n] -> "PK" + 0x4b50 + ... [encryption header n] [file data n] [data descriptor n] [archive decryption header] [archive extra data record] [central directory header 1] . . . [central directory header n] -> "PK" + 0x4b50 [zip64 end of central directory record] [zip64 end of central directory locator] [end of central directory record] <- 필수 포함 (단 한개) */ /** Local file header: local file header signature 4 bytes (0x04034b50) version needed to extract 2 bytes general purpose bit flag 2 bytes compression method 2 bytes last mod file time 2 bytes last mod file date 2 bytes crc-32 4 bytes compressed size 4 bytes uncompressed size 4 bytes file name length 2 bytes -> Variable extra field length 2 bytes -> Variable file name (variable size) extra field (variable size) */ #pragma pack(push, 1) constexpr int LOCAL_FILE_HEADER_BYTE = 30; struct LocalFileHeader { uint32_t signature; uint16_t versionNeededToExtract; uint16_t generalBitFlag; uint16_t compressionMethod; // no compression == 0 uint16_t lastModTime; // 압축 시점의 시간 (1980년 기준 시간, DOS TIME) uint16_t lastModDate; // 압축 시점의 날짜 (1980년 기준 연도, DOS TIME) uint32_t crc32; uint32_t sizeOfCompressed; // same as unCompression (cuz no compreesion) uint32_t sizeOfUncompressed; uint16_t lengthOfFileName; uint16_t lengthOfExtraField; // var[lengthOfFileName] fileName // var[lengthOfExtraField] extraField }; // 정적 메모리 사이즈 검사 static_assert(sizeof(LocalFileHeader) == LOCAL_FILE_HEADER_BYTE, "LocalFileHeader Size is mismatch"); /** Central directory structure: [central directory header 1] . . . [central directory header n] [digital signature] File header: central file header signature 4 bytes (0x02014b50) version made by 2 bytes version needed to extract 2 bytes general purpose bit flag 2 bytes compression method 2 bytes last mod file time 2 bytes last mod file date 2 bytes crc-32 4 bytes compressed size 4 bytes uncompressed size 4 bytes file name length 2 bytes extra field length 2 bytes file comment length 2 bytes disk number start 2 bytes internal file attributes 2 bytes external file attributes 4 bytes relative offset of local header 4 bytes file name (variable size) extra field (variable size) file comment (variable size) */ constexpr int CENTRAL_DIRECTORY_BYTE = 46; struct CentralDirectory { uint32_t signature; uint16_t versionMadeBy; uint16_t versionNeededToExtract; uint16_t generalBitFlag; uint16_t compressionMethod; // no compression == 0 uint16_t lastModTime; // 압축 시점의 시간 (1980년 기준 시간) uint16_t lastModDate; // 압축 시점의 날짜 (1980년 기준 연도) uint32_t crc32; uint32_t sizeOfCompressed; // same as unCompression (cuz no compreesion) uint32_t sizeOfUncompressed; uint16_t lengthOfFileName; uint16_t lengthOfExtraField; uint16_t lengthOfFileComment; uint16_t diskNumStart; uint16_t attributeInternal; uint32_t attributeExternal; uint32_t offsetLocalFileHeader; // var[lengthOfFileName] fileName // var[lengthOfExtraField] extraField // var[lengthOfFileComment] fileComment }; // 정적 메모리 사이즈 검사 static_assert(sizeof(CentralDirectory) == CENTRAL_DIRECTORY_BYTE, "CentralDirectory Size is mismatch"); /** End of central directory record: end of central dir signature 4 bytes (0x0605 + 4b50) number of this disk 2 bytes // 중앙 디렉터리가 시작되는 디스크의 번호. number of the disk with the start of the central directory 2 bytes // 이 디스크에 있는 중앙 디렉터리 항목의 수 total number of entries in the central directory on this disk 2 bytes // .ZIP 파일 내 전체 파일 수 total number of entries in the central directory 2 bytes size of the central directory 4 bytes // 중앙 디렉터리가 시작되는 디스크 상에서 중앙 디렉터리 시작 지점의 오프셋 offset of start of central directory with respect to the starting disk number 4 bytes .ZIP file comment length 2 bytes .ZIP file comment (variable size) */ constexpr int EOCD_BYTE = 22; struct EoCDRecord { uint32_t signature; // central directory end record을 포함하는 이 디스크의 번호 uint16_t diskNumber; // 중앙 디렉터리가 시작되는 디스크의 번호. uint16_t diskNumber_CentralDirStart; // 이 디스크에 있는 중앙 디렉터리 항목의 수 uint16_t numOfCentralDir; // .ZIP 파일 내 전체 파일 수 uint16_t numOfEntries; uint32_t sizeOfCentralDir; uint32_t offsetCentralDir; uint16_t lengthOfCommentLength; // var[LengthOfCommentLength] zipFileComment }; // 정적 메모리 사이즈 검사 static_assert(sizeof(EoCDRecord) == EOCD_BYTE); #pragma pack(pop)