Playlist Generator
1.0
|
00001 /* 00002 Copyright (c) 2010, Stig Brautaset. 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without 00006 modification, are permitted provided that the following conditions are 00007 met: 00008 00009 Redistributions of source code must retain the above copyright 00010 notice, this list of conditions and the following disclaimer. 00011 00012 Redistributions in binary form must reproduce the above copyright 00013 notice, this list of conditions and the following disclaimer in the 00014 documentation and/or other materials provided with the distribution. 00015 00016 Neither the name of the the author nor the names of its contributors 00017 may be used to endorse or promote products derived from this software 00018 without specific prior written permission. 00019 00020 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00024 HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00026 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00027 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00028 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00029 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00030 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 00033 #import "SBJsonStreamParser.h" 00034 #import "SBJsonTokeniser.h" 00035 #import "SBJsonStreamParserState.h" 00036 #import <limits.h> 00037 00038 @implementation SBJsonStreamParser 00039 00040 @synthesize supportMultipleDocuments; 00041 @synthesize error; 00042 @synthesize delegate; 00043 @synthesize maxDepth; 00044 @synthesize state; 00045 @synthesize stateStack; 00046 00047 #pragma mark Housekeeping 00048 00049 - (id)init { 00050 self = [super init]; 00051 if (self) { 00052 maxDepth = 32u; 00053 stateStack = [[NSMutableArray alloc] initWithCapacity:maxDepth]; 00054 state = [SBJsonStreamParserStateStart sharedInstance]; 00055 tokeniser = [[SBJsonTokeniser alloc] init]; 00056 } 00057 return self; 00058 } 00059 00060 - (void)dealloc { 00061 self.state = nil; 00062 } 00063 00064 #pragma mark Methods 00065 00066 - (NSString*)tokenName:(sbjson_token_t)token { 00067 switch (token) { 00068 case sbjson_token_array_start: 00069 return @"start of array"; 00070 break; 00071 00072 case sbjson_token_array_end: 00073 return @"end of array"; 00074 break; 00075 00076 case sbjson_token_number: 00077 return @"number"; 00078 break; 00079 00080 case sbjson_token_string: 00081 return @"string"; 00082 break; 00083 00084 case sbjson_token_true: 00085 case sbjson_token_false: 00086 return @"boolean"; 00087 break; 00088 00089 case sbjson_token_null: 00090 return @"null"; 00091 break; 00092 00093 case sbjson_token_keyval_separator: 00094 return @"key-value separator"; 00095 break; 00096 00097 case sbjson_token_separator: 00098 return @"value separator"; 00099 break; 00100 00101 case sbjson_token_object_start: 00102 return @"start of object"; 00103 break; 00104 00105 case sbjson_token_object_end: 00106 return @"end of object"; 00107 break; 00108 00109 case sbjson_token_eof: 00110 case sbjson_token_error: 00111 break; 00112 } 00113 NSAssert(NO, @"Should not get here"); 00114 return @"<aaiiie!>"; 00115 } 00116 00117 - (void)maxDepthError { 00118 self.error = [NSString stringWithFormat:@"Input depth exceeds max depth of %lu", maxDepth]; 00119 self.state = [SBJsonStreamParserStateError sharedInstance]; 00120 } 00121 00122 - (void)handleObjectStart { 00123 if (stateStack.count >= maxDepth) { 00124 [self maxDepthError]; 00125 return; 00126 } 00127 00128 [delegate parserFoundObjectStart:self]; 00129 [stateStack addObject:state]; 00130 self.state = [SBJsonStreamParserStateObjectStart sharedInstance]; 00131 } 00132 00133 - (void)handleObjectEnd: (sbjson_token_t) tok { 00134 self.state = [stateStack lastObject]; 00135 [stateStack removeLastObject]; 00136 [state parser:self shouldTransitionTo:tok]; 00137 [delegate parserFoundObjectEnd:self]; 00138 } 00139 00140 - (void)handleArrayStart { 00141 if (stateStack.count >= maxDepth) { 00142 [self maxDepthError]; 00143 return; 00144 } 00145 00146 [delegate parserFoundArrayStart:self]; 00147 [stateStack addObject:state]; 00148 self.state = [SBJsonStreamParserStateArrayStart sharedInstance]; 00149 } 00150 00151 - (void)handleArrayEnd: (sbjson_token_t) tok { 00152 self.state = [stateStack lastObject]; 00153 [stateStack removeLastObject]; 00154 [state parser:self shouldTransitionTo:tok]; 00155 [delegate parserFoundArrayEnd:self]; 00156 } 00157 00158 - (void) handleTokenNotExpectedHere: (sbjson_token_t) tok { 00159 NSString *tokenName = [self tokenName:tok]; 00160 NSString *stateName = [state name]; 00161 00162 self.error = [NSString stringWithFormat:@"Token '%@' not expected %@", tokenName, stateName]; 00163 self.state = [SBJsonStreamParserStateError sharedInstance]; 00164 } 00165 00166 - (SBJsonStreamParserStatus)parse:(NSData *)data_ { 00167 @autoreleasepool { 00168 [tokeniser appendData:data_]; 00169 00170 for (;;) { 00171 00172 if ([state isError]) 00173 return SBJsonStreamParserError; 00174 00175 NSObject *token; 00176 sbjson_token_t tok = [tokeniser getToken:&token]; 00177 switch (tok) { 00178 case sbjson_token_eof: 00179 return [state parserShouldReturn:self]; 00180 break; 00181 00182 case sbjson_token_error: 00183 self.state = [SBJsonStreamParserStateError sharedInstance]; 00184 self.error = tokeniser.error; 00185 return SBJsonStreamParserError; 00186 break; 00187 00188 default: 00189 00190 if (![state parser:self shouldAcceptToken:tok]) { 00191 [self handleTokenNotExpectedHere: tok]; 00192 return SBJsonStreamParserError; 00193 } 00194 00195 switch (tok) { 00196 case sbjson_token_object_start: 00197 [self handleObjectStart]; 00198 break; 00199 00200 case sbjson_token_object_end: 00201 [self handleObjectEnd: tok]; 00202 break; 00203 00204 case sbjson_token_array_start: 00205 [self handleArrayStart]; 00206 break; 00207 00208 case sbjson_token_array_end: 00209 [self handleArrayEnd: tok]; 00210 break; 00211 00212 case sbjson_token_separator: 00213 case sbjson_token_keyval_separator: 00214 [state parser:self shouldTransitionTo:tok]; 00215 break; 00216 00217 case sbjson_token_true: 00218 [delegate parser:self foundBoolean:YES]; 00219 [state parser:self shouldTransitionTo:tok]; 00220 break; 00221 00222 case sbjson_token_false: 00223 [delegate parser:self foundBoolean:NO]; 00224 [state parser:self shouldTransitionTo:tok]; 00225 break; 00226 00227 case sbjson_token_null: 00228 [delegate parserFoundNull:self]; 00229 [state parser:self shouldTransitionTo:tok]; 00230 break; 00231 00232 case sbjson_token_number: 00233 [delegate parser:self foundNumber:(NSNumber*)token]; 00234 [state parser:self shouldTransitionTo:tok]; 00235 break; 00236 00237 case sbjson_token_string: 00238 if ([state needKey]) 00239 [delegate parser:self foundObjectKey:(NSString*)token]; 00240 else 00241 [delegate parser:self foundString:(NSString*)token]; 00242 [state parser:self shouldTransitionTo:tok]; 00243 break; 00244 00245 default: 00246 break; 00247 } 00248 break; 00249 } 00250 } 00251 return SBJsonStreamParserComplete; 00252 } 00253 } 00254 00255 @end