/vendor/TouchJSON/Extensions/CDataScanner_Extensions.m
Objective C | 135 lines | 86 code | 20 blank | 29 comment | 24 complexity | 4b326e15fac554cebe9a2633a95e417a MD5 | raw file
1// 2// CDataScanner_Extensions.m 3// TouchCode 4// 5// Created by Jonathan Wight on 12/08/2005. 6// Copyright 2005 toxicsoftware.com. All rights reserved. 7// 8// Permission is hereby granted, free of charge, to any person 9// obtaining a copy of this software and associated documentation 10// files (the "Software"), to deal in the Software without 11// restriction, including without limitation the rights to use, 12// copy, modify, merge, publish, distribute, sublicense, and/or sell 13// copies of the Software, and to permit persons to whom the 14// Software is furnished to do so, subject to the following 15// conditions: 16// 17// The above copyright notice and this permission notice shall be 18// included in all copies or substantial portions of the Software. 19// 20// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 22// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 24// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 25// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27// OTHER DEALINGS IN THE SOFTWARE. 28// 29 30#import "CDataScanner_Extensions.h" 31 32#define LF 0x000a // Line Feed 33#define FF 0x000c // Form Feed 34#define CR 0x000d // Carriage Return 35#define NEL 0x0085 // Next Line 36#define LS 0x2028 // Line Separator 37#define PS 0x2029 // Paragraph Separator 38 39@implementation CDataScanner (CDataScanner_Extensions) 40 41- (BOOL)scanCStyleComment:(NSString **)outComment 42{ 43if ([self scanString:@"/*" intoString:NULL] == YES) 44 { 45 NSString *theComment = NULL; 46 if ([self scanUpToString:@"*/" intoString:&theComment] == NO) 47 [NSException raise:NSGenericException format:@"Started to scan a C style comment but it wasn't terminated."]; 48 49 if ([theComment rangeOfString:@"/*"].location != NSNotFound) 50 [NSException raise:NSGenericException format:@"C style comments should not be nested."]; 51 52 if ([self scanString:@"*/" intoString:NULL] == NO) 53 [NSException raise:NSGenericException format:@"C style comment did not end correctly."]; 54 55 if (outComment != NULL) 56 *outComment = theComment; 57 58 return(YES); 59 } 60else 61 { 62 return(NO); 63 } 64} 65 66- (BOOL)scanCPlusPlusStyleComment:(NSString **)outComment 67 { 68 if ([self scanString:@"//" intoString:NULL] == YES) 69 { 70 unichar theCharacters[] = { LF, FF, CR, NEL, LS, PS, }; 71 NSCharacterSet *theLineBreaksCharacterSet = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithCharacters:theCharacters length:sizeof(theCharacters) / sizeof(*theCharacters)]]; 72 73 NSString *theComment = NULL; 74 [self scanUpToCharactersFromSet:theLineBreaksCharacterSet intoString:&theComment]; 75 [self scanCharactersFromSet:theLineBreaksCharacterSet intoString:NULL]; 76 77 if (outComment != NULL) 78 *outComment = theComment; 79 80 return(YES); 81 } 82 else 83 { 84 return(NO); 85 } 86 } 87 88- (NSUInteger)lineOfScanLocation 89 { 90 NSUInteger theLine = 0; 91 for (const u_int8_t *C = start; C < current; ++C) 92 { 93 // TODO: JIW What about MS-DOS line endings you bastard! (Also other unicode line endings) 94 if (*C == '\n' || *C == '\r') 95 { 96 ++theLine; 97 } 98 } 99 return(theLine); 100 } 101 102- (NSDictionary *)userInfoForScanLocation 103 { 104 NSUInteger theLine = 0; 105 const u_int8_t *theLineStart = start; 106 for (const u_int8_t *C = start; C < current; ++C) 107 { 108 if (*C == '\n' || *C == '\r') 109 { 110 theLineStart = C - 1; 111 ++theLine; 112 } 113 } 114 115 NSUInteger theCharacter = current - theLineStart; 116 117 NSRange theStartRange = NSIntersectionRange((NSRange){ .location = MAX((NSInteger)self.scanLocation - 20, 0), .length = 20 + (NSInteger)self.scanLocation - 20 }, (NSRange){ .location = 0, .length = self.data.length }); 118 NSRange theEndRange = NSIntersectionRange((NSRange){ .location = self.scanLocation, .length = 20 }, (NSRange){ .location = 0, .length = self.data.length }); 119 120 121 NSString *theSnippet = [NSString stringWithFormat:@"%@!HERE>!%@", 122 [[[NSString alloc] initWithData:[self.data subdataWithRange:theStartRange] encoding:NSUTF8StringEncoding] autorelease], 123 [[[NSString alloc] initWithData:[self.data subdataWithRange:theEndRange] encoding:NSUTF8StringEncoding] autorelease] 124 ]; 125 126 NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys: 127 [NSNumber numberWithUnsignedInteger:theLine], @"line", 128 [NSNumber numberWithUnsignedInteger:theCharacter], @"character", 129 [NSNumber numberWithUnsignedInteger:self.scanLocation], @"location", 130 theSnippet, @"snippet", 131 NULL]; 132 return(theUserInfo); 133 } 134 135@end