Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -904,11 +904,10 @@ AC_ARG_ENABLE(files, AS_HELP_STRING([--disable-files], [disable file support])) AS_IF([test x"$enable_files" != x"no"], [ AC_DEFINE(OF_HAVE_FILES, 1, [Whether we have files]) AC_SUBST(USE_SRCS_FILES, '${SRCS_FILES}') - AC_SUBST(USE_SRCS_FILES_NOINCLUDE, '${SRCS_FILES_NOINCLUDE}') AC_SUBST(OFHASH, "ofhash") AC_SUBST(OFZIP, "ofzip") case "$host_os" in msdosdjgpp*) Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -64,11 +64,10 @@ TESTS_LIBS = @TESTS_LIBS@ TESTS_OBJCFLAGS = @TESTS_OBJCFLAGS@ UNICODE_M = @UNICODE_M@ USE_INCLUDES_ATOMIC = @USE_INCLUDES_ATOMIC@ USE_SRCS_FILES = @USE_SRCS_FILES@ -USE_SRCS_FILES_NOINCLUDE = @USE_SRCS_FILES_NOINCLUDE@ USE_SRCS_PLUGINS = @USE_SRCS_PLUGINS@ USE_SRCS_SOCKETS = @USE_SRCS_SOCKETS@ USE_SRCS_THREADS = @USE_SRCS_THREADS@ WEAK_NSFOUNDATIONVERSIONNUMBER = @WEAK_NSFOUNDATIONVERSIONNUMBER@ WRAPPER = @WRAPPER@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -114,15 +114,13 @@ SRCS_FILES = OFFile.m \ OFFileManager.m \ OFINICategory.m \ OFINIFile.m \ OFSettings.m -SRCS_FILES_NOINCLUDE = OFURLHandler_file.m SRCS_PLUGINS = OFPlugin.m SRCS_SOCKETS = OFHTTPClient.m \ OFHTTPServer.m \ - OFKernelEventObserver.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFUDPSocket.m \ resolver.m \ socket.m @@ -141,10 +139,11 @@ atomic_x86.h INCLUDES := ${SRCS:.m=.h} \ OFCollection.h \ OFCryptoHash.h \ OFJSONRepresentation.h \ + OFKernelEventObserver.h \ OFKeyValueCoding.h \ OFLocking.h \ OFMessagePackRepresentation.h \ OFSerialization.h \ OFTLSSocket.h \ @@ -171,14 +170,15 @@ OFMutableString_UTF8.m \ OFSet_hashtable.m \ OFString_UTF8.m \ ${AUTORELEASE_M} \ ${FOUNDATION_COMPAT_M} \ - ${INSTANCE_M} \ - ${USE_SRCS_FILES_NOINCLUDE} -SRCS_FILES += OFSettings_INIFile.m -SRCS_SOCKETS += ${OFKERNELEVENTOBSERVER_EPOLL_M} \ + ${INSTANCE_M} +SRCS_FILES += OFSettings_INIFile.m \ + OFURLHandler_file.m +SRCS_SOCKETS += OFKernelEventObserver.m \ + ${OFKERNELEVENTOBSERVER_EPOLL_M} \ ${OFKERNELEVENTOBSERVER_KQUEUE_M} \ ${OFKERNELEVENTOBSERVER_POLL_M} \ ${OFKERNELEVENTOBSERVER_SELECT_M} \ OFTCPSocket+SOCKS5.m Index: src/OFFile.h ================================================================== --- src/OFFile.h +++ src/OFFile.h @@ -13,10 +13,11 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFSeekableStream.h" +#import "OFKernelEventObserver.h" #ifndef OF_MORPHOS # define OF_FILE_HANDLE_IS_FD # define OF_INVALID_FILE_HANDLE (-1) typedef int of_file_handle_t; @@ -36,10 +37,13 @@ * @class OFFile OFFile.h ObjFW/OFFile.h * * @brief A class which provides methods to read and write files. */ @interface OFFile: OFSeekableStream +#ifdef OF_FILE_HANDLE_IS_FD + +#endif { of_file_handle_t _handle; bool _atEndOfStream; } Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -24,10 +24,11 @@ #import "OFHTTPClient.h" #import "OFData.h" #import "OFDictionary.h" #import "OFHTTPRequest.h" #import "OFHTTPResponse.h" +#import "OFKernelEventObserver.h" #import "OFNumber.h" #import "OFString.h" #import "OFTCPSocket.h" #import "OFURL.h" @@ -63,11 +64,11 @@ context: (id)context; - (void)start; - (void)closeAndReconnect; @end -@interface OFHTTPClientResponse: OFHTTPResponse +@interface OFHTTPClientResponse: OFHTTPResponse { OFTCPSocket *_socket; bool _hasContentLength, _chunked, _keepAlive, _atEndOfStream; size_t _toRead; } Index: src/OFHTTPServer.m ================================================================== --- src/OFHTTPServer.m +++ src/OFHTTPServer.m @@ -171,11 +171,11 @@ return [OFString stringWithUTF8StringNoCopy: cString freeWhenDone: true]; } -@interface OFHTTPServerResponse: OFHTTPResponse +@interface OFHTTPServerResponse: OFHTTPResponse { OFTCPSocket *_socket; OFHTTPServer *_server; OFHTTPRequest *_request; bool _chunked, _headersSent; Index: src/OFInflateStream.h ================================================================== --- src/OFInflateStream.h +++ src/OFInflateStream.h @@ -13,27 +13,31 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" +#import "OFKernelEventObserver.h" OF_ASSUME_NONNULL_BEGIN #define OF_INFLATE_STREAM_BUFFER_SIZE 4096 /*! * @class OFInflateStream OFInflateStream.h ObjFW/OFInflateStream.h + * + * @note This class only conforms to OFReadyForReadingObserving if the + * underlying stream does so, too. * * @brief A class that handles Deflate decompression transparently for an * underlying stream. */ -@interface OFInflateStream: OFStream +@interface OFInflateStream: OFStream { #ifdef OF_INFLATE_STREAM_M @public #endif - OFStream *_stream; + OF_KINDOF(OFStream *) _stream; uint8_t _buffer[OF_INFLATE_STREAM_BUFFER_SIZE]; uint16_t _bufferIndex, _bufferLength; uint8_t _byte; uint8_t _bitIndex, _savedBitsLength; uint16_t _savedBits; Index: src/OFKernelEventObserver.h ================================================================== --- src/OFKernelEventObserver.h +++ src/OFKernelEventObserver.h @@ -14,11 +14,13 @@ * file. */ #import "OFObject.h" -#import "socket.h" +#ifdef OF_HAVE_SOCKETS +# import "socket.h" +#endif OF_ASSUME_NONNULL_BEGIN @class OFMutableArray OF_GENERIC(ObjectType); @class OFDate; @@ -88,10 +90,11 @@ * OFKernelEventObserver. */ @property (readonly, nonatomic) int fileDescriptorForWriting; @end +#ifdef OF_HAVE_SOCKETS /*! * @class OFKernelEventObserver * OFKernelEventObserver.h ObjFW/OFKernelEventObserver.h * * @brief A class that can observe multiple kernel events (e.g. streams being @@ -203,7 +206,8 @@ * thread, but in some circumstances, it might be desirable for a thread to * manually stop the observe running in another thread. */ - (void)cancel; @end +#endif OF_ASSUME_NONNULL_END Index: src/OFProcess.h ================================================================== --- src/OFProcess.h +++ src/OFProcess.h @@ -26,10 +26,11 @@ #ifdef OF_HAVE_SYS_TYPES_H # include #endif #import "OFStream.h" +#import "OFKernelEventObserver.h" #import "OFString.h" #ifdef OF_WINDOWS # include #endif @@ -43,10 +44,13 @@ * @class OFProcess OFProcess.h ObjFW/OFProcess.h * * @brief A class for stream-like communication with a newly created process. */ @interface OFProcess: OFStream +#ifndef OF_WINDOWS + +#endif { #ifndef OF_WINDOWS pid_t _pid; int _readPipe[2], _writePipe[2]; #else Index: src/OFProcess.m ================================================================== --- src/OFProcess.m +++ src/OFProcess.m @@ -525,27 +525,21 @@ #endif return (size_t)bytesWritten; } +#ifndef OF_WINDOWS - (int)fileDescriptorForReading { -#ifndef OF_WINDOWS return _readPipe[0]; -#else - OF_UNRECOGNIZED_SELECTOR -#endif } - (int)fileDescriptorForWriting { -#ifndef OF_WINDOWS return _writePipe[1]; -#else - OF_UNRECOGNIZED_SELECTOR -#endif } +#endif - (void)closeForWriting { #ifndef OF_WINDOWS if (_writePipe[1] != -1) Index: src/OFRunLoop+Private.h ================================================================== --- src/OFRunLoop+Private.h +++ src/OFRunLoop+Private.h @@ -23,28 +23,32 @@ OF_ASSUME_NONNULL_BEGIN @interface OFRunLoop () + (void)of_setMainRunLoop: (OFRunLoop *)runLoop; #ifdef OF_HAVE_SOCKETS -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector context: (nullable id)context; -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer exactLength: (size_t)length target: (id)target selector: (SEL)selector context: (nullable id)context; -+ (void)of_addAsyncReadLineForStream: (OFStream *)stream ++ (void)of_addAsyncReadLineForStream: (OFStream *) + stream encoding: (of_string_encoding_t)encoding target: (id)target selector: (SEL)selector context: (nullable id)context; -+ (void)of_addAsyncWriteForStream: (OFStream *)stream ++ (void)of_addAsyncWriteForStream: (OFStream *) + stream buffer: (const void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector context: (nullable id)context; @@ -64,22 +68,26 @@ receiver: (of_udp_socket_address_t)receiver target: (id)target selector: (SEL)selector context: (nullable id)context; # ifdef OF_HAVE_BLOCKS -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block; -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer exactLength: (size_t)length block: (of_stream_async_read_block_t)block; -+ (void)of_addAsyncReadLineForStream: (OFStream *)stream ++ (void)of_addAsyncReadLineForStream: (OFStream *) + stream encoding: (of_string_encoding_t)encoding block: (of_stream_async_read_line_block_t)block; -+ (void)of_addAsyncWriteForStream: (OFStream *)stream ++ (void)of_addAsyncWriteForStream: (OFStream *) + stream buffer: (const void *)buffer length: (size_t)length block: (of_stream_async_write_block_t)block; + (void)of_addAsyncAcceptForTCPSocket: (OFTCPSocket *)socket block: (of_tcp_socket_async_accept_block_t) Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -527,11 +527,12 @@ code \ [queue appendObject: queueItem]; \ \ objc_autoreleasePoolPop(pool); -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector context: (id)context @@ -543,11 +544,12 @@ queueItem->_buffer = buffer; queueItem->_length = length; }) } -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer exactLength: (size_t)exactLength target: (id)target selector: (SEL)selector context: (id)context @@ -559,11 +561,12 @@ queueItem->_buffer = buffer; queueItem->_exactLength = exactLength; }) } -+ (void)of_addAsyncReadLineForStream: (OFStream *)stream ++ (void)of_addAsyncReadLineForStream: (OFStream *) + stream encoding: (of_string_encoding_t)encoding target: (id)target selector: (SEL)selector context: (id)context { @@ -573,11 +576,12 @@ queueItem->_context = [context retain]; queueItem->_encoding = encoding; }) } -+ (void)of_addAsyncWriteForStream: (OFStream *)stream ++ (void)of_addAsyncWriteForStream: (OFStream *) + stream buffer: (const void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector context: (id)context @@ -636,11 +640,12 @@ queueItem->_receiver = receiver; }) } # ifdef OF_HAVE_BLOCKS -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block { ADD_READ(OFRunLoop_ReadQueueItem, stream, { @@ -648,11 +653,12 @@ queueItem->_buffer = buffer; queueItem->_length = length; }) } -+ (void)of_addAsyncReadForStream: (OFStream *)stream ++ (void)of_addAsyncReadForStream: (OFStream *) + stream buffer: (void *)buffer exactLength: (size_t)exactLength block: (of_stream_async_read_block_t)block { ADD_READ(OFRunLoop_ExactReadQueueItem, stream, { @@ -660,21 +666,23 @@ queueItem->_buffer = buffer; queueItem->_exactLength = exactLength; }) } -+ (void)of_addAsyncReadLineForStream: (OFStream *)stream ++ (void)of_addAsyncReadLineForStream: (OFStream *) + stream encoding: (of_string_encoding_t)encoding block: (of_stream_async_read_line_block_t)block { ADD_READ(OFRunLoop_ReadLineQueueItem, stream, { queueItem->_block = [block copy]; queueItem->_encoding = encoding; }) } -+ (void)of_addAsyncWriteForStream: (OFStream *)stream ++ (void)of_addAsyncWriteForStream: (OFStream *) + stream buffer: (const void *)buffer length: (size_t)length block: (of_stream_async_write_block_t)block { ADD_WRITE(OFRunLoop_WriteQueueItem, stream, { Index: src/OFStdIOStream.h ================================================================== --- src/OFStdIOStream.h +++ src/OFStdIOStream.h @@ -13,10 +13,11 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFStream.h" +#import "OFKernelEventObserver.h" #ifdef OF_MORPHOS # define BOOL EXEC_BOOL # include # undef BOOL @@ -34,10 +35,13 @@ */ #ifdef OF_STDIO_STREAM_WIN32_CONSOLE_H OF_SUBCLASSING_RESTRICTED #endif @interface OFStdIOStream: OFStream +#if !defined(OF_WINDOWS) && !defined(OF_MORPHOS) + +#endif { #ifndef OF_MORPHOS int _fd; #else BPTR _handle; Index: src/OFStream.h ================================================================== --- src/OFStream.h +++ src/OFStream.h @@ -102,15 +102,11 @@ * the methods that do the actual work. OFStream uses those for all other * methods and does all the caching and other stuff for you. If you * override these methods without the `lowlevel` prefix, you *will* break * caching and get broken results! */ -@interface OFStream: OFObject < -#ifdef OF_HAVE_SOCKETS - OFReadyForReadingObserving, OFReadyForWritingObserving, -#endif - OFCopying> +@interface OFStream: OFObject { #if !defined(OF_SEEKABLE_STREAM_M) && !defined(OF_TCP_SOCKET_M) @private #endif char *_Nullable _readBuffer, *_Nullable _readBufferMemory; @@ -142,20 +138,10 @@ * By default, a stream is in blocking mode. * On Win32, setting this currently only works for sockets! */ @property (readonly, nonatomic, getter=isBlocking) bool blocking; -/*! - * @brief The file descriptor for the read end of the stream. - */ -@property (readonly, nonatomic) int fileDescriptorForReading; - -/*! - * @brief The file descriptor for the write end of the stream. - */ -@property (readonly, nonatomic) int fileDescriptorForWriting; - /*! * @brief Reads *at most* size bytes from the stream into a buffer. * * On network streams, this might read less than the specified number of bytes. * If you want to read exactly the specified number of bytes, use @@ -198,12 +184,12 @@ * If you want to read exactly the specified number of bytes, use * @ref asyncReadIntoBuffer:exactLength:target:selector:context:. Note that a * read can even return 0 bytes - this does not necessarily mean that the * stream ended, so you still need to check @ref atEndOfStream. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! @@ -231,12 +217,12 @@ * Unlike @ref asyncReadIntoBuffer:length:target:selector:context:, this method * does not call the method when less than the specified length has been read - * instead, it waits until it got exactly the specified length, the stream has * ended or an exception occurred. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read. * The buffer *must* be *at least* this big! * @param target The target on which the selector should be called when the @@ -265,12 +251,12 @@ * If you want to read exactly the specified number of bytes, use * @ref asyncReadIntoBuffer:exactLength:block:. Note that a read can even * return 0 bytes - this does not necessarily mean that the stream ended, so * you still need to check @ref atEndOfStream. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param buffer The buffer into which the data is read. * The buffer must not be freed before the async read completed! * @param length The length of the data that should be read at most. * The buffer *must* be *at least* this big! @@ -291,12 +277,12 @@ * Unlike @ref asyncReadIntoBuffer:length:block:, this method does not invoke * the block when less than the specified length has been read - instead, it * waits until it got exactly the specified length, the stream has ended or an * exception occurred. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param buffer The buffer into which the data is read * @param length The length of the data that should be read. * The buffer *must* be *at least* this big! * @param block The block to call when the data has been received. @@ -660,12 +646,12 @@ #ifdef OF_HAVE_SOCKETS /*! * @brief Asynchronously reads until a newline, `\0`, end of stream or an * exception occurs. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param target The target on which to call the selector when the data has * been received. If the method returns true, it will be called * again when the next line has been received. If you want the * next method in the queue to handle the next line, you need to @@ -681,12 +667,12 @@ /*! * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param encoding The encoding used by the stream * @param target The target on which to call the selector when the data has * been received. If the method returns true, it will be called * again when the next line has been received. If you want the @@ -705,12 +691,12 @@ # ifdef OF_HAVE_BLOCKS /*! * @brief Asynchronously reads until a newline, `\0`, end of stream or an * exception occurs. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param block The block to call when the data has been received. * If the block returns true, it will be called again when the next * line has been received. If you want the next block in the queue * to handle the next line, you need to return false from the @@ -720,12 +706,12 @@ /*! * @brief Asynchronously reads with the specified encoding until a newline, * `\0`, end of stream or an exception occurs. * - * @note The stream must implement @ref fileDescriptorForReading and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForReadingObserving in order + * for this to work! * * @param encoding The encoding used by the stream * @param block The block to call when the data has been received. * If the block returns true, it will be called again when the next * line has been received. If you want the next block in the queue @@ -821,12 +807,12 @@ #ifdef OF_HAVE_SOCKETS /*! * @brief Asynchronously writes a buffer into the stream. * - * @note The stream must implement @ref fileDescriptorForWriting and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForWritingObserving in order + * for this to work! * * @param buffer The buffer from which the data is written into the stream. The * buffer needs to be valid until the write request is completed! * @param length The length of the data that should be written * @param target The target on which the selector should be called when the @@ -848,12 +834,12 @@ # ifdef OF_HAVE_BLOCKS /*! * @brief Asynchronously writes a buffer into the stream. * - * @note The stream must implement @ref fileDescriptorForWriting and return a - * valid file descriptor in order for this to work! + * @note The stream must conform to @ref OFReadyForWritingObserving in order + * for this to work! * * @param buffer The buffer from which the data is written into the stream. The * buffer needs to be valid until the write request is completed! * @param length The length of the data that should be written * @param block The block to call when the data has been written. It should Index: src/OFStream.m ================================================================== --- src/OFStream.m +++ src/OFStream.m @@ -193,11 +193,14 @@ length: (size_t)length target: (id)target selector: (SEL)selector context: (id)context { - [OFRunLoop of_addAsyncReadForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer length: length target: target selector: selector context: context]; @@ -207,11 +210,14 @@ exactLength: (size_t)length target: (id)target selector: (SEL)selector context: (id)context { - [OFRunLoop of_addAsyncReadForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer exactLength: length target: target selector: selector context: context]; @@ -220,21 +226,27 @@ # ifdef OF_HAVE_BLOCKS - (void)asyncReadIntoBuffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block { - [OFRunLoop of_addAsyncReadForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer length: length block: block]; } - (void)asyncReadIntoBuffer: (void *)buffer exactLength: (size_t)length block: (of_stream_async_read_block_t)block { - [OFRunLoop of_addAsyncReadForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncReadForStream: stream buffer: buffer exactLength: length block: block]; } # endif @@ -828,11 +840,14 @@ - (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding target: (id)target selector: (SEL)selector context: (id)context { - [OFRunLoop of_addAsyncReadLineForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncReadLineForStream: stream encoding: encoding target: target selector: selector context: context]; } @@ -845,11 +860,14 @@ } - (void)asyncReadLineWithEncoding: (of_string_encoding_t)encoding block: (of_stream_async_read_line_block_t)block { - [OFRunLoop of_addAsyncReadLineForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncReadLineForStream: stream encoding: encoding block: block]; } # endif #endif @@ -1077,11 +1095,14 @@ length: (size_t)length target: (id)target selector: (SEL)selector context: (id)context { - [OFRunLoop of_addAsyncWriteForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncWriteForStream: stream buffer: buffer length: length target: target selector: selector context: context]; @@ -1090,11 +1111,14 @@ # ifdef OF_HAVE_BLOCKS - (void)asyncWriteBuffer: (const void *)buffer length: (size_t)length block: (of_stream_async_write_block_t)block { - [OFRunLoop of_addAsyncWriteForStream: self + OFStream *stream = + (OFStream *)self; + + [OFRunLoop of_addAsyncWriteForStream: stream buffer: buffer length: length block: block]; } # endif Index: src/OFStreamSocket.h ================================================================== --- src/OFStreamSocket.h +++ src/OFStreamSocket.h @@ -23,11 +23,12 @@ /*! * @class OFStreamSocket OFStreamSocket.h ObjFW/OFStreamSocket.h * * @brief A class which provides methods to create and use stream sockets. */ -@interface OFStreamSocket: OFStream +@interface OFStreamSocket: OFStream { of_socket_t _socket; bool _atEndOfStream; } Index: src/OFTarArchive.h ================================================================== --- src/OFTarArchive.h +++ src/OFTarArchive.h @@ -13,10 +13,11 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" +#import "OFKernelEventObserver.h" #import "OFTarArchiveEntry.h" OF_ASSUME_NONNULL_BEGIN @class OFString; @@ -40,12 +41,16 @@ /*! * @brief A stream for reading the current entry * * @note This is only available in read mode. + * + * @note The returned stream only conforms to @ref OFReadyForReadingObserving if + * the underlying stream does so, too. */ -@property (readonly, nonatomic) OFStream *streamForReadingCurrentEntry; +@property (readonly, nonatomic) + OFStream *streamForReadingCurrentEntry; /*! * @brief Creates a new OFTarArchive object with the specified stream. * * @param stream A stream from which the tar archive will be read. @@ -120,10 +125,13 @@ /*! * @brief Returns a stream for writing the specified entry. * * @note This is only available in write and append mode. + * + * @note The returned stream only conforms to @ref OFReadyForWritingObserving if + * the underlying stream does so, too. * * @warning Calling @ref nextEntry will invalidate all streams returned by * @ref streamForReadingCurrentEntry or * @ref streamForWritingEntry:! Reading from or writing to an * invalidated stream will throw an @ref OFReadFailedException or @@ -130,14 +138,15 @@ * @ref OFWriteFailedException! * * @param entry The entry for which a stream for writing should be returned * @return A stream for writing the specified entry */ -- (OFStream *)streamForWritingEntry: (OFTarArchiveEntry *)entry; +- (OFStream *) + streamForWritingEntry: (OFTarArchiveEntry *)entry; /*! * @brief Closes the OFTarArchive. */ - (void)close; @end OF_ASSUME_NONNULL_END Index: src/OFTarArchive.m ================================================================== --- src/OFTarArchive.m +++ src/OFTarArchive.m @@ -31,11 +31,11 @@ #import "OFNotOpenException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" #import "OFWriteFailedException.h" -@interface OFTarArchive_FileReadStream: OFStream +@interface OFTarArchive_FileReadStream: OFStream { OFTarArchiveEntry *_entry; OF_KINDOF(OFStream *) _stream; uint64_t _toRead; bool _atEndOfStream; @@ -44,14 +44,14 @@ - (instancetype)initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; - (void)of_skip; @end -@interface OFTarArchive_FileWriteStream: OFStream +@interface OFTarArchive_FileWriteStream: OFStream { OFTarArchiveEntry *_entry; - OFStream *_stream; + OF_KINDOF(OFStream *) _stream; uint64_t _toWrite; } - (instancetype)initWithStream: (OFStream *)stream entry: (OFTarArchiveEntry *)entry; @@ -201,11 +201,11 @@ entry: entry]; return entry; } -- (OFStream *)streamForReadingCurrentEntry +- (OFStream *)streamForReadingCurrentEntry { if (_mode != OF_TAR_ARCHIVE_MODE_READ) @throw [OFInvalidArgumentException exception]; if (_lastReturnedStream == nil) @@ -212,11 +212,12 @@ @throw [OFInvalidArgumentException exception]; return [[_lastReturnedStream retain] autorelease]; } -- (OFStream *)streamForWritingEntry: (OFTarArchiveEntry *)entry +- (OFStream *) + streamForWritingEntry: (OFTarArchiveEntry *)entry { void *pool; if (_mode != OF_TAR_ARCHIVE_MODE_WRITE && _mode != OF_TAR_ARCHIVE_MODE_APPEND)