@@ -1,7 +1,7 @@ /* - * Copyright (c) 2008-2022 Jonathan Schleifer + * Copyright (c) 2008-2024 Jonathan Schleifer * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in @@ -20,28 +20,53 @@ OF_ASSUME_NONNULL_BEGIN @class OFArray OF_GENERIC(ObjectType); @class OFMutableArray OF_GENERIC(ObjectType); @class OFMutableDictionary OF_GENERIC(KeyType, ObjectType); +@class OFSeekableStream; @class OFStream; +@class OFZIPArchive; + +/** + * @protocol OFZIPArchiveDelegate OFZIPArchive.h ObjFW/OFZIPArchive.h + * + * @brief A delegate for OFZIPArchive. + */ +@protocol OFZIPArchiveDelegate +@optional +/** + * @brief A callback that is called when an @ref OFZIPArchive wants to read a + * different archive part. + * + * @param archive The archive that wants to read another part + * @param partNumber The number of the part the archive wants to read + * @param lastPartNumber The number of the last archive part + * @return The stream to read the needed part, or `nil` if no such part exists + */ +- (nullable OFSeekableStream *)archive: (OFZIPArchive *)archive + wantsPartNumbered: (unsigned int)partNumber + lastPartNumber: (unsigned int)lastPartNumber; +@end /** * @class OFZIPArchive OFZIPArchive.h ObjFW/OFZIPArchive.h * * @brief A class for accessing and manipulating ZIP files. */ OF_SUBCLASSING_RESTRICTED @interface OFZIPArchive: OFObject { - OFStream *_stream; #ifdef OF_ZIP_ARCHIVE_M @public #endif + OFObject *_Nullable _delegate; + OF_KINDOF(OFStream *) _stream; int64_t _offset; -@protected uint_least8_t _mode; - uint32_t _diskNumber, _centralDirectoryDisk; + uint32_t _diskNumber, _lastDiskNumber; +@protected + uint32_t _centralDirectoryDisk; uint64_t _centralDirectoryEntriesInDisk, _centralDirectoryEntries; uint64_t _centralDirectorySize; int64_t _centralDirectoryOffset; OFString *_Nullable _archiveComment; #ifdef OF_ZIP_ARCHIVE_M @@ -51,10 +76,16 @@ OFMutableDictionary OF_GENERIC(OFString *, OFZIPArchiveEntry *) *_pathToEntryMap; OFStream *_Nullable _lastReturnedStream; } +/** + * @brief The delegate of the ZIP archive. + */ +@property OF_NULLABLE_PROPERTY (assign, nonatomic) + OFObject *delegate; + /** * @brief The archive comment. */ @property OF_NULLABLE_PROPERTY (copy, nonatomic) OFString *archiveComment; @@ -83,29 +114,29 @@ + (instancetype)archiveWithStream: (OFStream *)stream mode: (OFString *)mode; /** * @brief Creates a new OFZIPArchive object with the specified file. * - * @param URI The URI to the ZIP file + * @param IRI The IRI to the ZIP file * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return A new, autoreleased OFZIPArchive * @throw OFInvalidFormatException The format is not that of a valid ZIP archive */ -+ (instancetype)archiveWithURI: (OFURI *)URI mode: (OFString *)mode; ++ (instancetype)archiveWithIRI: (OFIRI *)IRI mode: (OFString *)mode; /** - * @brief Creates a URI for accessing a the specified file within the specified - * ZIP archive. + * @brief Creates an IRI for accessing a the specified file within the + * specified ZIP archive. * * @param path The path of the file within the archive - * @param URI The URI of the archive - * @return A URI for accessing the specified file within the specified ZIP + * @param IRI The IRI of the archive + * @return An IRI for accessing the specified file within the specified ZIP * archive */ -+ (OFURI *)URIForFilePath: (OFString *)path inArchiveWithURI: (OFURI *)URI; ++ (OFIRI *)IRIForFilePath: (OFString *)path inArchiveWithIRI: (OFIRI *)IRI; - (instancetype)init OF_UNAVAILABLE; /** * @brief Initializes an already allocated OFZIPArchive object with the @@ -124,18 +155,18 @@ /** * @brief Initializes an already allocated OFZIPArchive object with the * specified file. * - * @param URI The URI to the ZIP file + * @param IRI The IRI to the ZIP file * @param mode The mode for the ZIP file. Valid modes are "r" for reading, * "w" for creating a new file and "a" for appending to an existing * archive. * @return An initialized OFZIPArchive * @throw OFInvalidFormatException The format is not that of a valid ZIP archive */ -- (instancetype)initWithURI: (OFURI *)URI mode: (OFString *)mode; +- (instancetype)initWithIRI: (OFIRI *)IRI mode: (OFString *)mode; /** * @brief Returns a stream for reading the specified file from the archive. * * @note This method is only available in read mode. @@ -186,13 +217,15 @@ * * Bit 3 and 11 of the general purpose bit flag. * @return A stream for writing the specified entry to the archive * @throw OFNotOpenException The archive is not open * @throw OFInvalidArgumentException The archive is not in write mode * @throw OFOpenItemFailedException Opening the specified file within the - * archive failed. If @ref errNo is `EEXIST`, - * because there is already a file with the - * same name in the archive. + * archive failed. If + * @ref OFOpenItemFailedException#errNo is + * `EEXIST`, it failed because there is + * already a file with the same name in the + * archive. * @throw OFNotImplementedException The desired compression method is not * implemented */ - (OFStream *)streamForWritingEntry: (OFZIPArchiveEntry *)entry;