@@ -44,67 +44,116 @@ typedef enum {
44
44
45
45
46
46
/* *
47
- @brief Delegate for interacting directly with the stream parser
48
-
49
- You will most likely find it much more convenient to implement the
50
- SBJsonStreamParserAdapterDelegate protocol instead.
47
+ @brief SBJsonStreamParserDelegate protocol adapter
48
+
49
+ @see SBJsonStreamParser
51
50
*/
52
51
@protocol SBJsonStreamParserDelegate
53
52
54
- // / Called when object start is found
55
- - (void )parserFoundObjectStart : (SBJsonStreamParser*)parser ;
56
-
57
- // / Called when object key is found
58
- - (void )parser : (SBJsonStreamParser*)parser foundObjectKey : (NSString *)key ;
59
-
60
- // / Called when object end is found
61
- - (void )parserFoundObjectEnd : (SBJsonStreamParser*)parser ;
62
-
63
- // / Called when array start is found
64
- - (void )parserFoundArrayStart : (SBJsonStreamParser*)parser ;
65
-
66
- // / Called when array end is found
67
- - (void )parserFoundArrayEnd : (SBJsonStreamParser*)parser ;
68
-
69
- // / Called when a boolean value is found
70
- - (void )parser : (SBJsonStreamParser*)parser foundBoolean : (BOOL )x ;
71
-
72
- // / Called when a null value is found
73
- - (void )parserFoundNull : (SBJsonStreamParser*)parser ;
74
-
75
- // / Called when a number is found
76
- - (void )parser : (SBJsonStreamParser*)parser foundNumber : (NSNumber *)num ;
53
+ /* *
54
+ @brief Called if a JSON array is found
55
+
56
+ This method is called if a JSON array is found.
57
+
58
+ */
59
+ - (void )parser : (SBJsonStreamParser*)parser foundArray : (NSArray *)array ;
77
60
78
- // / Called when a string is found
79
- - (void )parser : (SBJsonStreamParser*)parser foundString : (NSString *)string ;
61
+ /* *
62
+ @brief Called when a JSON object is found
63
+
64
+ This method is called if a JSON object is found.
65
+ */
66
+ - (void )parser : (SBJsonStreamParser*)parser foundObject : (NSDictionary *)dict ;
80
67
81
68
@end
82
69
70
+ typedef enum {
71
+ SBJsonStreamParserNone,
72
+ SBJsonStreamParserArray,
73
+ SBJsonStreamParserObject,
74
+ } SBJsonStreamParserType;
83
75
84
76
/* *
85
77
@brief Parse a stream of JSON data.
86
78
87
79
Using this class directly you can reduce the apparent latency for each
88
80
download/parse cycle of documents over a slow connection. You can start
89
81
parsing *and return chunks of the parsed document* before the entire
90
- document is downloaded.
82
+ document is downloaded. Using this class is also useful to parse huge
83
+ documents on disk bit by bit so you don't have to keep them all in memory.
84
+
85
+ The default behaviour is that the delegate only receives one call from
86
+ either the -parser:foundArray: or -parser:foundObject: method when the
87
+ document is fully parsed. However, if your inputs contains multiple JSON
88
+ documents and you set the parser's -supportMultipleDocuments property to YES
89
+ you will get one call for each full method.
90
+
91
+ @code
92
+ SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease];
93
+ parser.delegate = self;
94
+ parser.supportMultipleDocuments = YES;
95
+
96
+ // Note that this input contains multiple top-level JSON documents
97
+ NSData *json = [@"[]{}[]{}" dataWithEncoding:NSUTF8StringEncoding];
98
+ [parser parse:data];
99
+ @endcode
91
100
92
- Using this class is also useful to parse huge documents on disk
93
- bit by bit so you don't have to keep them all in memory.
101
+ In the above example @p self will have the following sequence of methods called on it:
94
102
95
- @see SBJsonStreamParserAdapter for more information.
103
+ @li -parser:foundArray:
104
+ @li -parser:foundObject:
105
+ @li -parser:foundArray:
106
+ @li -parser:foundObject:
96
107
108
+ Often you won't have control over the input you're parsing, so can't make use of
109
+ this feature. But, all is not lost: this class will let you get the same effect by
110
+ allowing you to skip one or more of the outer enclosing objects. Thus, the next
111
+ example results in the same sequence of -parser:foundArray: / -parser:foundObject:
112
+ being called on your delegate.
113
+
114
+ @code
115
+ SBJsonStreamParser *parser = [[[SBJsonStreamParser alloc] init] autorelease];
116
+ parser.delegate = self;
117
+ parser.levelsToSkip = 1;
118
+
119
+ // Note that this input contains A SINGLE top-level document
120
+ NSData *json = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];
121
+ [parser parse:data];
122
+ @endcode
123
+
124
+ @see SBJsonStreamParserDelegate
97
125
@see @ref objc2json
98
126
99
127
*/
100
128
@interface SBJsonStreamParser : NSObject {
101
129
@private
102
130
SBJsonTokeniser *tokeniser;
131
+
132
+ NSUInteger depth;
133
+ NSMutableArray *array;
134
+ NSMutableDictionary *dict;
135
+ NSMutableArray *keyStack;
136
+ NSMutableArray *stack;
137
+
138
+ SBJsonStreamParserType currentType;
103
139
}
104
140
105
141
@property (nonatomic , assign ) SBJsonStreamParserState *state; // Private
106
142
@property (nonatomic , readonly , retain ) NSMutableArray *stateStack; // Private
107
143
144
+
145
+ /* *
146
+ @brief How many levels to skip
147
+
148
+ This is useful for parsing huge JSON documents, or documents coming in over a very slow link.
149
+
150
+ If you set this to N it will skip the outer N levels and call the -parser:foundArray:
151
+ or -parser:foundObject: methods for each of the inner objects, as appropriate.
152
+
153
+ @see The StreamParserIntegrationTest.m file for examples
154
+ */
155
+ @property NSUInteger levelsToSkip;
156
+
108
157
/* *
109
158
@brief Expect multiple documents separated by whitespace
110
159
@@ -126,7 +175,7 @@ typedef enum {
126
175
into valid tokens.
127
176
128
177
@note
129
- Usually this should be an instance of SBJsonStreamParserAdapter , but you can
178
+ Usually this should be an instance of SBJsonStreamParser , but you can
130
179
substitute your own implementation of the SBJsonStreamParserDelegate protocol if you need to.
131
180
*/
132
181
@property (assign ) id <SBJsonStreamParserDelegate> delegate;
0 commit comments