Index: Doxyfile ================================================================== --- Doxyfile +++ Doxyfile @@ -10,10 +10,11 @@ OF_HAVE_FILES \ OF_HAVE_OPTIONAL_PROTOCOLS \ OF_HAVE_PROPERTIES \ OF_HAVE_SOCKETS \ OF_HAVE_THREADS \ + OF_METHOD_NORETURN \ OF_SENTINEL \ OF_REQUIRES_SUPER \ OF_RETURNS_RETAINED \ OF_RETURNS_NOT_RETAINED \ OF_RETURNS_INNER_POINTER \ Index: src/OFZIPArchive.m ================================================================== --- src/OFZIPArchive.m +++ src/OFZIPArchive.m @@ -55,11 +55,11 @@ @end @interface OFZIPArchive_LocalFileHeader: OFObject { @public - uint16_t _minVersion, _generalPurposeBitFlag, _compressionMethod; + uint16_t _minVersionNeeded, _generalPurposeBitFlag, _compressionMethod; uint16_t _lastModifiedFileTime, _lastModifiedFileDate; uint32_t _CRC32; uint64_t _compressedSize, _uncompressedSize; OFString *_fileName; OFDataArray *_extraField; @@ -339,14 +339,14 @@ initWithFile: _file] autorelease]; if (![localFileHeader matchesEntry: entry]) @throw [OFInvalidFormatException exception]; - if ((localFileHeader->_minVersion & 0xFF) > 45) { + if ((localFileHeader->_minVersionNeeded & 0xFF) > 45) { OFString *version = [OFString stringWithFormat: @"%u.%u", - (localFileHeader->_minVersion & 0xFF) / 10, - (localFileHeader->_minVersion & 0xFF) % 10]; + (localFileHeader->_minVersionNeeded & 0xFF) / 10, + (localFileHeader->_minVersionNeeded & 0xFF) % 10]; @throw [OFUnsupportedVersionException exceptionWithVersion: version]; } @@ -374,11 +374,11 @@ uint16_t ZIP64Size; if ([file readLittleEndianInt32] != 0x04034B50) @throw [OFInvalidFormatException exception]; - _minVersion = [file readLittleEndianInt16]; + _minVersionNeeded = [file readLittleEndianInt16]; _generalPurposeBitFlag = [file readLittleEndianInt16]; _compressionMethod = [file readLittleEndianInt16]; _lastModifiedFileTime = [file readLittleEndianInt16]; _lastModifiedFileDate = [file readLittleEndianInt16]; _CRC32 = [file readLittleEndianInt32]; @@ -393,12 +393,12 @@ _fileName = [[file readStringWithLength: fileNameLength encoding: encoding] copy]; _extraField = [[file readDataArrayWithCount: extraFieldLength] retain]; - of_zip_archive_entry_find_extra_field(_extraField, 0x0001, - &ZIP64, &ZIP64Size); + of_zip_archive_entry_extra_field_find(_extraField, + OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64, &ZIP64, &ZIP64Size); if (ZIP64 != NULL) { if (_uncompressedSize == 0xFFFFFFFF) _uncompressedSize = of_zip_archive_read_field64( &ZIP64, &ZIP64Size); @@ -425,13 +425,13 @@ [super dealloc]; } - (bool)matchesEntry: (OFZIPArchiveEntry*)entry { - if (_minVersion != [entry OF_minVersion] || + if (_minVersionNeeded != [entry minVersionNeeded] || _generalPurposeBitFlag != [entry OF_generalPurposeBitFlag] || - _compressionMethod != [entry OF_compressionMethod] || + _compressionMethod != [entry compressionMethod] || _lastModifiedFileTime != [entry OF_lastModifiedFileTime] || _lastModifiedFileDate != [entry OF_lastModifiedFileDate]) return false; if (!(_generalPurposeBitFlag & (1 << 3))) @@ -459,18 +459,18 @@ mode: @"rb"]; [_file seekToOffset: offset whence: SEEK_SET]; switch (localFileHeader->_compressionMethod) { - case 0: /* No compression */ + case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE: _stream = [_file retain]; break; - case 8: /* Deflate */ + case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE: _stream = [[OFDeflateStream alloc] initWithStream: _file]; break; - case 9: /* Deflate64 */ + case OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE64: _stream = [[OFDeflate64Stream alloc] initWithStream: _file]; break; default: @throw [OFNotImplementedException Index: src/OFZIPArchiveEntry+Private.h ================================================================== --- src/OFZIPArchiveEntry+Private.h +++ src/OFZIPArchiveEntry+Private.h @@ -18,17 +18,10 @@ #import "macros.h" @interface OFZIPArchiveEntry (OF_PRIVATE_CATEGORY) - (instancetype)OF_initWithFile: (OFFile*)file; -- (uint16_t)OF_madeWithVersion; -- (uint16_t)OF_minVersion; - (uint16_t)OF_generalPurposeBitFlag; -- (uint16_t)OF_compressionMethod; - (uint16_t)OF_lastModifiedFileTime; - (uint16_t)OF_lastModifiedFileDate; -- (OFDataArray*)OF_extraFieldNoCopy; -- (uint16_t)OF_startDiskNumber; -- (uint16_t)OF_internalAttributes; -- (uint32_t)OF_externalAttributes; - (uint64_t)OF_localFileHeaderOffset; @end Index: src/OFZIPArchiveEntry.h ================================================================== --- src/OFZIPArchiveEntry.h +++ src/OFZIPArchiveEntry.h @@ -15,10 +15,66 @@ */ #import "OFObject.h" /*! @file */ + +enum { + OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE = 0, + OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE = 8, + OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE64 = 9 +}; + +/*! + * @brief Attribute compatibility part of ZIP versions. + */ +enum of_zip_archive_entry_attribute_compatibility { + /** MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems) */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MSDOS = 0, + /** Amiga */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_AMIGA = 1, + /** OpenVMS */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OPENVMS = 2, + /** UNIX */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX = 3, + /** VM/CMS */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VM_CMS = 4, + /** Atari ST */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ATARI_ST = 5, + /** OS/2 HPFS */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS2_HPFS = 6, + /** Macintosh */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MACINTOSH = 7, + /** Z-System */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_Z_SYSTEM = 8, + /** CP/M */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_CP_M = 9, + /** Windows NTFS */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_WINDOWS_NTFS = 10, + /** MVS (OS/390 - Z/OS) */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_MVS = 11, + /** VSE */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VSE = 12, + /** Acorn Risc */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ACORN_RISC = 13, + /** VFAT */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_VFAT = 14, + /** Alternate MVS */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_ALTERNATE_MVS = 15, + /** BeOS */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_BEOS = 16, + /** Tandem */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_TANDEM = 17, + /** OS/400 */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS_400 = 18, + /** OS X (Darwin) */ + OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_OS_X = 19 +}; + +enum { + OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64 = 0x0001 +}; @class OFString; @class OFDataArray; @class OFFile; @class OFDate; @@ -29,29 +85,32 @@ * @brief A class which represents an entry in the central directory of a ZIP * archive. */ @interface OFZIPArchiveEntry: OFObject { - uint16_t _madeWithVersion, _minVersion, _generalPurposeBitFlag; - uint16_t _compressionMethod, _lastModifiedFileTime; - uint16_t _lastModifiedFileDate; + uint16_t _versionMadeBy, _minVersionNeeded, _generalPurposeBitFlag; + uint16_t _compressionMethod; + uint16_t _lastModifiedFileTime, _lastModifiedFileDate; uint32_t _CRC32; uint64_t _compressedSize, _uncompressedSize; OFString *_fileName; OFDataArray *_extraField; OFString *_fileComment; uint32_t _startDiskNumber; uint16_t _internalAttributes; - uint32_t _externalAttributes; + uint32_t _versionSpecificAttributes; uint64_t _localFileHeaderOffset; } #ifdef OF_HAVE_PROPERTIES @property (readonly, copy) OFString *fileName, *fileComment; +@property (readonly) uint16_t versionMadeBy, minVersionNeeded; +@property (readonly) uint16_t compressionMethod; @property (readonly) uint64_t compressedSize, uncompressedSize; @property (readonly, retain) OFDate *modificationDate; @property (readonly) uint32_t CRC32; +@property (readonly) uint32_t versionSpecificAttributes; @property (readonly, copy) OFDataArray *extraField; #endif /*! * @brief Returns the file name of the entry. @@ -65,10 +124,48 @@ * * @return The comment of the entry's file */ - (OFString*)fileComment; +/*! + * @brief Returns the version which made the entry. + * + * The lower 8 bits are the ZIP specification version.@n + * The upper 8 bits are the attribute compatibility. + * See @ref of_zip_archive_entry_attribute_compatibility. + * + * @return The version which made the entry + */ +- (uint16_t)versionMadeBy; + +/*! + * @brief Returns the minimum version required to extract the file. + * + * The lower 8 bits are the ZIP specification version.@n + * The upper 8 bits are the attribute compatibility. + * See @ref of_zip_archive_entry_attribute_compatibility. + * + * @return The minimum version required to extract the file + */ +- (uint16_t)minVersionNeeded; + +/*! + * @brief Returns the compression method of the entry + * + * Supported values are: + * Value | Description + * --------------------------------------------------|--------------- + * OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_NONE | No compression + * OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE | Deflate + * OF_ZIP_ARCHIVE_ENTRY_COMPRESSION_METHOD_DEFLATE64 | Deflate64 + * + * Other values may be returned, but the file cannot be extracted then. + * + * @return The compression method of the entry + */ +- (uint16_t)compressionMethod; + /*! * @brief Returns the compressed size of the entry's file. * * @return The compressed size of the entry's file */ @@ -93,10 +190,20 @@ * * @return The CRC32 checksum of the entry's file */ - (uint32_t)CRC32; +/*! + * @brief Returns the version specific attributes. + * + * The meaning of the version specific attributes depends on the attribute + * compatibility part of the version that made the entry. + * + * @return The version specific attributes + */ +- (uint32_t)versionSpecificAttributes; + /*! * @brief Returns the extra field of the entry. * * @return The extra field of the entry */ @@ -105,17 +212,20 @@ #ifdef __cplusplus extern "C" { #endif /*! - * @brief Gets a pointer to and the size of the extra field with the specified - * tag. + * @brief Gets a pointer to and the size of the extensible data field with the + * specified tag. * + * @param extraField The extra field to search for an extensible data field with + * the specified tag + * @param tag The tag to look for * @param data A pointer to a pointer that should be set to the start of the * extra field with the specified tag * @param size A pointer to an uint16_t that should be set to the size */ -extern void of_zip_archive_entry_find_extra_field(OFDataArray *extraField, +extern void of_zip_archive_entry_extra_field_find(OFDataArray *extraField, uint16_t tag, uint8_t **data, uint16_t *size); #ifdef __cplusplus } #endif Index: src/OFZIPArchiveEntry.m ================================================================== --- src/OFZIPArchiveEntry.m +++ src/OFZIPArchiveEntry.m @@ -31,11 +31,11 @@ extern uint32_t of_zip_archive_read_field32(uint8_t**, uint16_t*); extern uint64_t of_zip_archive_read_field64(uint8_t**, uint16_t*); void -of_zip_archive_entry_find_extra_field(OFDataArray *extraField, uint16_t tag, +of_zip_archive_entry_extra_field_find(OFDataArray *extraField, uint16_t tag, uint8_t **data, uint16_t *size) { uint8_t *bytes; size_t i, count; @@ -80,12 +80,12 @@ uint16_t ZIP64Size; if ([file readLittleEndianInt32] != 0x02014B50) @throw [OFInvalidFormatException exception]; - _madeWithVersion = [file readLittleEndianInt16]; - _minVersion = [file readLittleEndianInt16]; + _versionMadeBy = [file readLittleEndianInt16]; + _minVersionNeeded = [file readLittleEndianInt16]; _generalPurposeBitFlag = [file readLittleEndianInt16]; _compressionMethod = [file readLittleEndianInt16]; _lastModifiedFileTime = [file readLittleEndianInt16]; _lastModifiedFileDate = [file readLittleEndianInt16]; _CRC32 = [file readLittleEndianInt32]; @@ -94,11 +94,11 @@ fileNameLength = [file readLittleEndianInt16]; extraFieldLength = [file readLittleEndianInt16]; fileCommentLength = [file readLittleEndianInt16]; _startDiskNumber = [file readLittleEndianInt16]; _internalAttributes = [file readLittleEndianInt16]; - _externalAttributes = [file readLittleEndianInt32]; + _versionSpecificAttributes = [file readLittleEndianInt32]; _localFileHeaderOffset = [file readLittleEndianInt32]; encoding = (_generalPurposeBitFlag & (1 << 11) ? OF_STRING_ENCODING_UTF_8 : OF_STRING_ENCODING_CODEPAGE_437); @@ -108,12 +108,12 @@ _extraField = [[file readDataArrayWithCount: extraFieldLength] retain]; _fileComment = [[file readStringWithLength: fileCommentLength encoding: encoding] copy]; - of_zip_archive_entry_find_extra_field(_extraField, 0x0001, - &ZIP64, &ZIP64Size); + of_zip_archive_entry_extra_field_find(_extraField, + OF_ZIP_ARCHIVE_ENTRY_EXTRA_FIELD_ZIP64, &ZIP64, &ZIP64Size); if (ZIP64 != NULL) { if (_uncompressedSize == 0xFFFFFFFF) _uncompressedSize = of_zip_archive_read_field64( &ZIP64, &ZIP64Size); @@ -157,10 +157,25 @@ - (OFString*)fileComment { OF_GETTER(_fileComment, true) } + +- (uint16_t)versionMadeBy +{ + return _versionMadeBy; +} + +- (uint16_t)minVersionNeeded +{ + return _minVersionNeeded; +} + +- (uint16_t)compressionMethod +{ + return _compressionMethod; +} - (uint64_t)compressedSize { return _compressedSize; } @@ -196,10 +211,15 @@ - (uint32_t)CRC32 { return _CRC32; } + +- (uint32_t)versionSpecificAttributes +{ + return _versionSpecificAttributes; +} - (OFDataArray*)extraField { return [[_extraField copy] autorelease]; } @@ -228,30 +248,15 @@ objc_autoreleasePoolPop(pool); return [ret autorelease]; } -- (uint16_t)OF_madeWithVersion -{ - return _madeWithVersion; -} - -- (uint16_t)OF_minVersion -{ - return _minVersion; -} - - (uint16_t)OF_generalPurposeBitFlag { return _generalPurposeBitFlag; } -- (uint16_t)OF_compressionMethod -{ - return _compressionMethod; -} - - (uint16_t)OF_lastModifiedFileTime { return _lastModifiedFileTime; } @@ -258,30 +263,10 @@ - (uint16_t)OF_lastModifiedFileDate { return _lastModifiedFileDate; } -- (OFDataArray*)OF_extraFieldNoCopy -{ - OF_GETTER(_extraField, true) -} - -- (uint16_t)OF_startDiskNumber -{ - return _startDiskNumber; -} - -- (uint16_t)OF_internalAttributes -{ - return _internalAttributes; -} - -- (uint32_t)OF_externalAttributes -{ - return _externalAttributes; -} - - (uint64_t)OF_localFileHeaderOffset { return _localFileHeaderOffset; } @end