Index: src/OFHTTPClient.m ================================================================== --- src/OFHTTPClient.m +++ src/OFHTTPClient.m @@ -518,12 +518,12 @@ forRequest: _request]; return false; } } -- (bool)socket: (OFTCPSocket *)socket - didWriteRequest: (const void *)request +- (size_t)socket: (OFTCPSocket *)socket + didWriteRequest: (const void **)request length: (size_t)length context: (id)context exception: (id)exception { OFData *body; @@ -548,30 +548,30 @@ length: [body count] * [body itemSize] target: self selector: @selector(socket:didWriteBody:length: context:exception:) context: nil]; - return false; + return 0; } else return [self socket: socket didWriteBody: NULL length: 0 context: nil exception: nil]; } -- (bool)socket: (OFTCPSocket *)socket - didWriteBody: (const void *)body - length: (size_t)length - context: (id)context - exception: (id)exception +- (size_t)socket: (OFTCPSocket *)socket + didWriteBody: (const void **)body + length: (size_t)length + context: (id)context + exception: (id)exception { [socket asyncReadLineWithTarget: self selector: @selector(socket:didReadLine:context: exception:) context: nil]; - return false; + return 0; } - (void)handleSocket: (OFTCPSocket *)socket { /* Index: src/OFRunLoop.m ================================================================== --- src/OFRunLoop.m +++ src/OFRunLoop.m @@ -285,11 +285,13 @@ if (_writtenLength != _length && exception == nil) return true; # ifdef OF_HAVE_BLOCKS if (_block != NULL) { - if (!_block(object, _buffer, _writtenLength, exception)) + _length = _block(object, &_buffer, _writtenLength, exception); + + if (_length == 0) return false; _writtenLength = 0; return true; } else { @@ -296,12 +298,14 @@ # endif bool (*func)(id, SEL, OFStream *, const void *, size_t, id, id) = (bool (*)(id, SEL, OFStream *, const void *, size_t, id, id))[_target methodForSelector: _selector]; - if (!func(_target, _selector, object, _buffer, _writtenLength, - _context, exception)) + _length = func(_target, _selector, object, &_buffer, + _writtenLength, _context, exception); + + if (_length == 0) return false; _writtenLength = 0; return true; # ifdef OF_HAVE_BLOCKS Index: src/OFStream.h ================================================================== --- src/OFStream.h +++ src/OFStream.h @@ -66,18 +66,22 @@ /*! * @brief A block which is called when data was written to the stream. * * @param stream The stream to which data was written * @param buffer The buffer which was written to the stream - * @param length The length of the data that bas been written + * @param bytesWritten The number of bytes which have been written. This + * matches the length specified on the asynchronous write + * if no exception was encountered. * @param exception An exception which occurred while reading or `nil` on * success - * @return A bool whether another write with the same buffer, length and - * callback block should be performed + * @return The length to repeat the write with or 0 if it should not repeat. + * The buffer may be changed, so that every time a new buffer and length + * can be specified while the callback stays the same. */ -typedef bool (^of_stream_async_write_block_t)(OFStream *stream, - const void *buffer, size_t length, id _Nullable exception); +typedef size_t (^of_stream_async_write_block_t)(OFStream *stream, + const void *_Nonnull *_Nonnull buffer, size_t bytesWritten, + id _Nullable exception); #endif /*! * @class OFStream OFStream.h ObjFW/OFStream.h * @@ -805,16 +809,18 @@ * * @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 - * data has been received. If the method returns true, the same - * buffer and length will be written again and same method will - * be called again. + * data has been written. The method should return the length for + * the next write with the same callback or 0 if it should not + * repeat. The buffer may be changed, so that every time a new + * buffer and length can be specified while the callback stays + * the same. * @param selector The selector to call on the target. The signature must be - * `bool (OFStream *stream, const void *buffer, size_t length, - * id context, id exception)`. + * `bool (OFStream *stream, const void *buffer, + * size_t bytesWritten, id context, id exception)`. */ - (void)asyncWriteBuffer: (const void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector @@ -828,11 +834,15 @@ * valid file descriptor 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 + * @param block The block to call when the data has been written. It should + * return the length for the next write with the same callback or + * 0 if it should not repeat. The buffer may be changed, so that + * every time a new buffer and length can be specified while the + * callback stays the same. */ - (void)asyncWriteBuffer: (const void *)buffer length: (size_t)length block: (of_stream_async_write_block_t)block; # endif