From 2763eb75f25f28f2b407d1c2c89ac9cddf7f7392 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Mon, 26 Apr 2021 13:12:45 +0200 Subject: [PATCH 01/36] IOS-2794 Use less bytes in truncateLeadingBytes --- pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m index 4993c8c..946a3fa 100644 --- a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m +++ b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m @@ -72,7 +72,9 @@ NS_ASSUME_NONNULL_BEGIN typeof(self) strongSelf = weakSelf; NSUInteger length = strongSelf.data.length - numBytes; NSData *newData = [strongSelf.data subdataWithRange:NSMakeRange(numBytes, length)]; - strongSelf.data = [NSMutableData dataWithData: newData]; + [strongSelf.data replaceBytesInRange:NSMakeRange(0, length) + withBytes:newData.bytes]; + strongSelf.data.length -= numBytes; }); } From 5d20e18bf87e16cfdbabb24546caa06446c80ee8 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Mon, 26 Apr 2021 13:14:12 +0200 Subject: [PATCH 02/36] IOS-2794 Return own bytes, avoid copy --- pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m index 946a3fa..3af3744 100644 --- a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m +++ b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m @@ -84,8 +84,7 @@ NS_ASSUME_NONNULL_BEGIN __weak typeof(self) weakSelf = self; dispatch_sync(self.queue, ^{ typeof(self) strongSelf = weakSelf; - NSData *copy = strongSelf.data.copy; - copyOfBytes = copy.bytes; + copyOfBytes = strongSelf.data.bytes; }); return copyOfBytes; From 514cc4b23c4239b0b3207612c063ee9f88d167c6 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Mon, 26 Apr 2021 14:29:47 +0200 Subject: [PATCH 03/36] IOS-2794 Make that a mutable array componentsSeparatedByCString --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 2 +- pantomime-lib/Framework/Pantomime/CWPart.m | 2 +- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index b8db21e..1b369c7 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -255,7 +255,7 @@ @result An instance of NSArray holding all components. The array is empty if the separator was not found in the receiver. */ -- (NSArray *) componentsSeparatedByCString: (const char *) theCString; +- (NSMutableArray *) componentsSeparatedByCString: (const char *) theCString; /*! @method asciiString diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index b2f670e..101330a 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -553,7 +553,7 @@ static int currentPartVersion = 2; dataToSend = [dataToSend wrapWithLimit: limit]; } - NSArray *allLines = [dataToSend componentsSeparatedByCString: "\n"]; + NSMutableArray *allLines = [dataToSend componentsSeparatedByCString: "\n"]; NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { if (i == count - 1 && [[allLines objectAtIndex: i] length] == 0) { diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index b7dbba7..2c3398b 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -734,7 +734,7 @@ static const char *hexDigit = "0123456789ABCDEF"; return NSOrderedDescending; } -- (NSArray *) componentsSeparatedByCString: (const char *) theCString +- (NSMutableArray *) componentsSeparatedByCString: (const char *) theCString { NSMutableArray *aMutableArray; NSRange r1, r2; From 224c0b961b901fa8b449572cbf5a785bf1f6d87f Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Mon, 26 Apr 2021 15:04:04 +0200 Subject: [PATCH 04/36] IOS-2794 Check last line outside the loop --- pantomime-lib/Framework/Pantomime/CWPart.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index 101330a..e7124c7 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -554,11 +554,11 @@ static int currentPartVersion = 2; } NSMutableArray *allLines = [dataToSend componentsSeparatedByCString: "\n"]; + if ([[allLines lastObject] length] == 0) { + [allLines removeLastObject]; + } NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { - if (i == count - 1 && [[allLines objectAtIndex: i] length] == 0) { - break; - } [dataValue appendData: [allLines objectAtIndex: i]]; [dataValue appendBytes: LF length: 1]; } From 18671718ca761c4139ba0674323311c588cb9ae7 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Mon, 26 Apr 2021 15:07:44 +0200 Subject: [PATCH 05/36] IOS-2794 Lower memory consumption --- pantomime-lib/Framework/Pantomime/CWPart.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index e7124c7..4ece572 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -559,8 +559,9 @@ static int currentPartVersion = 2; } NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { - [dataValue appendData: [allLines objectAtIndex: i]]; + [dataValue appendData: [allLines objectAtIndex: 0]]; [dataValue appendBytes: LF length: 1]; + [allLines removeObjectAtIndex:0]; } return dataValue; } From 16764a988f6b2b7f6ce915924615977afd9355e3 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Mon, 26 Apr 2021 15:35:35 +0200 Subject: [PATCH 06/36] IOS-2794 Set to nil early --- pantomime-lib/Framework/Pantomime/CWSMTP.m | 1 + 1 file changed, 1 insertion(+) diff --git a/pantomime-lib/Framework/Pantomime/CWSMTP.m b/pantomime-lib/Framework/Pantomime/CWSMTP.m index e557dc6..1b0baad 100644 --- a/pantomime-lib/Framework/Pantomime/CWSMTP.m +++ b/pantomime-lib/Framework/Pantomime/CWSMTP.m @@ -679,6 +679,7 @@ static inline CWInternetAddress *next_recipient(NSMutableArray *theRecipients, B // We first replace all occurences of LF by CRLF in the Message's data. // aMutableData = [[NSMutableData dataWithData: _data] replaceLFWithCRLF]; + _data = nil; // // According to RFC 2821 section 4.5.2, we must check for the character From 88aa4005a1928b6d879974f26c91ac6f568e4e34 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Mon, 26 Apr 2021 15:50:29 +0200 Subject: [PATCH 07/36] IOS-2794 Tighten truncateLeadingBytes --- pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m index 3af3744..fa1a636 100644 --- a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m +++ b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m @@ -70,10 +70,9 @@ NS_ASSUME_NONNULL_BEGIN __weak typeof(self) weakSelf = self; dispatch_sync(self.queue, ^{ typeof(self) strongSelf = weakSelf; - NSUInteger length = strongSelf.data.length - numBytes; - NSData *newData = [strongSelf.data subdataWithRange:NSMakeRange(numBytes, length)]; - [strongSelf.data replaceBytesInRange:NSMakeRange(0, length) - withBytes:newData.bytes]; + NSUInteger theCount = strongSelf.data.length - numBytes; + char *theBytesTarget = [[strongSelf data] mutableBytes]; + memmove(theBytesTarget, theBytesTarget + numBytes, theCount); strongSelf.data.length -= numBytes; }); } From a9a1cd7572bbb7230fe2ed6c0d4aa45853073211 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Tue, 27 Apr 2021 12:42:15 +0200 Subject: [PATCH 08/36] IOS-2794 Delete object after SMTP complete --- pantomime-lib/Framework/Pantomime/CWSMTP.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pantomime-lib/Framework/Pantomime/CWSMTP.m b/pantomime-lib/Framework/Pantomime/CWSMTP.m index 1b0baad..82a8a46 100644 --- a/pantomime-lib/Framework/Pantomime/CWSMTP.m +++ b/pantomime-lib/Framework/Pantomime/CWSMTP.m @@ -725,6 +725,10 @@ static inline CWInternetAddress *next_recipient(NSMutableArray *theRecipients, B // The data we wrote in the previous call was sucessfully written. // We inform the delegate that the mail was sucessfully sent. PERFORM_SELECTOR_2(_delegate, @selector(messageSent:), PantomimeMessageSent, _message, @"Message"); + + // Delete memory consuming objects + _data = nil; + _message = nil; } else { From 349806bd1774b43691e28fe7e183be5de233c635 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 10:27:58 +0200 Subject: [PATCH 09/36] IOS-2794 Less memory in _removeInvalidHeadersFromMessage --- pantomime-lib/Framework/Pantomime/CWIMAPFolder.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m index 2cceb2e..607e2ab 100644 --- a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m +++ b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m @@ -770,7 +770,7 @@ - (NSData *) _removeInvalidHeadersFromMessage: (NSData *) theMessage { NSMutableData *aMutableData; - NSArray *allLines; + NSMutableArray *allLines; NSUInteger i, count; // We allocate our mutable data object @@ -785,7 +785,10 @@ NSData *aLine; // We get a line... - aLine = [allLines objectAtIndex: i]; + aLine = [allLines firstObject]; + + // Remove the line immediately to easy memory consumption + [allLines removeObjectAtIndex:0]; // We skip dumb headers if ([aLine hasCPrefix: "From "]) From 90f72c639fed6089e81fad2615921867ea6659fd Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 12:54:31 +0200 Subject: [PATCH 10/36] IOS-2794 Use firstObject uniformly --- pantomime-lib/Framework/Pantomime/CWPart.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index 4ece572..b0a6578 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -559,7 +559,7 @@ static int currentPartVersion = 2; } NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { - [dataValue appendData: [allLines objectAtIndex: 0]]; + [dataValue appendData: [allLines firstObject]]; [dataValue appendBytes: LF length: 1]; [allLines removeObjectAtIndex:0]; } From e68cbbe15b535215aec301d7e96acc30c930f186 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:06:28 +0200 Subject: [PATCH 11/36] IOS-2794 Test subdata copying --- .../Pantomime/NSData+ExtensionsTest.m | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m b/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m index fa61490..eef7326 100644 --- a/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m +++ b/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m @@ -205,6 +205,24 @@ static NSString *text = @"My test\t Text containing 1234567890ß? stuff"; [self assertDataByTrimmingWhiteSpacesFromTestStringUsedInFormat:testFormat]; } +#pragma mark - subdata + +/// This test proves that `[NSData subdataWithRange]` _copies_ the bytes it covers to a new buffer. +- (void)testSubdataWithRange +{ + NSString *testStr = @"<35BE75EB.74E6.4CB7.9C5D.432B241FDF90@pretty.Easy.privacy>"; + NSData *testData = [testStr dataUsingEncoding:NSASCIIStringEncoding]; + + NSRange r1 = NSMakeRange(0, 5); + NSData *subDataFromStart = [testData subdataWithRange:r1]; + XCTAssertNotEqual([testData bytes], [subDataFromStart bytes]); + + NSInteger offset = 5; + NSRange r2 = NSMakeRange(offset, 5); + NSData *subDataFromOffset = [testData subdataWithRange:r2]; + XCTAssertNotEqual([testData bytes] + offset, [subDataFromOffset bytes]); +} + #pragma mark helper - (void)assertDataByTrimmingWhiteSpacesFromTestStringUsedInFormat:(NSString *)format From 9fe5f23be38e2891d7a059b539650bafd877741b Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:16:29 +0200 Subject: [PATCH 12/36] IOS-2794 Revert "Use firstObject uniformly" This reverts commit 90f72c639fed6089e81fad2615921867ea6659fd. --- pantomime-lib/Framework/Pantomime/CWPart.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index b0a6578..4ece572 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -559,7 +559,7 @@ static int currentPartVersion = 2; } NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { - [dataValue appendData: [allLines firstObject]]; + [dataValue appendData: [allLines objectAtIndex: 0]]; [dataValue appendBytes: LF length: 1]; [allLines removeObjectAtIndex:0]; } From b222a98ea037619e861bfe89767cab582bc173dd Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:16:50 +0200 Subject: [PATCH 13/36] IOS-2794 Revert "Less memory in _removeInvalidHeadersFromMessage" This reverts commit 349806bd1774b43691e28fe7e183be5de233c635. --- pantomime-lib/Framework/Pantomime/CWIMAPFolder.m | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m index 607e2ab..2cceb2e 100644 --- a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m +++ b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m @@ -770,7 +770,7 @@ - (NSData *) _removeInvalidHeadersFromMessage: (NSData *) theMessage { NSMutableData *aMutableData; - NSMutableArray *allLines; + NSArray *allLines; NSUInteger i, count; // We allocate our mutable data object @@ -785,10 +785,7 @@ NSData *aLine; // We get a line... - aLine = [allLines firstObject]; - - // Remove the line immediately to easy memory consumption - [allLines removeObjectAtIndex:0]; + aLine = [allLines objectAtIndex: i]; // We skip dumb headers if ([aLine hasCPrefix: "From "]) From 574f415350b9086f642dcfb83b1019ed978fec6d Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:17:01 +0200 Subject: [PATCH 14/36] IOS-2794 Revert "Lower memory consumption" This reverts commit 18671718ca761c4139ba0674323311c588cb9ae7. --- pantomime-lib/Framework/Pantomime/CWPart.m | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index 4ece572..e7124c7 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -559,9 +559,8 @@ static int currentPartVersion = 2; } NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { - [dataValue appendData: [allLines objectAtIndex: 0]]; + [dataValue appendData: [allLines objectAtIndex: i]]; [dataValue appendBytes: LF length: 1]; - [allLines removeObjectAtIndex:0]; } return dataValue; } From 8113bd859b7a64cf47a057cacbb9c990b2080c2d Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:19:17 +0200 Subject: [PATCH 15/36] IOS-2794 Revert "Check last line outside the loop" This reverts commit 224c0b961b901fa8b449572cbf5a785bf1f6d87f. --- pantomime-lib/Framework/Pantomime/CWPart.m | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index e7124c7..101330a 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -554,11 +554,11 @@ static int currentPartVersion = 2; } NSMutableArray *allLines = [dataToSend componentsSeparatedByCString: "\n"]; - if ([[allLines lastObject] length] == 0) { - [allLines removeLastObject]; - } NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { + if (i == count - 1 && [[allLines objectAtIndex: i] length] == 0) { + break; + } [dataValue appendData: [allLines objectAtIndex: i]]; [dataValue appendBytes: LF length: 1]; } From 6f90df8cf7b7fb8d1ce6a4f7bb79c530e095017e Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:19:29 +0200 Subject: [PATCH 16/36] IOS-2794 Revert "Make that a mutable array" This reverts commit 514cc4b23c4239b0b3207612c063ee9f88d167c6. --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 2 +- pantomime-lib/Framework/Pantomime/CWPart.m | 2 +- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index 1b369c7..b8db21e 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -255,7 +255,7 @@ @result An instance of NSArray holding all components. The array is empty if the separator was not found in the receiver. */ -- (NSMutableArray *) componentsSeparatedByCString: (const char *) theCString; +- (NSArray *) componentsSeparatedByCString: (const char *) theCString; /*! @method asciiString diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index 101330a..b2f670e 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -553,7 +553,7 @@ static int currentPartVersion = 2; dataToSend = [dataToSend wrapWithLimit: limit]; } - NSMutableArray *allLines = [dataToSend componentsSeparatedByCString: "\n"]; + NSArray *allLines = [dataToSend componentsSeparatedByCString: "\n"]; NSUInteger count = [allLines count]; for (int i = 0; i < count; i++) { if (i == count - 1 && [[allLines objectAtIndex: i] length] == 0) { diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 2c3398b..b7dbba7 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -734,7 +734,7 @@ static const char *hexDigit = "0123456789ABCDEF"; return NSOrderedDescending; } -- (NSMutableArray *) componentsSeparatedByCString: (const char *) theCString +- (NSArray *) componentsSeparatedByCString: (const char *) theCString { NSMutableArray *aMutableArray; NSRange r1, r2; From 39275525216c778f33011b6837a04d91edfa8454 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:27:49 +0200 Subject: [PATCH 17/36] IOS-2794 Wrong approach --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 3 +++ pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index b8db21e..853b3a9 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -158,6 +158,9 @@ */ - (NSData *) subdataToIndex: (NSUInteger) theIndex; +/// Like `subDataWithRange`, but doesn't copy bytes, and instead points to the bytes from the original. +- (NSData *)subdataUncopiedWithRange:(NSRange)range; + /** @discussion Simple method to trim the leading and trailing whitespaces (characters with no visible representation). Cahracters currently taken into accout are: diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index b7dbba7..00faad7 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -437,6 +437,13 @@ static const char *hexDigit = "0123456789ABCDEF"; return [self subdataWithRange: NSMakeRange(0, theIndex)]; } +- (NSData *)subdataUncopiedWithRange:(NSRange)range +{ + const char *theBytes = [self bytes]; + const char *newBytes = theBytes + range.location; + return [NSData dataWithBytesNoCopy:(void *) newBytes length:range.length]; +} + - (NSData *)dataByTrimmingWhiteSpaces { const char *bytes = [self bytes]; From dce3db0fee31f06a2c2ecea2f3ef4a6fe2f1c371 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:37:28 +0200 Subject: [PATCH 18/36] IOS-2794 This could work --- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 00faad7..6f100cf 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -441,7 +441,14 @@ static const char *hexDigit = "0123456789ABCDEF"; { const char *theBytes = [self bytes]; const char *newBytes = theBytes + range.location; - return [NSData dataWithBytesNoCopy:(void *) newBytes length:range.length]; + + // Let the NSData point to existing bytes without copy, + // and don't do anything to free them + return [[NSData alloc] initWithBytesNoCopy:(void *) newBytes + length:range.length + deallocator:^(void * _Nonnull bytes, NSUInteger length) { + // ignore, don't free anything + }]; } - (NSData *)dataByTrimmingWhiteSpaces From 27c43d4a9b07c3f56d703dea8c8aa199ae7e9a4b Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 14:41:28 +0200 Subject: [PATCH 19/36] IOS-2794 Dare to use subdataUncopiedWithRange componentsSeparatedByCString --- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 6f100cf..7ebdd26 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -764,7 +764,7 @@ static const char *hexDigit = "0123456789ABCDEF"; while (r2.length) { - [aMutableArray addObject: [self subdataWithRange: NSMakeRange(r1.location, r2.location - r1.location)]]; + [aMutableArray addObject: [self subdataUncopiedWithRange: NSMakeRange(r1.location, r2.location - r1.location)]]; r1.location = r2.location + r2.length; r1.length = len - r1.location; From cc019e5deefde4713beffae8bcbbca7c6456f67a Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 15:08:55 +0200 Subject: [PATCH 20/36] IOS-2794 Revert "Dare to use subdataUncopiedWithRange" This reverts commit 27c43d4a9b07c3f56d703dea8c8aa199ae7e9a4b. --- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 7ebdd26..6f100cf 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -764,7 +764,7 @@ static const char *hexDigit = "0123456789ABCDEF"; while (r2.length) { - [aMutableArray addObject: [self subdataUncopiedWithRange: NSMakeRange(r1.location, r2.location - r1.location)]]; + [aMutableArray addObject: [self subdataWithRange: NSMakeRange(r1.location, r2.location - r1.location)]]; r1.location = r2.location + r2.length; r1.length = len - r1.location; From 977caf2398de8db6e4764efa5eb63d638f808ebc Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 15:30:09 +0200 Subject: [PATCH 21/36] IOS-2794 Optimized componentsSeparatedByCString --- .../PantomimeFramework/NSData+Extensions.h | 4 ++++ .../Framework/Pantomime/NSData+Extensions.m | 23 +++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index 853b3a9..f1b363c 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -260,6 +260,10 @@ */ - (NSArray *) componentsSeparatedByCString: (const char *) theCString; +/// Like `componentsSeparatedByCString`, but calls the given block with each result and the current count. +- (void)componentsSeparatedByCString:(const char *)theCString + block:(void (^)(NSData *, NSUInteger))block; + /*! @method asciiString @discussion This method turns the receiver into a NSString object. diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 6f100cf..1570366 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -776,6 +776,29 @@ static const char *hexDigit = "0123456789ABCDEF"; return AUTORELEASE(aMutableArray); } +- (void)componentsSeparatedByCString:(const char *)theCString + block:(void (^)(NSData *, NSUInteger))block +{ + NSUInteger len = [self length]; + NSRange r1 = NSMakeRange(0,len); + + NSRange r2 = [self rangeOfCString: theCString + options: 0 + range: r1]; + + + NSUInteger count = 0; + while (r2.length) { + block([self subdataWithRange: NSMakeRange(r1.location, r2.location - r1.location)], count); + count++; + r1.location = r2.location + r2.length; + r1.length = len - r1.location; + + r2 = [self rangeOfCString: theCString options: 0 range: r1]; + } + + block([self subdataWithRange: NSMakeRange(r1.location, len - r1.location)], count); +} // // From fee9757a1a9b748788386febf29f19a978c7ee13 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 16:53:12 +0200 Subject: [PATCH 22/36] IOS-2794 _removeInvalidHeadersFromMessage --- .../Framework/Pantomime/CWIMAPFolder.m | 38 ++++++------------- 1 file changed, 12 insertions(+), 26 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m index 2cceb2e..4e2cc9c 100644 --- a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m +++ b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m @@ -769,35 +769,21 @@ // - (NSData *) _removeInvalidHeadersFromMessage: (NSData *) theMessage { - NSMutableData *aMutableData; - NSArray *allLines; - NSUInteger i, count; - - // We allocate our mutable data object - aMutableData = [[NSMutableData alloc] initWithCapacity: [theMessage length]]; + // We allocate our mutable data object + NSMutableData *aMutableData = [[NSMutableData alloc] initWithCapacity: [theMessage length]]; - // We now replace all \n by \r\n - allLines = [theMessage componentsSeparatedByCString: "\n"]; - count = [allLines count]; - - for (i = 0; i < count; i++) - { - NSData *aLine; - - // We get a line... - aLine = [allLines objectAtIndex: i]; - - // We skip dumb headers - if ([aLine hasCPrefix: "From "]) - { - continue; - } + // We now replace all \n by \r\n + [theMessage componentsSeparatedByCString:"\n" block:^(NSData *aLine, NSUInteger count) { + // We skip dumb headers + if ([aLine hasCPrefix: "From "]) { + return; + } - [aMutableData appendData: aLine]; - [aMutableData appendCString: "\r\n"]; - } + [aMutableData appendData: aLine]; + [aMutableData appendCString: "\r\n"]; + }]; - return AUTORELEASE(aMutableData); + return AUTORELEASE(aMutableData); } @end From e981d0f7de1760534b761ef73735399eac66d7be Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 17:04:01 +0200 Subject: [PATCH 23/36] IOS-2794 Block parameter for if it's the last componentsSeparatedByCString --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 3 ++- pantomime-lib/Framework/Pantomime/CWIMAPFolder.m | 4 +++- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 8 +++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index f1b363c..faa05c3 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -261,8 +261,9 @@ - (NSArray *) componentsSeparatedByCString: (const char *) theCString; /// Like `componentsSeparatedByCString`, but calls the given block with each result and the current count. +/// The block will be invoked for every component, together with its count and a boolean denoting if it's the last element. - (void)componentsSeparatedByCString:(const char *)theCString - block:(void (^)(NSData *, NSUInteger))block; + block:(void (^)(NSData *, NSUInteger, BOOL isLast))block; /*! @method asciiString diff --git a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m index 4e2cc9c..6c7ed28 100644 --- a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m +++ b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m @@ -773,7 +773,9 @@ NSMutableData *aMutableData = [[NSMutableData alloc] initWithCapacity: [theMessage length]]; // We now replace all \n by \r\n - [theMessage componentsSeparatedByCString:"\n" block:^(NSData *aLine, NSUInteger count) { + [theMessage componentsSeparatedByCString:"\n" block:^(NSData *aLine, + NSUInteger count, + BOOL isLast) { // We skip dumb headers if ([aLine hasCPrefix: "From "]) { return; diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 1570366..70748e6 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -777,7 +777,7 @@ static const char *hexDigit = "0123456789ABCDEF"; } - (void)componentsSeparatedByCString:(const char *)theCString - block:(void (^)(NSData *, NSUInteger))block + block:(void (^)(NSData *, NSUInteger, BOOL isLast))block { NSUInteger len = [self length]; NSRange r1 = NSMakeRange(0,len); @@ -789,7 +789,9 @@ static const char *hexDigit = "0123456789ABCDEF"; NSUInteger count = 0; while (r2.length) { - block([self subdataWithRange: NSMakeRange(r1.location, r2.location - r1.location)], count); + block([self subdataWithRange: NSMakeRange(r1.location, r2.location - r1.location)], + count, + NO); count++; r1.location = r2.location + r2.length; r1.length = len - r1.location; @@ -797,7 +799,7 @@ static const char *hexDigit = "0123456789ABCDEF"; r2 = [self rangeOfCString: theCString options: 0 range: r1]; } - block([self subdataWithRange: NSMakeRange(r1.location, len - r1.location)], count); + block([self subdataWithRange: NSMakeRange(r1.location, len - r1.location)], count, YES); } // From 47610e12533cf89eeb0bc8c754074ed0f25e4203 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 17:04:30 +0200 Subject: [PATCH 24/36] IOS-2794 Formatting --- pantomime-lib/Framework/Pantomime/CWIMAPFolder.m | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m index 6c7ed28..2c46760 100644 --- a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m +++ b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m @@ -773,9 +773,10 @@ NSMutableData *aMutableData = [[NSMutableData alloc] initWithCapacity: [theMessage length]]; // We now replace all \n by \r\n - [theMessage componentsSeparatedByCString:"\n" block:^(NSData *aLine, - NSUInteger count, - BOOL isLast) { + [theMessage componentsSeparatedByCString:"\n" + block:^(NSData *aLine, + NSUInteger count, + BOOL isLast) { // We skip dumb headers if ([aLine hasCPrefix: "From "]) { return; From ea3bf3ff758ca998cf18eef19ce8208477fbeccf Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 17:07:13 +0200 Subject: [PATCH 25/36] IOS-2794 [CWPart dataValue] --- pantomime-lib/Framework/Pantomime/CWPart.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index b2f670e..4840730 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -553,15 +553,15 @@ static int currentPartVersion = 2; dataToSend = [dataToSend wrapWithLimit: limit]; } - NSArray *allLines = [dataToSend componentsSeparatedByCString: "\n"]; - NSUInteger count = [allLines count]; - for (int i = 0; i < count; i++) { - if (i == count - 1 && [[allLines objectAtIndex: i] length] == 0) { - break; + [dataToSend componentsSeparatedByCString:"\n" + block:^(NSData *aLine, NSUInteger count, BOOL isLast) { + if (isLast && [aLine length] == 0) { + return; } - [dataValue appendData: [allLines objectAtIndex: i]]; - [dataValue appendBytes: LF length: 1]; - } + [dataValue appendData:aLine]; + [dataValue appendBytes:LF length:1]; + }]; + return dataValue; } From c1ec8e723617bb6e54f8ca033ffea4f7c4f0df5f Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 17:08:37 +0200 Subject: [PATCH 26/36] IOS-2794 Parameter names --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 2 +- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index faa05c3..4d191d5 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -263,7 +263,7 @@ /// Like `componentsSeparatedByCString`, but calls the given block with each result and the current count. /// The block will be invoked for every component, together with its count and a boolean denoting if it's the last element. - (void)componentsSeparatedByCString:(const char *)theCString - block:(void (^)(NSData *, NSUInteger, BOOL isLast))block; + block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block; /*! @method asciiString diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 70748e6..393c393 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -777,7 +777,7 @@ static const char *hexDigit = "0123456789ABCDEF"; } - (void)componentsSeparatedByCString:(const char *)theCString - block:(void (^)(NSData *, NSUInteger, BOOL isLast))block + block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block { NSUInteger len = [self length]; NSRange r1 = NSMakeRange(0,len); From bcff358b08d8f2500aa3c5452f317480b1c43ca2 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 17:10:10 +0200 Subject: [PATCH 27/36] IOS-2794 Use subdataUncopiedWithRange --- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 393c393..1640495 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -789,7 +789,7 @@ static const char *hexDigit = "0123456789ABCDEF"; NSUInteger count = 0; while (r2.length) { - block([self subdataWithRange: NSMakeRange(r1.location, r2.location - r1.location)], + block([self subdataUncopiedWithRange:NSMakeRange(r1.location, r2.location - r1.location)], count, NO); count++; From 263fd8dd3f219c4dc6cf56ae28697a5049ba1771 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 17:11:01 +0200 Subject: [PATCH 28/36] IOS-2794 Docs --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 1 + 1 file changed, 1 insertion(+) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index 4d191d5..732fd3d 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -262,6 +262,7 @@ /// Like `componentsSeparatedByCString`, but calls the given block with each result and the current count. /// The block will be invoked for every component, together with its count and a boolean denoting if it's the last element. +/// @Note: Uses `subdataUncopiedWithRange` to produce the `NSData` parts. - (void)componentsSeparatedByCString:(const char *)theCString block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block; From e3bc83d472497a70e8908881bb63b8d7969839a2 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Wed, 28 Apr 2021 17:16:44 +0200 Subject: [PATCH 29/36] IOS-2794 Docs --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index 732fd3d..decb539 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -159,6 +159,8 @@ - (NSData *) subdataToIndex: (NSUInteger) theIndex; /// Like `subDataWithRange`, but doesn't copy bytes, and instead points to the bytes from the original. +/// @note The caller has to make sure that the returned `NSData` does not exist longer than the `NSData` that owns +/// the actual bytes. - (NSData *)subdataUncopiedWithRange:(NSRange)range; /** @@ -262,7 +264,7 @@ /// Like `componentsSeparatedByCString`, but calls the given block with each result and the current count. /// The block will be invoked for every component, together with its count and a boolean denoting if it's the last element. -/// @Note: Uses `subdataUncopiedWithRange` to produce the `NSData` parts. +/// @note Uses `subdataUncopiedWithRange` to produce the `NSData` parts. - (void)componentsSeparatedByCString:(const char *)theCString block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block; From 3d003446399837c6101309742264d32f516489c4 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Thu, 29 Apr 2021 09:33:41 +0200 Subject: [PATCH 30/36] IOS-2794 Don't use subdataUncopiedWithRange --- .../PantomimeFramework/NSData+Extensions.h | 5 ----- .../Framework/Pantomime/NSData+Extensions.m | 16 +--------------- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index decb539..ad984e9 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -158,11 +158,6 @@ */ - (NSData *) subdataToIndex: (NSUInteger) theIndex; -/// Like `subDataWithRange`, but doesn't copy bytes, and instead points to the bytes from the original. -/// @note The caller has to make sure that the returned `NSData` does not exist longer than the `NSData` that owns -/// the actual bytes. -- (NSData *)subdataUncopiedWithRange:(NSRange)range; - /** @discussion Simple method to trim the leading and trailing whitespaces (characters with no visible representation). Cahracters currently taken into accout are: diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 1640495..e35f2a5 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -437,20 +437,6 @@ static const char *hexDigit = "0123456789ABCDEF"; return [self subdataWithRange: NSMakeRange(0, theIndex)]; } -- (NSData *)subdataUncopiedWithRange:(NSRange)range -{ - const char *theBytes = [self bytes]; - const char *newBytes = theBytes + range.location; - - // Let the NSData point to existing bytes without copy, - // and don't do anything to free them - return [[NSData alloc] initWithBytesNoCopy:(void *) newBytes - length:range.length - deallocator:^(void * _Nonnull bytes, NSUInteger length) { - // ignore, don't free anything - }]; -} - - (NSData *)dataByTrimmingWhiteSpaces { const char *bytes = [self bytes]; @@ -789,7 +775,7 @@ static const char *hexDigit = "0123456789ABCDEF"; NSUInteger count = 0; while (r2.length) { - block([self subdataUncopiedWithRange:NSMakeRange(r1.location, r2.location - r1.location)], + block([self subdataWithRange:NSMakeRange(r1.location, r2.location - r1.location)], count, NO); count++; From 83a6c72d2c568c92f3582f98ad9e2786371bfe15 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Thu, 29 Apr 2021 09:50:38 +0200 Subject: [PATCH 31/36] IOS-2794 Revert "Test subdata copying" This reverts commit e68cbbe15b535215aec301d7e96acc30c930f186. --- .../Pantomime/NSData+ExtensionsTest.m | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m b/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m index eef7326..fa61490 100644 --- a/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m +++ b/PantomimeFramework/PantomimeFrameworkTests/Pantomime/NSData+ExtensionsTest.m @@ -205,24 +205,6 @@ static NSString *text = @"My test\t Text containing 1234567890ß? stuff"; [self assertDataByTrimmingWhiteSpacesFromTestStringUsedInFormat:testFormat]; } -#pragma mark - subdata - -/// This test proves that `[NSData subdataWithRange]` _copies_ the bytes it covers to a new buffer. -- (void)testSubdataWithRange -{ - NSString *testStr = @"<35BE75EB.74E6.4CB7.9C5D.432B241FDF90@pretty.Easy.privacy>"; - NSData *testData = [testStr dataUsingEncoding:NSASCIIStringEncoding]; - - NSRange r1 = NSMakeRange(0, 5); - NSData *subDataFromStart = [testData subdataWithRange:r1]; - XCTAssertNotEqual([testData bytes], [subDataFromStart bytes]); - - NSInteger offset = 5; - NSRange r2 = NSMakeRange(offset, 5); - NSData *subDataFromOffset = [testData subdataWithRange:r2]; - XCTAssertNotEqual([testData bytes] + offset, [subDataFromOffset bytes]); -} - #pragma mark helper - (void)assertDataByTrimmingWhiteSpacesFromTestStringUsedInFormat:(NSString *)format From eef0b3b9debf5af2e20f599e45170c3f46a459d9 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Thu, 29 Apr 2021 11:48:17 +0200 Subject: [PATCH 32/36] IOS-2794 Docs --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index ad984e9..0ba06bf 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -257,9 +257,8 @@ */ - (NSArray *) componentsSeparatedByCString: (const char *) theCString; -/// Like `componentsSeparatedByCString`, but calls the given block with each result and the current count. -/// The block will be invoked for every component, together with its count and a boolean denoting if it's the last element. -/// @note Uses `subdataUncopiedWithRange` to produce the `NSData` parts. +/// Like `componentsSeparatedByCString`, but calls the given block with each component, the current count, . +/// and a boolean denoting if it's the last element. - (void)componentsSeparatedByCString:(const char *)theCString block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block; From 98a3c5386fb5e93630f0ee9661b3fa3629b3fef4 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Thu, 29 Apr 2021 12:12:55 +0200 Subject: [PATCH 33/36] IOS-2794 Format --- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index e35f2a5..1d02c0a 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -768,9 +768,9 @@ static const char *hexDigit = "0123456789ABCDEF"; NSUInteger len = [self length]; NSRange r1 = NSMakeRange(0,len); - NSRange r2 = [self rangeOfCString: theCString - options: 0 - range: r1]; + NSRange r2 = [self rangeOfCString:theCString + options:0 + range:r1]; NSUInteger count = 0; @@ -785,7 +785,7 @@ static const char *hexDigit = "0123456789ABCDEF"; r2 = [self rangeOfCString: theCString options: 0 range: r1]; } - block([self subdataWithRange: NSMakeRange(r1.location, len - r1.location)], count, YES); + block([self subdataWithRange:NSMakeRange(r1.location, len - r1.location)], count, YES); } // From 49784361b238283f3af3663e4b69696ad0c49c2e Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Thu, 29 Apr 2021 12:14:46 +0200 Subject: [PATCH 34/36] IOS-2794 Comments --- pantomime-lib/Framework/Pantomime/CWSMTP.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWSMTP.m b/pantomime-lib/Framework/Pantomime/CWSMTP.m index 82a8a46..451de0f 100644 --- a/pantomime-lib/Framework/Pantomime/CWSMTP.m +++ b/pantomime-lib/Framework/Pantomime/CWSMTP.m @@ -679,7 +679,7 @@ static inline CWInternetAddress *next_recipient(NSMutableArray *theRecipients, B // We first replace all occurences of LF by CRLF in the Message's data. // aMutableData = [[NSMutableData dataWithData: _data] replaceLFWithCRLF]; - _data = nil; + _data = nil; // save memory by deleting as soon as possible // // According to RFC 2821 section 4.5.2, we must check for the character @@ -726,7 +726,7 @@ static inline CWInternetAddress *next_recipient(NSMutableArray *theRecipients, B // We inform the delegate that the mail was sucessfully sent. PERFORM_SELECTOR_2(_delegate, @selector(messageSent:), PantomimeMessageSent, _message, @"Message"); - // Delete memory consuming objects + // Delete memory consuming objects as soon as possible _data = nil; _message = nil; } From 7b295604f2fb5c0c6e2a1629f7810afa8ae7bd15 Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Fri, 30 Apr 2021 11:00:58 +0200 Subject: [PATCH 35/36] IOS-2794 Rename enumerateComponentsSeperatedByString --- PantomimeFramework/PantomimeFramework/NSData+Extensions.h | 4 ++-- pantomime-lib/Framework/Pantomime/CWIMAPFolder.m | 8 ++++---- pantomime-lib/Framework/Pantomime/CWPart.m | 4 ++-- pantomime-lib/Framework/Pantomime/NSData+Extensions.m | 4 ++-- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index 0ba06bf..eacf455 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -259,8 +259,8 @@ /// Like `componentsSeparatedByCString`, but calls the given block with each component, the current count, . /// and a boolean denoting if it's the last element. -- (void)componentsSeparatedByCString:(const char *)theCString - block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block; +- (void)enumerateComponentsSeperatedByString:(const char *)theCString + block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block; /*! @method asciiString diff --git a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m index 2c46760..4172ba2 100644 --- a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m +++ b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m @@ -773,10 +773,10 @@ NSMutableData *aMutableData = [[NSMutableData alloc] initWithCapacity: [theMessage length]]; // We now replace all \n by \r\n - [theMessage componentsSeparatedByCString:"\n" - block:^(NSData *aLine, - NSUInteger count, - BOOL isLast) { + [theMessage enumerateComponentsSeperatedByString:"\n" + block:^(NSData *aLine, + NSUInteger count, + BOOL isLast) { // We skip dumb headers if ([aLine hasCPrefix: "From "]) { return; diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index 4840730..9c0bf02 100644 --- a/pantomime-lib/Framework/Pantomime/CWPart.m +++ b/pantomime-lib/Framework/Pantomime/CWPart.m @@ -553,8 +553,8 @@ static int currentPartVersion = 2; dataToSend = [dataToSend wrapWithLimit: limit]; } - [dataToSend componentsSeparatedByCString:"\n" - block:^(NSData *aLine, NSUInteger count, BOOL isLast) { + [dataToSend enumerateComponentsSeperatedByString:"\n" + block:^(NSData *aLine, NSUInteger count, BOOL isLast) { if (isLast && [aLine length] == 0) { return; } diff --git a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index 1d02c0a..dae8ae5 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -762,8 +762,8 @@ static const char *hexDigit = "0123456789ABCDEF"; return AUTORELEASE(aMutableArray); } -- (void)componentsSeparatedByCString:(const char *)theCString - block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block +- (void)enumerateComponentsSeperatedByString:(const char *)theCString + block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block { NSUInteger len = [self length]; NSRange r1 = NSMakeRange(0,len); From 3a5ba594b838a4efd2e09e9f1161e5f3723f8dee Mon Sep 17 00:00:00 2001 From: Dirk Zimmermann Date: Fri, 30 Apr 2021 11:05:11 +0200 Subject: [PATCH 36/36] IOS-2794 Rename copyOfBytes -> bytes --- pantomime-lib/Framework/Pantomime/CWService+Protected.m | 2 +- .../Framework/Pantomime/Utils/CWThreadSafeData.h | 4 ++-- .../Framework/Pantomime/Utils/CWThreadSafeData.m | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pantomime-lib/Framework/Pantomime/CWService+Protected.m b/pantomime-lib/Framework/Pantomime/CWService+Protected.m index 99a81dc..61d4321 100644 --- a/pantomime-lib/Framework/Pantomime/CWService+Protected.m +++ b/pantomime-lib/Framework/Pantomime/CWService+Protected.m @@ -60,7 +60,7 @@ unsigned char *bytes; NSInteger count, len; - bytes = (unsigned char*)[_wbuf copyOfBytes]; + bytes = (unsigned char*)[_wbuf bytes]; len = [_wbuf length]; #ifdef MACOSX diff --git a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.h b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.h index 7d8d6ca..69dbfa3 100644 --- a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.h +++ b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.h @@ -49,9 +49,9 @@ NS_ASSUME_NONNULL_BEGIN - (void)truncateLeadingBytes:(NSUInteger)numBytes; /** - @return a copy of the inner byte array. + @return a pointer to the inner byte array. */ -- (const char*)copyOfBytes; +- (const char *)bytes; /** @discussion This method is used to obtain the subdata to index diff --git a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m index fa1a636..5f58f06 100644 --- a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m +++ b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m @@ -77,16 +77,16 @@ NS_ASSUME_NONNULL_BEGIN }); } -- (const char*)copyOfBytes +- (const char *)bytes { - __block const char* copyOfBytes = nil; + __block const char *theBytes = nil; __weak typeof(self) weakSelf = self; dispatch_sync(self.queue, ^{ typeof(self) strongSelf = weakSelf; - copyOfBytes = strongSelf.data.bytes; + theBytes = strongSelf.data.bytes; }); - return copyOfBytes; + return theBytes; } - (NSData *)subdataToIndex:(NSUInteger)index