aboutsummaryrefslogtreecommitdiffstats
path: root/Source/SPDataAdditions.m
diff options
context:
space:
mode:
Diffstat (limited to 'Source/SPDataAdditions.m')
-rw-r--r--Source/SPDataAdditions.m53
1 files changed, 53 insertions, 0 deletions
diff --git a/Source/SPDataAdditions.m b/Source/SPDataAdditions.m
index 8b2207c5..65605577 100644
--- a/Source/SPDataAdditions.m
+++ b/Source/SPDataAdditions.m
@@ -39,6 +39,11 @@
#include <stdlib.h>
#import "SPFunctions.h"
+/** Limit an NSUInteger to unsigned 32 bit max.
+ * @return Whatever is smaller: UINT32_MAX or i
+ *
+ * This is pretty much a NOOP on 32 bit platforms.
+ */
uint32_t LimitUInt32(NSUInteger i);
#pragma mark -
@@ -433,6 +438,54 @@ uint32_t LimitUInt32(NSUInteger i);
return string;
}
+- (void)enumerateLinesBreakingAt:(SPLineTerminator)lbChars withBlock:(void (^)(NSRange line,BOOL *stop))block
+{
+ if(lbChars == SPLineTerminatorAny) lbChars = SPLineTerminatorCR|SPLineTerminatorLF|SPLineTerminatorCRLF;
+
+ const uint8_t *bytes = [self bytes];
+ NSUInteger length = [self length];
+
+ NSUInteger curStart = 0;
+ SPLineTerminator terminatorFound = 0;
+ NSUInteger i;
+ for (i = 0; i < length; i++) {
+ uint8_t chr = bytes[i];
+ // if looking for cr and/or crlf we look for cr otherwise for lf
+ if(((lbChars & SPLineTerminatorCRLF) || (lbChars & SPLineTerminatorCR)) && chr == '\r') {
+ //if we are looking for CRLF check for the following LF
+ if((lbChars & SPLineTerminatorCRLF) && ((i+1) < length) && bytes[i+1] == '\n') {
+ terminatorFound = SPLineTerminatorCRLF;
+ }
+ //if we were looking for CR we've found one
+ else if((lbChars & SPLineTerminatorCR)) {
+ terminatorFound = SPLineTerminatorCR;
+ }
+ }
+ else if((lbChars & SPLineTerminatorLF) && chr == '\n') {
+ terminatorFound = SPLineTerminatorLF;
+ }
+ // no linebreak yet ?
+ if(!terminatorFound) continue;
+
+ // found one. call the block.
+ BOOL stop = NO;
+ NSRange lineRange = NSMakeRange(curStart, (i-curStart));
+ block(lineRange,&stop);
+ if(stop) return;
+
+ // reset vars for next line
+ if(terminatorFound == SPLineTerminatorCRLF) i++; //skip the \n in CRLF
+ curStart = (i+1);
+ terminatorFound = 0;
+ }
+ // there could we one unterminated line left in buffer
+ if(curStart < i) {
+ NSRange lineRange = NSMakeRange(curStart, (i-curStart));
+ BOOL iDontCare = NO;
+ block(lineRange,&iDontCare);
+ }
+}
+
@end
#pragma mark -