Index: src/OFTarArchive.h ================================================================== --- src/OFTarArchive.h +++ src/OFTarArchive.h @@ -32,54 +32,77 @@ #ifdef OF_TAR_ARCHIVE_ENTRY_M @public #endif OFStream *_stream; @protected + enum { + OF_TAR_ARCHIVE_MODE_READ, + OF_TAR_ARCHIVE_MODE_WRITE, + OF_TAR_ARCHIVE_MODE_APPEND + } _mode; OFTarArchiveEntry *_lastReturnedEntry; } /*! * @brief Creates a new OFTarArchive object with the specified stream. * * @param stream A stream from which the tar archive will be read + * @param mode The mode for the tar file. Valid modes are "r" for reading, + * "w" for creating a new file and "a" for appending to an existing + * file. * @return A new, autoreleased OFTarArchive */ -+ (instancetype)archiveWithStream: (OFStream *)stream; ++ (instancetype)archiveWithStream: (OFStream *)stream + mode: (OFString *)mode; #ifdef OF_HAVE_FILES /*! * @brief Creates a new OFTarArchive object with the specified file. * * @param path The path to the tar archive + * @param mode The mode for the tar file. Valid modes are "r" for reading, + * "w" for creating a new file and "a" for appending to an existing + * file. * @return A new, autoreleased OFTarArchive */ -+ (instancetype)archiveWithPath: (OFString *)path; ++ (instancetype)archiveWithPath: (OFString *)path + mode: (OFString *)mode; #endif /*! * @brief Initializes an already allocated OFTarArchive object with the * specified stream. * * @param stream A stream from which the tar archive will be read + * @param mode The mode for the tar file. Valid modes are "r" for reading, + * "w" for creating a new file and "a" for appending to an existing + * file. * @return An initialized OFTarArchive */ -- initWithStream: (OFStream *)stream OF_DESIGNATED_INITIALIZER; +- initWithStream: (OFStream *)stream + mode: (OFString *)mode OF_DESIGNATED_INITIALIZER; #ifdef OF_HAVE_FILES /*! * @brief Initializes an already allocated OFTarArchive object with the * specified file. * * @param path The path to the tar archive + * @param mode The mode for the tar file. Valid modes are "r" for reading, + * "w" for creating a new file and "a" for appending to an existing + * file. * @return An initialized OFTarArchive */ -- initWithPath: (OFString *)path; +- initWithPath: (OFString *)path + mode: (OFString *)mode; #endif /*! * @brief Returns the next entry from the tar archive or `nil` if all entries * have been read. + * + * This is only available in read mode. * * @warning Calling @ref nextEntry will invalidate all streams returned by the * previous entry! Reading from an invalidated stream will throw an * @ref OFReadFailedException! * Index: src/OFTarArchive.m ================================================================== --- src/OFTarArchive.m +++ src/OFTarArchive.m @@ -22,41 +22,59 @@ #import "OFStream.h" #ifdef OF_HAVE_FILES # import "OFFile.h" #endif +#import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" @implementation OFTarArchive: OFObject + (instancetype)archiveWithStream: (OFStream *)stream + mode: (OFString *)mode { - return [[[self alloc] initWithStream: stream] autorelease]; + return [[[self alloc] initWithStream: stream + mode: mode] autorelease]; } #ifdef OF_HAVE_FILES + (instancetype)archiveWithPath: (OFString *)path + mode: (OFString *)mode { - return [[[self alloc] initWithPath: path] autorelease]; + return [[[self alloc] initWithPath: path + mode: mode] autorelease]; } #endif - initWithStream: (OFStream *)stream + mode: (OFString *)mode { self = [super init]; - _stream = [stream retain]; + @try { + _stream = [stream retain]; + + if ([mode isEqual: @"r"]) + _mode = OF_TAR_ARCHIVE_MODE_READ; + else + @throw [OFInvalidArgumentException exception]; + } @catch (id e) { + [self release]; + @throw e; + } return self; } #ifdef OF_HAVE_FILES - initWithPath: (OFString *)path + mode: (OFString *)mode { OFFile *file = [[OFFile alloc] initWithPath: path - mode: @"r"]; + mode: mode]; @try { - self = [self initWithStream: file]; + self = [self initWithStream: file + mode: mode]; } @finally { [file release]; } return self; @@ -77,10 +95,13 @@ char c[512]; uint32_t u32[512 / sizeof(uint32_t)]; } buffer; bool empty = true; + if (_mode != OF_TAR_ARCHIVE_MODE_READ) + @throw [OFInvalidArgumentException exception]; + [_lastReturnedEntry of_skip]; [_lastReturnedEntry close]; [_lastReturnedEntry release]; _lastReturnedEntry = nil; Index: utils/ofzip/TarArchive.m ================================================================== --- utils/ofzip/TarArchive.m +++ utils/ofzip/TarArchive.m @@ -55,11 +55,12 @@ - initWithStream: (OF_KINDOF(OFStream *))stream { self = [super init]; @try { - _archive = [[OFTarArchive alloc] initWithStream: stream]; + _archive = [[OFTarArchive alloc] initWithStream: stream + mode: @"r"]; } @catch (id e) { [self release]; @throw e; }