blob: 1216698b7c2f0643598280631f2a08a25992d443 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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
|