blob: 5978c2c7beab899ddfa15151b672e514fa11d5c0 [file] [log] [blame]
#import "RingBuffer.h"
@implementation RingBuffer
- (id)initWithData:(NSMutableData*)data {
if ((self = [super init])) {
buffer = data;
}
return self;
}
- (UInt32)freeSpace {
return (UInt32)(position < tail ? tail - position : (buffer.length - position) + tail) - (tail ? 1 : 0);
}
- (BOOL)appendByte:(uint8_t)byte {
if (self.freeSpace < 1) return NO;
((uint8_t*)buffer.mutableBytes)[position++] = byte;
return YES;
}
- (SInt32)appendData:(const NSData*)value offset:(SInt32)offset length:(SInt32)length {
SInt32 totalWritten = 0;
const uint8_t *input = value.bytes;
uint8_t *data = buffer.mutableBytes;
if (position >= tail) {
totalWritten = MIN((UInt32)buffer.length - position, length);
memcpy(data + position, input + offset, totalWritten);
position += totalWritten;
if (totalWritten == length) return length;
length -= totalWritten;
offset += totalWritten;
}
UInt32 freeSpace = self.freeSpace;
if (!freeSpace) return totalWritten;
if (position == buffer.length) {
position = 0;
}
// position < tail
SInt32 written = MIN(freeSpace, length);
memcpy(data + position, input + offset, written);
position += written;
totalWritten += written;
return totalWritten;
}
- (SInt32)flushToOutputStream:(NSOutputStream*)stream {
SInt32 totalWritten = 0;
const uint8_t *data = buffer.bytes;
if (tail > position) {
SInt32 written = (SInt32)[stream write:data + tail maxLength:buffer.length - tail];
if (written <= 0) return totalWritten;
totalWritten += written;
tail += written;
if (tail == buffer.length) {
tail = 0;
}
}
if (tail < position) {
SInt32 written = (SInt32)[stream write:data + tail maxLength:position - tail];
if (written <= 0) return totalWritten;
totalWritten += written;
tail += written;
}
if (tail == position) {
tail = position = 0;
}
if (position == buffer.length && tail > 0) {
position = 0;
}
if (tail == buffer.length) {
tail = 0;
}
return totalWritten;
}
@end