/core/externals/google-toolbox-for-mac/Foundation/GTMNSScanner+JSON.m
Objective C | 83 lines | 61 code | 3 blank | 19 comment | 19 complexity | be57e7afee3730cc332c19e8aa04a7d9 MD5 | raw file
1// 2// GTMNSScanner+JSON.m 3// 4// Copyright 2009 Google Inc. 5// 6// Licensed under the Apache License, Version 2.0 (the "License"); you may not 7// use this file except in compliance with the License. You may obtain a copy 8// of the License at 9// 10// http://www.apache.org/licenses/LICENSE-2.0 11// 12// Unless required by applicable law or agreed to in writing, software 13// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15// License for the specific language governing permissions and limitations under 16// the License. 17// 18 19#import "GTMDefines.h" 20#import "GTMNSScanner+JSON.h" 21 22@implementation NSScanner (GTMNSScannerJSONAdditions) 23 24- (BOOL)gtm_scanJSONString:(NSString **)jsonString 25 startChar:(unichar)startChar 26 endChar:(unichar)endChar { 27 BOOL isGood = NO; 28 NSRange jsonRange = { NSNotFound, 0 }; 29 NSString *scanString = [self string]; 30 NSUInteger startLocation = [self scanLocation]; 31 NSUInteger length = [scanString length]; 32 NSUInteger blockOpen = 0; 33 NSCharacterSet *charsToSkip = [self charactersToBeSkipped]; 34 BOOL inQuoteMode = NO; 35 NSUInteger i; 36 for (i = startLocation; i < length; ++i) { 37 unichar jsonChar = [scanString characterAtIndex:i]; 38 if (jsonChar == startChar && !inQuoteMode) { 39 if (blockOpen == 0) { 40 jsonRange.location = i; 41 } 42 blockOpen += 1; 43 } else if (blockOpen == 0) { 44 // If we haven't opened our block skip over any characters in 45 // charsToSkip. 46 if (![charsToSkip characterIsMember:jsonChar]) { 47 break; 48 } 49 } else if (jsonChar == endChar && !inQuoteMode) { 50 blockOpen -= 1; 51 if (blockOpen == 0) { 52 i += 1; // Move onto next character 53 jsonRange.length = i - jsonRange.location; 54 break; 55 } 56 } else { 57 if (jsonChar == '"') { 58 inQuoteMode = !inQuoteMode; 59 } else if (inQuoteMode && jsonChar == '\\') { 60 // Skip the escaped character if it isn't the last one 61 if (i < length - 1) ++i; 62 } 63 } 64 } 65 [self setScanLocation:i]; 66 if (blockOpen == 0 && jsonRange.location != NSNotFound) { 67 isGood = YES; 68 if (jsonString) { 69 *jsonString = [scanString substringWithRange:jsonRange]; 70 } 71 } 72 return isGood; 73} 74 75- (BOOL)gtm_scanJSONObjectString:(NSString **)jsonString { 76 return [self gtm_scanJSONString:jsonString startChar:'{' endChar:'}']; 77} 78 79- (BOOL)gtm_scanJSONArrayString:(NSString**)jsonString { 80 return [self gtm_scanJSONString:jsonString startChar:'[' endChar:']']; 81} 82 83@end