aboutsummaryrefslogtreecommitdiff
path: root/Foundation/GTMNSScanner+JSON.m
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-05-07 06:00:37 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2009-05-07 06:00:37 +0000
commitf963db9cc70dc2ffc7a1d29895b624ce33a68d75 (patch)
tree7a569b359421272a39312250a37c8553f26a4863 /Foundation/GTMNSScanner+JSON.m
parente9fe951720e98ca768e2c51d05fa257ecfd6b894 (diff)
[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
Diffstat (limited to 'Foundation/GTMNSScanner+JSON.m')
-rw-r--r--Foundation/GTMNSScanner+JSON.m83
1 files changed, 83 insertions, 0 deletions
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