Skip to content

Commit

Permalink
Move multi-document support chosing to the parser delegate, so decisi…
Browse files Browse the repository at this point in the history
…on can be done in the adapter
  • Loading branch information
stig committed Nov 10, 2013
1 parent 28a7c73 commit f342770
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 23 deletions.
20 changes: 6 additions & 14 deletions src/main/objc/SBJsonStreamParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ typedef enum {
You will most likely find it much more convenient to implement the
SBJsonStreamParserAdapterDelegate protocol instead.
*/
@protocol SBJsonStreamParserDelegate
@protocol SBJsonStreamParserDelegate < NSObject >

/// Called when object start is found
- (void)parserFoundObjectStart:(SBJsonStreamParser*)parser;
Expand Down Expand Up @@ -77,6 +77,11 @@ typedef enum {
/// Called when a string is found
- (void)parser:(SBJsonStreamParser*)parser foundString:(NSString*)string;

@optional

/// Called to determine whether to allow multiple whitespace-separated documents
- (BOOL)parserShouldSupportManyDocuments:(SBJsonStreamParser*)parser;

@end


Expand Down Expand Up @@ -120,19 +125,6 @@ typedef enum {
@property (nonatomic, unsafe_unretained) SBJsonStreamParserState *state; // Private
@property (nonatomic, readonly, strong) NSMutableArray *stateStack; // Private

/**
Expect multiple documents separated by whitespace
Normally the -parse: method returns SBJsonStreamParserComplete when it's found a complete JSON document.
Attempting to parse any more data at that point is considered an error. ("Garbage after JSON".)
If you set this property to true the parser will never return SBJsonStreamParserComplete. Rather,
once an object is completed it will expect another object to immediately follow, separated
only by (optional) whitespace.
*/
@property BOOL supportMultipleDocuments;

/**
Delegate to receive messages
Expand Down
1 change: 0 additions & 1 deletion src/main/objc/SBJsonStreamParser.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ @implementation SBJsonStreamParser {
SBJsonStreamTokeniser *tokeniser;
}

@synthesize supportMultipleDocuments;
@synthesize error;
@synthesize delegate;
@synthesize maxDepth;
Expand Down
23 changes: 19 additions & 4 deletions src/main/objc/SBJsonStreamParserAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,17 @@ typedef enum {
The default behaviour is that the delegate only receives one call from
either the -parser:foundArray: or -parser:foundObject: method when the
document is fully parsed. However, if your inputs contains multiple JSON
documents and you set the parser's -supportMultipleDocuments property to YES
you will get one call for each full method.
document is fully parsed.
If your input contains multiple JSON documents you can set the adapter's
-supportManyDocuments property to YES and get called for each document:
SBJsonStreamParserAdapter *adapter = [[SBJsonStreamParserAdapter alloc] init];
adapter.delegate = self;
adapter.supportManyDocuments = YES;
SBJsonStreamParser *parser = [[SBJsonStreamParser alloc] init];
parser.delegate = adapter;
parser.supportMultipleDocuments = YES;
// Note that this input contains multiple top-level JSON documents
NSData *json = [@"[]{}[]{}" dataWithEncoding:NSUTF8StringEncoding];
Expand Down Expand Up @@ -126,6 +127,20 @@ typedef enum {

- (id)initWithProcessBlock:(id (^)(id, NSString*))processBlock;

/**
Expect multiple documents separated by whitespace
Normally the -parse: method returns SBJsonStreamParserComplete when it's found a complete JSON document.
Attempting to parse any more data at that point is considered an error. ("Garbage after JSON".)
If you set this property to true the parser will never return SBJsonStreamParserComplete. Rather,
once an object is completed it will expect another object to immediately follow, separated
only by (optional) whitespace.
*/
@property BOOL supportManyDocuments;


/**
How many levels to skip
Expand Down
4 changes: 4 additions & 0 deletions src/main/objc/SBJsonStreamParserAdapter.m
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,8 @@ - (NSString *)pathString {
return pathString;
}

- (BOOL)parserShouldSupportManyDocuments:(SBJsonStreamParser *)parser {
return self.supportManyDocuments;
}

@end
2 changes: 1 addition & 1 deletion src/main/objc/SBJsonStreamParserState.m
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ - (void)parser:(SBJsonStreamParser*)parser shouldTransitionTo:(sbjson_token_t)to

case sbjson_token_array_close:
case sbjson_token_object_close:
if (parser.supportMultipleDocuments)
if ([parser.delegate respondsToSelector:@selector(parserShouldSupportManyDocuments:)] && [parser.delegate parserShouldSupportManyDocuments:parser])
state = parser.state;
else
state = [SBJsonStreamParserStateComplete sharedInstance];
Expand Down
7 changes: 4 additions & 3 deletions src/test/objc/StreamSuite.m
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ @implementation StreamSuite {
- (void)setUp {
adapter = [SBJsonStreamParserAdapter new];
adapter.delegate = self;
adapter.supportManyDocuments = YES;

parser = [SBJsonStreamParser new];
parser.delegate = adapter;
parser.supportMultipleDocuments = YES;


arrayCount = objectCount = 0u;
}

Expand All @@ -66,7 +66,8 @@ - (void) testParsingWithShortWorkBuffer{
"consectetur adipiscing elit. Donec ultrices ornare gravida. Vestibulum"\
" ante ipsum primisin faucibus orci luctus et ultrices posuere\"}]";

parser.supportMultipleDocuments = NO;
adapter.supportManyDocuments = NO;

SBJsonStreamParserStatus status = SBJsonStreamParserWaitingForData;
NSData* data = nil;

Expand Down

0 comments on commit f342770

Please sign in to comment.