diff --git a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h index b8db21e..eacf455 100644 --- a/PantomimeFramework/PantomimeFramework/NSData+Extensions.h +++ b/PantomimeFramework/PantomimeFramework/NSData+Extensions.h @@ -257,6 +257,11 @@ */ - (NSArray *) componentsSeparatedByCString: (const char *) theCString; +/// Like `componentsSeparatedByCString`, but calls the given block with each component, the current count, . +/// and a boolean denoting if it's the last element. +- (void)enumerateComponentsSeperatedByString:(const char *)theCString + block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))block; + /*! @method asciiString @discussion This method turns the receiver into a NSString object. diff --git a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m index 102a5d9..c497b70 100644 --- a/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m +++ b/pantomime-lib/Framework/Pantomime/CWIMAPFolder.m @@ -769,35 +769,24 @@ // - (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 enumerateComponentsSeperatedByString:"\n" + block:^(NSData *aLine, + NSUInteger count, + BOOL isLast) { + // 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 diff --git a/pantomime-lib/Framework/Pantomime/CWPart.m b/pantomime-lib/Framework/Pantomime/CWPart.m index b2f670e..9c0bf02 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 enumerateComponentsSeperatedByString:"\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; } diff --git a/pantomime-lib/Framework/Pantomime/CWSMTP.m b/pantomime-lib/Framework/Pantomime/CWSMTP.m index 798ae99..c2129e7 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; // save memory by deleting as soon as possible // // According to RFC 2821 section 4.5.2, we must check for the character @@ -724,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 as soon as possible + _data = nil; + _message = nil; } else { 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/NSData+Extensions.m b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m index b7dbba7..dae8ae5 100644 --- a/pantomime-lib/Framework/Pantomime/NSData+Extensions.m +++ b/pantomime-lib/Framework/Pantomime/NSData+Extensions.m @@ -762,6 +762,31 @@ static const char *hexDigit = "0123456789ABCDEF"; return AUTORELEASE(aMutableArray); } +- (void)enumerateComponentsSeperatedByString:(const char *)theCString + block:(void (^)(NSData *aLine, NSUInteger count, BOOL isLast))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, + NO); + 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, YES); +} // // 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 4993c8c..5f58f06 100644 --- a/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m +++ b/pantomime-lib/Framework/Pantomime/Utils/CWThreadSafeData.m @@ -70,23 +70,23 @@ 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 = [NSMutableData dataWithData: newData]; + NSUInteger theCount = strongSelf.data.length - numBytes; + char *theBytesTarget = [[strongSelf data] mutableBytes]; + memmove(theBytesTarget, theBytesTarget + numBytes, theCount); + strongSelf.data.length -= numBytes; }); } -- (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; - NSData *copy = strongSelf.data.copy; - copyOfBytes = copy.bytes; + theBytes = strongSelf.data.bytes; }); - return copyOfBytes; + return theBytes; } - (NSData *)subdataToIndex:(NSUInteger)index