@@ -1056,42 +1056,60 @@ encoding: OFStringEncodingUTF8]; } - (void)flushWriteBuffer { + size_t bytesWritten; + if (_writeBuffer == NULL) return; - [self lowlevelWriteBuffer: _writeBuffer length: _writeBufferLength]; + bytesWritten = [self lowlevelWriteBuffer: _writeBuffer + length: _writeBufferLength]; - OFFreeMemory(_writeBuffer); - _writeBuffer = NULL; - _writeBufferLength = 0; + if (bytesWritten == 0) + return; + + if (bytesWritten == _writeBufferLength) { + OFFreeMemory(_writeBuffer); + _writeBuffer = NULL; + _writeBufferLength = 0; + } + + OFEnsure(bytesWritten < _writeBufferLength); + + memmove(_writeBuffer, _writeBuffer + bytesWritten, + _writeBufferLength - bytesWritten); + _writeBufferLength -= bytesWritten; + @try { + _writeBuffer = OFResizeMemory(_writeBuffer, + _writeBufferLength, 1); + } @catch (OFOutOfMemoryException *e) { + /* We don't care, as we only made it smaller. */ + } } -- (size_t)writeBuffer: (const void *)buffer - length: (size_t)length +- (void)writeBuffer: (const void *)buffer length: (size_t)length { if (!_buffersWrites) { size_t bytesWritten = [self lowlevelWriteBuffer: buffer length: length]; - if (_canBlock && bytesWritten < length) + if (bytesWritten < length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; - - return bytesWritten; } else { + if (SIZE_MAX - _writeBufferLength < length) + @throw [OFOutOfRangeException exception]; + _writeBuffer = OFResizeMemory(_writeBuffer, _writeBufferLength + length, 1); memcpy(_writeBuffer + _writeBufferLength, buffer, length); _writeBufferLength += length; - - return length; } } #ifdef OF_HAVE_SOCKETS - (void)asyncWriteData: (OFData *)data @@ -1237,11 +1255,11 @@ { double_ = OFToBigEndianDouble(double_); [self writeBuffer: (char *)&double_ length: 8]; } -- (size_t)writeBigEndianInt16s: (const uint16_t *)buffer count: (size_t)count +- (void)writeBigEndianInt16s: (const uint16_t *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint16_t)) @throw [OFOutOfRangeException exception]; @@ -1260,15 +1278,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeBigEndianInt32s: (const uint32_t *)buffer count: (size_t)count +- (void)writeBigEndianInt32s: (const uint32_t *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint32_t)) @throw [OFOutOfRangeException exception]; @@ -1287,15 +1303,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeBigEndianInt64s: (const uint64_t *)buffer count: (size_t)count +- (void)writeBigEndianInt64s: (const uint64_t *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint64_t)) @throw [OFOutOfRangeException exception]; @@ -1314,15 +1328,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeBigEndianFloats: (const float *)buffer count: (size_t)count +- (void)writeBigEndianFloats: (const float *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(float)) @throw [OFOutOfRangeException exception]; @@ -1341,15 +1353,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeBigEndianDoubles: (const double *)buffer count: (size_t)count +- (void)writeBigEndianDoubles: (const double *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(double)) @throw [OFOutOfRangeException exception]; @@ -1368,12 +1378,10 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } - (void)writeLittleEndianInt16: (uint16_t)int16 { int16 = OFToLittleEndian16(int16); @@ -1402,11 +1410,11 @@ { double_ = OFToLittleEndianDouble(double_); [self writeBuffer: (char *)&double_ length: 8]; } -- (size_t)writeLittleEndianInt16s: (const uint16_t *)buffer count: (size_t)count +- (void)writeLittleEndianInt16s: (const uint16_t *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint16_t)) @throw [OFOutOfRangeException exception]; @@ -1425,15 +1433,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeLittleEndianInt32s: (const uint32_t *)buffer count: (size_t)count +- (void)writeLittleEndianInt32s: (const uint32_t *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint32_t)) @throw [OFOutOfRangeException exception]; @@ -1452,15 +1458,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeLittleEndianInt64s: (const uint64_t *)buffer count: (size_t)count +- (void)writeLittleEndianInt64s: (const uint64_t *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint64_t)) @throw [OFOutOfRangeException exception]; @@ -1479,15 +1483,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeLittleEndianFloats: (const float *)buffer count: (size_t)count +- (void)writeLittleEndianFloats: (const float *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(float)) @throw [OFOutOfRangeException exception]; @@ -1506,15 +1508,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeLittleEndianDoubles: (const double *)buffer count: (size_t)count +- (void)writeLittleEndianDoubles: (const double *)buffer count: (size_t)count { size_t size; if OF_UNLIKELY (count > SIZE_MAX / sizeof(double)) @throw [OFOutOfRangeException exception]; @@ -1533,15 +1533,13 @@ [self writeBuffer: tmp length: size]; } @finally { OFFreeMemory(tmp); } #endif - - return size; } -- (size_t)writeData: (OFData *)data +- (void)writeData: (OFData *)data { void *pool; size_t length; if (data == nil) @@ -1551,20 +1549,18 @@ length = data.count * data.itemSize; [self writeBuffer: data.items length: length]; objc_autoreleasePoolPop(pool); +} - return length; +- (void)writeString: (OFString *)string +{ + [self writeString: string encoding: OFStringEncodingUTF8]; } -- (size_t)writeString: (OFString *)string -{ - return [self writeString: string encoding: OFStringEncodingUTF8]; -} - -- (size_t)writeString: (OFString *)string encoding: (OFStringEncoding)encoding +- (void)writeString: (OFString *)string encoding: (OFStringEncoding)encoding { void *pool; size_t length; if (string == nil) @@ -1575,20 +1571,18 @@ [self writeBuffer: [string cStringWithEncoding: encoding] length: length]; objc_autoreleasePoolPop(pool); +} - return length; +- (void)writeLine: (OFString *)string +{ + [self writeLine: string encoding: OFStringEncodingUTF8]; } -- (size_t)writeLine: (OFString *)string -{ - return [self writeLine: string encoding: OFStringEncodingUTF8]; -} - -- (size_t)writeLine: (OFString *)string encoding: (OFStringEncoding)encoding +- (void)writeLine: (OFString *)string encoding: (OFStringEncoding)encoding { size_t stringLength = [string cStringLengthWithEncoding: encoding]; char *buffer; buffer = OFAllocMemory(stringLength + 1, 1); @@ -1600,27 +1594,22 @@ [self writeBuffer: buffer length: stringLength + 1]; } @finally { OFFreeMemory(buffer); } - - return stringLength + 1; } -- (size_t)writeFormat: (OFConstantString *)format, ... +- (void)writeFormat: (OFConstantString *)format, ... { va_list arguments; - size_t ret; va_start(arguments, format); - ret = [self writeFormat: format arguments: arguments]; + [self writeFormat: format arguments: arguments]; va_end(arguments); - - return ret; } -- (size_t)writeFormat: (OFConstantString *)format arguments: (va_list)arguments +- (void)writeFormat: (OFConstantString *)format arguments: (va_list)arguments { char *UTF8String; int length; if (format == nil) @@ -1633,12 +1622,10 @@ @try { [self writeBuffer: UTF8String length: length]; } @finally { free(UTF8String); } - - return length; } - (bool)hasDataInReadBuffer { return (_readBufferLength > 0);