#pragma once #include /** 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년 기준 시간) 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; // var[fileNameLength] fileName // var[extraFieldLength] extraField }; /** 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 compressedSize; // same as unCompression (cuz no compreesion) uint32_t unCompressedSize; uint16_t fileNameLength; uint16_t extraFieldLength; uint16_t fileCommentLength; uint16_t diskNumStart; uint16_t attributeInternal; uint32_t attributeExternal; uint32_t offsetLocalHeader; // var[fileNameLength] fileName // var[extraFieldLength] extraField // var[fileCommentLength] fileComment }; /** 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 OffsetOfCentralDirOffset; uint16_t LengthOfCommentLength; // var[zipFileCommentLength] zipFileComment }; #pragma pack(pop)