From f963db9cc70dc2ffc7a1d29895b624ce33a68d75 Mon Sep 17 00:00:00 2001 From: "gtm.daemon" Date: Thu, 7 May 2009 06:00:37 +0000 Subject: [Author: dmaclach] Added some support for scanning JSON. We don't parse it, but we scan out blobs that you can then pass to a parser. DELTA=219 (219 added, 0 deleted, 0 changed) R=thomasvl --- Foundation/GTMNSScanner+JSON.m | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 Foundation/GTMNSScanner+JSON.m (limited to 'Foundation/GTMNSScanner+JSON.m') diff --git a/Foundation/GTMNSScanner+JSON.m b/Foundation/GTMNSScanner+JSON.m new file mode 100644 index 0000000..1216698 --- /dev/null +++ b/Foundation/GTMNSScanner+JSON.m @@ -0,0 +1,83 @@ +// +// GTMNSScanner+JSON.m +// +// Copyright 2009 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy +// of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. +// + +#import "GTMDefines.h" +#import "GTMNSScanner+JSON.h" + +@implementation NSScanner (GTMNSScannerJSONAdditions) + +- (BOOL)gtm_scanJSONString:(NSString **)jsonString + startChar:(unichar)startChar + endChar:(unichar)endChar { + BOOL isGood = NO; + NSRange jsonRange = { NSNotFound, 0 }; + NSString *scanString = [self string]; + NSUInteger startLocation = [self scanLocation]; + NSUInteger length = [scanString length]; + NSUInteger blockOpen = 0; + NSCharacterSet *charsToSkip = [self charactersToBeSkipped]; + BOOL inQuoteMode = NO; + NSUInteger i; + for (i = startLocation; i < length; ++i) { + unichar jsonChar = [scanString characterAtIndex:i]; + if (jsonChar == startChar && !inQuoteMode) { + if (blockOpen == 0) { + jsonRange.location = i; + } + blockOpen += 1; + } else if (blockOpen == 0) { + // If we haven't opened our block skip over any characters in + // charsToSkip. + if (![charsToSkip characterIsMember:jsonChar]) { + break; + } + } else if (jsonChar == endChar && !inQuoteMode) { + blockOpen -= 1; + if (blockOpen == 0) { + i += 1; // Move onto next character + jsonRange.length = i - jsonRange.location; + break; + } + } else { + if (jsonChar == '"') { + inQuoteMode = !inQuoteMode; + } else if (inQuoteMode && jsonChar == '\\') { + // Skip the escaped character if it isn't the last one + if (i < length - 1) ++i; + } + } + } + [self setScanLocation:i]; + if (blockOpen == 0 && jsonRange.location != NSNotFound) { + isGood = YES; + if (jsonString) { + *jsonString = [scanString substringWithRange:jsonRange]; + } + } + return isGood; +} + +- (BOOL)gtm_scanJSONObjectString:(NSString **)jsonString { + return [self gtm_scanJSONString:jsonString startChar:'{' endChar:'}']; +} + +- (BOOL)gtm_scanJSONArrayString:(NSString**)jsonString { + return [self gtm_scanJSONString:jsonString startChar:'[' endChar:']']; +} + +@end -- cgit v1.2.3