5 // Created by Jonathan Wight on 04/16/08.
6 // Copyright 2008 toxicsoftware.com. All rights reserved.
9 #import "CDataScanner.h"
11 #import "CDataScanner_Extensions.h"
13 @interface CDataScanner ()
14 @property (readwrite, retain) NSCharacterSet *doubleCharacters;
19 inline static unichar CharacterAtPointer(void *start, void *end)
22 const u_int8_t theByte = *(u_int8_t *)start;
25 // TODO -- UNICODE!!!!
27 const unichar theCharacter = theByte;
31 @implementation CDataScanner
34 @dynamic scanLocation;
36 @synthesize doubleCharacters;
38 + (id)scannerWithData:(NSData *)inData
40 CDataScanner *theScanner = [[[self alloc] init] autorelease];
41 theScanner.data = inData;
47 if ((self = [super init]) != nil)
49 self.doubleCharacters = [NSCharacterSet characterSetWithCharactersInString:@"0123456789eE-."];
57 self.doubleCharacters = NULL;
62 - (NSInteger)scanLocation
64 return current - start;
72 - (void)setData:(NSData *)inData
84 data = [inData retain];
86 start = (u_int8_t *)data.bytes;
87 end = start + data.length;
94 - (void)setScanLocation:(NSInteger)inScanLocation
96 current = start + inScanLocation;
101 return(self.scanLocation >= length);
104 - (unichar)currentCharacter
106 return(CharacterAtPointer(current, end));
109 - (unichar)scanCharacter
111 const unichar theCharacter = CharacterAtPointer(current++, end);
112 return(theCharacter);
115 - (BOOL)scanCharacter:(unichar)inCharacter
117 unichar theCharacter = CharacterAtPointer(current, end);
118 if (theCharacter == inCharacter)
127 - (BOOL)scanUTF8String:(const char *)inString intoString:(NSString **)outValue;
129 const size_t theLength = strlen(inString);
130 if (end - current < theLength)
132 if (strncmp((char *)current, inString, theLength) == 0)
134 current += theLength;
136 *outValue = [NSString stringWithUTF8String:inString];
142 - (BOOL)scanString:(NSString *)inString intoString:(NSString **)outValue
144 if (end - current < inString.length)
146 if (strncmp((char *)current, [inString UTF8String], inString.length) == 0)
148 current += inString.length;
150 *outValue = inString;
156 - (BOOL)scanCharactersFromSet:(NSCharacterSet *)inSet intoString:(NSString **)outValue
159 for (P = current; P < end && [inSet characterIsMember:*P] == YES; ++P)
169 *outValue = [[[NSString alloc] initWithBytes:current length:P - current encoding:NSUTF8StringEncoding] autorelease];
177 - (BOOL)scanUpToString:(NSString *)inString intoString:(NSString **)outValue
179 const char *theToken = [inString UTF8String];
180 const char *theResult = strnstr((char *)current, theToken, end - current);
181 if (theResult == NULL)
188 *outValue = [[[NSString alloc] initWithBytes:current length:theResult - (char *)current encoding:NSUTF8StringEncoding] autorelease];
191 current = (u_int8_t *)theResult;
196 - (BOOL)scanUpToCharactersFromSet:(NSCharacterSet *)inSet intoString:(NSString **)outValue
199 for (P = current; P < end && [inSet characterIsMember:*P] == NO; ++P)
209 *outValue = [[[NSString alloc] initWithBytes:current length:P - current encoding:NSUTF8StringEncoding] autorelease];
217 - (BOOL)scanNumber:(NSNumber **)outValue
219 // Replace all of this with a strtod call
220 NSString *theString = NULL;
221 if ([self scanCharactersFromSet:doubleCharacters intoString:&theString])
224 *outValue = [NSNumber numberWithDouble:[theString doubleValue]]; // TODO dont use doubleValue