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

  1. //
  2. // CWThreadSafeData.m
  3. // Pantomime
  4. //
  5. // Created by Andreas Buff on 04.09.17.
  6. // Copyright © 2017 pEp Security S.A. All rights reserved.
  7. //
  8. #import "CWThreadSafeData.h"
  9. NS_ASSUME_NONNULL_BEGIN
  10. @interface CWThreadSafeData ()
  11. @property (nonatomic) dispatch_queue_t queue;
  12. @property (atomic) __block NSMutableData *data;
  13. @end
  14. @implementation CWThreadSafeData
  15. - (instancetype _Nullable)init
  16. {
  17. self = [super init];
  18. if (self) {
  19. self.queue = dispatch_queue_create("CWThreadSaveData", DISPATCH_QUEUE_SERIAL);
  20. self.data = [NSMutableData new];
  21. }
  22. return self;
  23. }
  24. - (instancetype _Nullable)initWithData:(NSData *)data
  25. {
  26. self = [self init];
  27. if (self) {
  28. self.data = [NSMutableData dataWithData:data];
  29. }
  30. return self;
  31. }
  32. - (instancetype _Nullable)initWithBytes:(char*)bytes length:(NSUInteger)length
  33. {
  34. self = [self init];
  35. if (self) {
  36. self.data = [NSMutableData dataWithBytes:bytes length:length];
  37. }
  38. return self;
  39. }
  40. - (NSUInteger)length
  41. {
  42. __block NSUInteger result = 0;
  43. __weak typeof(self) weakSelf = self;
  44. dispatch_sync(self.queue, ^{
  45. typeof(self) strongSelf = weakSelf;
  46. result = strongSelf.data.length;
  47. });
  48. return result;
  49. }
  50. - (void)reset
  51. {
  52. __weak typeof(self) weakSelf = self;
  53. dispatch_sync(self.queue, ^{
  54. typeof(self) strongSelf = weakSelf;
  55. strongSelf.data = [NSMutableData new];
  56. });
  57. }
  58. - (void)truncateLeadingBytes:(NSUInteger)numBytes
  59. {
  60. __weak typeof(self) weakSelf = self;
  61. dispatch_sync(self.queue, ^{
  62. typeof(self) strongSelf = weakSelf;
  63. NSUInteger theCount = strongSelf.data.length - numBytes;
  64. char *theBytesTarget = [[strongSelf data] mutableBytes];
  65. memmove(theBytesTarget, theBytesTarget + numBytes, theCount);
  66. strongSelf.data.length -= numBytes;
  67. });
  68. }
  69. - (const char *)bytes
  70. {
  71. __block const char *theBytes = nil;
  72. __weak typeof(self) weakSelf = self;
  73. dispatch_sync(self.queue, ^{
  74. typeof(self) strongSelf = weakSelf;
  75. theBytes = strongSelf.data.bytes;
  76. });
  77. return theBytes;
  78. }
  79. - (NSData *)subdataToIndex:(NSUInteger)index
  80. {
  81. __block NSData *subData = nil;
  82. __weak typeof(self) weakSelf = self;
  83. dispatch_sync(self.queue, ^{
  84. typeof(self) strongSelf = weakSelf;
  85. subData = [strongSelf.data subdataWithRange: NSMakeRange(0, index)];
  86. });
  87. return subData;
  88. }
  89. - (void)appendData:(NSData *)data
  90. {
  91. __weak typeof(self) weakSelf = self;
  92. dispatch_sync(self.queue, ^{
  93. typeof(self) strongSelf = weakSelf;
  94. [strongSelf.data appendData:data];
  95. });
  96. }
  97. - (NSData * _Nullable)dropFirstLine
  98. {
  99. __block NSData *firstLine = nil;
  100. __weak typeof(self) weakSelf = self;
  101. dispatch_sync(self.queue, ^{
  102. typeof(self) strongSelf = weakSelf;
  103. char *bytes, *end;
  104. NSUInteger i, count;
  105. bytes = (char *)[strongSelf.data mutableBytes];
  106. end = bytes + 1;
  107. count = strongSelf.data.length;
  108. for (i = 1; i < count; i++) {
  109. if (*end == '\n' && *(end - 1) == '\r') {
  110. NSData *aData = [NSData dataWithBytes: bytes length: (i - 1)];
  111. memmove(bytes,end + 1,count - i - 1);
  112. [strongSelf.data setLength: count - i - 1];
  113. firstLine = aData;
  114. return;
  115. }
  116. end++;
  117. }
  118. });
  119. return firstLine;
  120. }
  121. @end
  122. NS_ASSUME_NONNULL_END