123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359 |
- /*
- Copyright (c) 2010, Stig Brautaset.
- All rights reserved.
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
- Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- Neither the name of the the author nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #import "SBJsonStreamParserState.h"
- #import "SBJsonStreamParser.h"
- #define SINGLETON \
- + (id)sharedInstance { \
- static id state = nil; \
- if (!state) { \
- @synchronized(self) { \
- if (!state) state = [[self alloc] init]; \
- } \
- } \
- return state; \
- }
- @implementation SBJsonStreamParserState
- + (id)sharedInstance { return nil; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- return NO;
- }
- - (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser {
- return SBJsonStreamParserWaitingForData;
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {}
- - (BOOL)needKey {
- return NO;
- }
- - (NSString*)name {
- return @"<aaiie!>";
- }
- - (BOOL)isError {
- return NO;
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateStart
- SINGLETON
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- return token == sbjson_token_array_start || token == sbjson_token_object_start;
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- SBJsonStreamParserState *state = nil;
- switch (tok) {
- case sbjson_token_array_start:
- state = [SBJsonStreamParserStateArrayStart sharedInstance];
- break;
- case sbjson_token_object_start:
- state = [SBJsonStreamParserStateObjectStart sharedInstance];
- break;
- case sbjson_token_array_end:
- case sbjson_token_object_end:
- if (parser.supportMultipleDocuments)
- state = parser.state;
- else
- state = [SBJsonStreamParserStateComplete sharedInstance];
- break;
- case sbjson_token_eof:
- return;
- default:
- state = [SBJsonStreamParserStateError sharedInstance];
- break;
- }
- parser.state = state;
- }
- - (NSString*)name { return @"before outer-most array or object"; }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateComplete
- SINGLETON
- - (NSString*)name { return @"after outer-most array or object"; }
- - (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser {
- return SBJsonStreamParserComplete;
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateError
- SINGLETON
- - (NSString*)name { return @"in error"; }
- - (SBJsonStreamParserStatus)parserShouldReturn:(SBJsonStreamParser*)parser {
- return SBJsonStreamParserError;
- }
- - (BOOL)isError {
- return YES;
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateObjectStart
- SINGLETON
- - (NSString*)name { return @"at beginning of object"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- switch (token) {
- case sbjson_token_object_end:
- case sbjson_token_string:
- return YES;
- break;
- default:
- return NO;
- break;
- }
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- parser.state = [SBJsonStreamParserStateObjectGotKey sharedInstance];
- }
- - (BOOL)needKey {
- return YES;
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateObjectGotKey
- SINGLETON
- - (NSString*)name { return @"after object key"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- return token == sbjson_token_keyval_separator;
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- parser.state = [SBJsonStreamParserStateObjectSeparator sharedInstance];
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateObjectSeparator
- SINGLETON
- - (NSString*)name { return @"as object value"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- switch (token) {
- case sbjson_token_object_start:
- case sbjson_token_array_start:
- case sbjson_token_true:
- case sbjson_token_false:
- case sbjson_token_null:
- case sbjson_token_number:
- case sbjson_token_string:
- return YES;
- break;
- default:
- return NO;
- break;
- }
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- parser.state = [SBJsonStreamParserStateObjectGotValue sharedInstance];
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateObjectGotValue
- SINGLETON
- - (NSString*)name { return @"after object value"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- switch (token) {
- case sbjson_token_object_end:
- case sbjson_token_separator:
- return YES;
- break;
- default:
- return NO;
- break;
- }
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- parser.state = [SBJsonStreamParserStateObjectNeedKey sharedInstance];
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateObjectNeedKey
- SINGLETON
- - (NSString*)name { return @"in place of object key"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- return sbjson_token_string == token;
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- parser.state = [SBJsonStreamParserStateObjectGotKey sharedInstance];
- }
- - (BOOL)needKey {
- return YES;
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateArrayStart
- SINGLETON
- - (NSString*)name { return @"at array start"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- switch (token) {
- case sbjson_token_object_end:
- case sbjson_token_keyval_separator:
- case sbjson_token_separator:
- return NO;
- break;
- default:
- return YES;
- break;
- }
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- parser.state = [SBJsonStreamParserStateArrayGotValue sharedInstance];
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateArrayGotValue
- SINGLETON
- - (NSString*)name { return @"after array value"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- return token == sbjson_token_array_end || token == sbjson_token_separator;
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- if (tok == sbjson_token_separator)
- parser.state = [SBJsonStreamParserStateArrayNeedValue sharedInstance];
- }
- @end
- #pragma mark -
- @implementation SBJsonStreamParserStateArrayNeedValue
- SINGLETON
- - (NSString*)name { return @"as array value"; }
- - (BOOL)parser:(SBJsonStreamParser*)parser shouldAcceptToken:(sbjson_token_t)token {
- switch (token) {
- case sbjson_token_array_end:
- case sbjson_token_keyval_separator:
- case sbjson_token_object_end:
- case sbjson_token_separator:
- return NO;
- break;
- default:
- return YES;
- break;
- }
- }
- - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)tok {
- parser.state = [SBJsonStreamParserStateArrayGotValue sharedInstance];
- }
- @end
|