mirror of
https://github.com/wu736139669/Ash_AWord.git
synced 2026-08-08 06:46:38 +00:00
base
This commit is contained in:
+248
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
Copyright (c) 2010-2013, 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 <Foundation/Foundation.h>
|
||||
#import "SBJson4StreamParser.h"
|
||||
|
||||
/**
|
||||
Block called when the parser has parsed an item. This could be once
|
||||
for each root document parsed, or once for each unwrapped root array element.
|
||||
|
||||
@param item contains the parsed item.
|
||||
@param stop set to YES if you want the parser to stop
|
||||
*/
|
||||
typedef void (^SBJson4ValueBlock)(id item, BOOL* stop);
|
||||
|
||||
/**
|
||||
Block called if an error occurs.
|
||||
@param error the error.
|
||||
*/
|
||||
typedef void (^SBJson4ErrorBlock)(NSError* error);
|
||||
|
||||
/**
|
||||
Block used to process parsed tokens as they are encountered. You can use this
|
||||
to transform strings containing dates into NSDate, for example.
|
||||
@param item the parsed token
|
||||
@param path the JSON Path of the token
|
||||
*/
|
||||
typedef id (^SBJson4ProcessBlock)(id item, NSString* path);
|
||||
|
||||
|
||||
/**
|
||||
Parse one or more chunks of JSON data.
|
||||
|
||||
Using this class directly you can reduce the apparent latency for each
|
||||
download/parse cycle of documents over a slow connection. You can start
|
||||
parsing *and return chunks of the parsed document* before the entire
|
||||
document is downloaded.
|
||||
|
||||
Using this class is also useful to parse huge documents on disk
|
||||
bit by bit so you don't have to keep them all in memory.
|
||||
|
||||
JSON is mapped to Objective-C types in the following way:
|
||||
|
||||
- null -> NSNull
|
||||
- string -> NSString
|
||||
- array -> NSMutableArray
|
||||
- object -> NSMutableDictionary
|
||||
- true -> NSNumber's -numberWithBool:YES
|
||||
- false -> NSNumber's -numberWithBool:NO
|
||||
- number -> NSNumber
|
||||
|
||||
Since Objective-C doesn't have a dedicated class for boolean values,
|
||||
these turns into NSNumber instances. However, since these are
|
||||
initialised with the -initWithBool: method they round-trip back to JSON
|
||||
properly. In other words, they won't silently suddenly become 0 or 1;
|
||||
they'll be represented as 'true' and 'false' again.
|
||||
|
||||
Integers are parsed into either a `long long` or `unsigned long long`
|
||||
type if they fit, else a `double` is used. All real & exponential numbers
|
||||
are represented using a `double`. Previous versions of this library used
|
||||
an NSDecimalNumber in some cases, but this is no longer the case.
|
||||
|
||||
The default behaviour is that your passed-in block is only called once the
|
||||
entire input is parsed. If you set supportManyDocuments to YES and your input
|
||||
contains multiple (whitespace limited) JSON documents your block will be called
|
||||
for each document:
|
||||
|
||||
SBJson4ValueBlock block = ^(id v, BOOL *stop) {
|
||||
BOOL isArray = [v isKindOfClass:[NSArray class]];
|
||||
NSLog(@"Found: %@", isArray ? @"Array" : @"Object");
|
||||
}
|
||||
|
||||
SBJson4ErrorBlock eh = ^(NSError* err) {
|
||||
NSLog(@"OOPS: %@", err);
|
||||
}
|
||||
|
||||
id parser = [SBJson4Parser multiRootParserWithBlock:block
|
||||
errorHandler:eh];
|
||||
|
||||
// Note that this input contains multiple top-level JSON documents
|
||||
id data = [@"[]{}" dataWithEncoding:NSUTF8StringEncoding];
|
||||
[parser parse:data];
|
||||
[parser parse:data];
|
||||
|
||||
The above example will print:
|
||||
|
||||
- Found: Array
|
||||
- Found: Object
|
||||
- Found: Array
|
||||
- Found: Object
|
||||
|
||||
Often you won't have control over the input you're parsing, so can't make use
|
||||
of this feature. But, all is not lost: if you are parsing a long array you can
|
||||
get the same effect by setting rootArrayItems to YES:
|
||||
|
||||
id parser = [SBJson4Parser unwrapRootArrayParserWithBlock:block
|
||||
errorHandler:eh];
|
||||
|
||||
// Note that this input contains A SINGLE top-level document
|
||||
id data = [@"[[],{},[],{}]" dataWithEncoding:NSUTF8StringEncoding];
|
||||
[parser parse:data];
|
||||
|
||||
@note Stream based parsing does mean that you lose some of the correctness
|
||||
verification you would have with a parser that considered the entire input
|
||||
before returning an answer. It is technically possible to have some parts
|
||||
of a document returned *as if they were correct* but then encounter an error
|
||||
in a later part of the document. You should keep this in mind when
|
||||
considering whether it would suit your application.
|
||||
|
||||
|
||||
*/
|
||||
@interface SBJson4Parser : NSObject
|
||||
|
||||
/**
|
||||
Create a JSON Parser.
|
||||
|
||||
This can be used to create a parser that accepts only one document, or one that parses
|
||||
many documents any
|
||||
|
||||
@param block Called for each element. Set *stop to `YES` if you have seen
|
||||
enough and would like to skip the rest of the elements.
|
||||
|
||||
@param allowMultiRoot Indicate that you are expecting multiple whitespace-separated
|
||||
JSON documents, similar to what Twitter uses.
|
||||
|
||||
@param unwrapRootArray If set the parser will pretend an root array does not exist
|
||||
and the enumerator block will be called once for each item in it. This option
|
||||
does nothing if the the JSON has an object at its root.
|
||||
|
||||
@param eh Called if the parser encounters an error.
|
||||
|
||||
@see -unwrapRootArrayParserWithBlock:errorHandler:
|
||||
@see -multiRootParserWithBlock:errorHandler:
|
||||
@see -initWithBlock:processBlock:multiRoot:unwrapRootArray:maxDepth:errorHandler:
|
||||
|
||||
*/
|
||||
+ (id)parserWithBlock:(SBJson4ValueBlock)block
|
||||
allowMultiRoot:(BOOL)allowMultiRoot
|
||||
unwrapRootArray:(BOOL)unwrapRootArray
|
||||
errorHandler:(SBJson4ErrorBlock)eh;
|
||||
|
||||
|
||||
/**
|
||||
Create a JSON Parser that parses multiple whitespace separated documents.
|
||||
This is useful for something like twitter's feed, which gives you one JSON
|
||||
document per line.
|
||||
|
||||
@param block Called for each element. Set *stop to `YES` if you have seen
|
||||
enough and would like to skip the rest of the elements.
|
||||
|
||||
@param eh Called if the parser encounters an error.
|
||||
|
||||
@see +unwrapRootArrayParserWithBlock:errorHandler:
|
||||
@see +parserWithBlock:allowMultiRoot:unwrapRootArray:errorHandler:
|
||||
@see -initWithBlock:processBlock:multiRoot:unwrapRootArray:maxDepth:errorHandler:
|
||||
*/
|
||||
+ (id)multiRootParserWithBlock:(SBJson4ValueBlock)block
|
||||
errorHandler:(SBJson4ErrorBlock)eh;
|
||||
|
||||
/**
|
||||
Create a JSON Parser that parses a huge array and calls for the value block for
|
||||
each element in the outermost array.
|
||||
|
||||
@param block Called for each element. Set *stop to `YES` if you have seen
|
||||
enough and would like to skip the rest of the elements.
|
||||
|
||||
@param eh Called if the parser encounters an error.
|
||||
|
||||
@see +multiRootParserWithBlock:errorHandler:
|
||||
@see +parserWithBlock:allowMultiRoot:unwrapRootArray:errorHandler:
|
||||
@see -initWithBlock:processBlock:multiRoot:unwrapRootArray:maxDepth:errorHandler:
|
||||
*/
|
||||
+ (id)unwrapRootArrayParserWithBlock:(SBJson4ValueBlock)block
|
||||
errorHandler:(SBJson4ErrorBlock)eh;
|
||||
|
||||
/**
|
||||
Create a JSON Parser.
|
||||
|
||||
@param block Called for each element. Set *stop to `YES` if you have seen
|
||||
enough and would like to skip the rest of the elements.
|
||||
|
||||
@param processBlock A block that allows you to process individual values before being
|
||||
returned.
|
||||
|
||||
@param multiRoot Indicate that you are expecting multiple whitespace-separated
|
||||
JSON documents, similar to what Twitter uses.
|
||||
|
||||
@param unwrapRootArray If set the parser will pretend an root array does not exist
|
||||
and the enumerator block will be called once for each item in it. This option
|
||||
does nothing if the the JSON has an object at its root.
|
||||
|
||||
@param maxDepth The max recursion depth of the parser. Defaults to 32.
|
||||
|
||||
@param eh Called if the parser encounters an error.
|
||||
|
||||
*/
|
||||
- (id)initWithBlock:(SBJson4ValueBlock)block
|
||||
processBlock:(SBJson4ProcessBlock)processBlock
|
||||
multiRoot:(BOOL)multiRoot
|
||||
unwrapRootArray:(BOOL)unwrapRootArray
|
||||
maxDepth:(NSUInteger)maxDepth
|
||||
errorHandler:(SBJson4ErrorBlock)eh;
|
||||
|
||||
/**
|
||||
Parse some JSON
|
||||
|
||||
The JSON is assumed to be UTF8 encoded. This can be a full JSON document, or a part of one.
|
||||
|
||||
@param data An NSData object containing the next chunk of JSON
|
||||
|
||||
@return
|
||||
- SBJson4ParserComplete if a full document was found
|
||||
- SBJson4ParserWaitingForData if a partial document was found and more data is required to complete it
|
||||
- SBJson4ParserError if an error occured.
|
||||
|
||||
*/
|
||||
- (SBJson4ParserStatus)parse:(NSData*)data;
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user