You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

143 lines
3.4 KiB

//
// CWThreadSafeData.m
// Pantomime
//
// Created by Andreas Buff on 04.09.17.
// Copyright © 2017 pEp Security S.A. All rights reserved.
//
#import "CWThreadSafeData.h"
NS_ASSUME_NONNULL_BEGIN
@interface CWThreadSafeData ()
@property (nonatomic) dispatch_queue_t queue;
@property (atomic) __block NSMutableData *data;
@end
@implementation CWThreadSafeData
- (instancetype _Nullable)init
{
self = [super init];
if (self) {
self.queue = dispatch_queue_create("CWThreadSaveData", DISPATCH_QUEUE_SERIAL);
self.data = [NSMutableData new];
}
return self;
}
- (instancetype _Nullable)initWithData:(NSData *)data
{
self = [self init];
if (self) {
self.data = [NSMutableData dataWithData:data];
}
return self;
}
- (instancetype _Nullable)initWithBytes:(char*)bytes length:(NSUInteger)length
{
self = [self init];
if (self) {
self.data = [NSMutableData dataWithBytes:bytes length:length];
}
return self;
}
- (NSUInteger)length
{
__block NSUInteger result = 0;
__weak typeof(self) weakSelf = self;
dispatch_sync(self.queue, ^{
typeof(self) strongSelf = weakSelf;
result = strongSelf.data.length;
});
return result;
}
- (void)reset
{
__weak typeof(self) weakSelf = self;
dispatch_sync(self.queue, ^{
typeof(self) strongSelf = weakSelf;
strongSelf.data = [NSMutableData new];
});
}
- (void)truncateLeadingBytes:(NSUInteger)numBytes
{
__weak typeof(self) weakSelf = self;
dispatch_sync(self.queue, ^{
typeof(self) strongSelf = weakSelf;
NSUInteger theCount = strongSelf.data.length - numBytes;
char *theBytesTarget = [[strongSelf data] mutableBytes];
memmove(theBytesTarget, theBytesTarget + numBytes, theCount);
strongSelf.data.length -= numBytes;
});
}
- (const char *)bytes
{
__block const char *theBytes = nil;
__weak typeof(self) weakSelf = self;
dispatch_sync(self.queue, ^{
typeof(self) strongSelf = weakSelf;
theBytes = strongSelf.data.bytes;
});
return theBytes;
}
- (NSData *)subdataToIndex:(NSUInteger)index
{
__block NSData *subData = nil;
__weak typeof(self) weakSelf = self;
dispatch_sync(self.queue, ^{
typeof(self) strongSelf = weakSelf;
subData = [strongSelf.data subdataWithRange: NSMakeRange(0, index)];
});
return subData;
}
- (void)appendData:(NSData *)data
{
__weak typeof(self) weakSelf = self;
dispatch_sync(self.queue, ^{
typeof(self) strongSelf = weakSelf;
[strongSelf.data appendData:data];
});
}
- (NSData * _Nullable)dropFirstLine
{
__block NSData *firstLine = nil;
__weak typeof(self) weakSelf = self;
dispatch_sync(self.queue, ^{
typeof(self) strongSelf = weakSelf;
char *bytes, *end;
NSUInteger i, count;
bytes = (char *)[strongSelf.data mutableBytes];
end = bytes + 1;
count = strongSelf.data.length;
for (i = 1; i < count; i++) {
if (*end == '\n' && *(end - 1) == '\r') {
NSData *aData = [NSData dataWithBytes: bytes length: (i - 1)];
memmove(bytes,end + 1,count - i - 1);
[strongSelf.data setLength: count - i - 1];
firstLine = aData;
return;
}
end++;
}
});
return firstLine;
}
@end
NS_ASSUME_NONNULL_END