add .gitignore
This commit is contained in:
1
msext/Class/SGGateway/JSON/.svn/entries
Executable file
1
msext/Class/SGGateway/JSON/.svn/entries
Executable file
@@ -0,0 +1 @@
|
||||
12
|
||||
1
msext/Class/SGGateway/JSON/.svn/format
Executable file
1
msext/Class/SGGateway/JSON/.svn/format
Executable file
@@ -0,0 +1 @@
|
||||
12
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonBase.h"
|
||||
NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain";
|
||||
|
||||
|
||||
@implementation SBJsonBase
|
||||
|
||||
@synthesize errorTrace;
|
||||
@synthesize maxDepth;
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self)
|
||||
self.maxDepth = 512;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[errorTrace release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str {
|
||||
NSDictionary *userInfo;
|
||||
if (!errorTrace) {
|
||||
errorTrace = [NSMutableArray new];
|
||||
userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey];
|
||||
|
||||
} else {
|
||||
userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
str, NSLocalizedDescriptionKey,
|
||||
[errorTrace lastObject], NSUnderlyingErrorKey,
|
||||
nil];
|
||||
}
|
||||
|
||||
NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo];
|
||||
|
||||
[self willChangeValueForKey:@"errorTrace"];
|
||||
[errorTrace addObject:error];
|
||||
[self didChangeValueForKey:@"errorTrace"];
|
||||
}
|
||||
|
||||
- (void)clearErrorTrace {
|
||||
[self willChangeValueForKey:@"errorTrace"];
|
||||
[errorTrace release];
|
||||
errorTrace = nil;
|
||||
[self didChangeValueForKey:@"errorTrace"];
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonBase.h"
|
||||
|
||||
/**
|
||||
@brief Options for the parser class.
|
||||
|
||||
This exists so the SBJSON facade can implement the options in the parser without having to re-declare them.
|
||||
*/
|
||||
@protocol SBJsonParser
|
||||
|
||||
/**
|
||||
@brief Return the object represented by the given string.
|
||||
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object can be
|
||||
a string, number, boolean, null, array or dictionary.
|
||||
|
||||
@param repr the json string to parse
|
||||
*/
|
||||
- (id)objectWithString:(NSString *)repr;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
@brief The JSON parser class.
|
||||
|
||||
JSON is mapped to Objective-C types in the following way:
|
||||
|
||||
@li Null -> NSNull
|
||||
@li String -> NSMutableString
|
||||
@li Array -> NSMutableArray
|
||||
@li Object -> NSMutableDictionary
|
||||
@li Boolean -> NSNumber (initialised with -initWithBool:)
|
||||
@li Number -> NSDecimalNumber
|
||||
|
||||
Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber
|
||||
instances. These are initialised with the -initWithBool: method, and
|
||||
round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be
|
||||
represented as 'true' and 'false' again.)
|
||||
|
||||
JSON numbers turn into NSDecimalNumber instances,
|
||||
as we can thus avoid any loss of precision. (JSON allows ridiculously large numbers.)
|
||||
|
||||
*/
|
||||
@interface SBJsonParser : SBJsonBase <SBJsonParser> {
|
||||
|
||||
@private
|
||||
const char *c;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// don't use - exists for backwards compatibility with 2.1.x only. Will be removed in 2.3.
|
||||
@interface SBJsonParser (Private)
|
||||
- (id)fragmentWithString:(id)repr;
|
||||
@end
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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>
|
||||
|
||||
/**
|
||||
@brief Adds JSON parsing methods to NSString
|
||||
|
||||
This is a category on NSString that adds methods for parsing the target string.
|
||||
*/
|
||||
@interface NSString (NSString_SBJSON)
|
||||
|
||||
|
||||
/**
|
||||
@brief Returns the object represented in the receiver, or nil on error.
|
||||
|
||||
Returns a a scalar object represented by the string's JSON fragment representation.
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (id)JSONFragmentValue;
|
||||
|
||||
/**
|
||||
@brief Returns the NSDictionary or NSArray represented by the current string's JSON representation.
|
||||
|
||||
Returns the dictionary or array represented in the receiver, or nil on error.
|
||||
|
||||
Returns the NSDictionary or NSArray represented by the current string's JSON representation.
|
||||
*/
|
||||
- (id)JSONValue;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonWriter.h"
|
||||
|
||||
@interface SBJsonWriter ()
|
||||
|
||||
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json;
|
||||
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json;
|
||||
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json;
|
||||
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json;
|
||||
|
||||
- (NSString*)indent;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SBJsonWriter
|
||||
|
||||
static NSMutableCharacterSet *kEscapeChars;
|
||||
|
||||
+ (void)initialize {
|
||||
kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain];
|
||||
[kEscapeChars addCharactersInString: @"\"\\"];
|
||||
}
|
||||
|
||||
|
||||
@synthesize sortKeys;
|
||||
@synthesize humanReadable;
|
||||
|
||||
/**
|
||||
@deprecated This exists in order to provide fragment support in older APIs in one more version.
|
||||
It should be removed in the next major version.
|
||||
*/
|
||||
- (NSString*)stringWithFragment:(id)value {
|
||||
[self clearErrorTrace];
|
||||
depth = 0;
|
||||
NSMutableString *json = [NSMutableString stringWithCapacity:128];
|
||||
|
||||
if ([self appendValue:value into:json])
|
||||
return json;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (NSString*)stringWithObject:(id)value {
|
||||
|
||||
if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
|
||||
return [self stringWithFragment:value];
|
||||
}
|
||||
|
||||
if ([value respondsToSelector:@selector(proxyForJson)]) {
|
||||
NSString *tmp = [self stringWithObject:[value proxyForJson]];
|
||||
if (tmp)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
[self clearErrorTrace];
|
||||
[self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (NSString*)indent {
|
||||
return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0];
|
||||
}
|
||||
|
||||
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json {
|
||||
if ([fragment isKindOfClass:[NSDictionary class]]) {
|
||||
if (![self appendDictionary:fragment into:json])
|
||||
return NO;
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSArray class]]) {
|
||||
if (![self appendArray:fragment into:json])
|
||||
return NO;
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSString class]]) {
|
||||
if (![self appendString:fragment into:json])
|
||||
return NO;
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSNumber class]]) {
|
||||
if ('c' == *[fragment objCType])
|
||||
[json appendString:[fragment boolValue] ? @"true" : @"false"];
|
||||
else
|
||||
[json appendString:[fragment stringValue]];
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSNull class]]) {
|
||||
[json appendString:@"null"];
|
||||
} else if ([fragment respondsToSelector:@selector(proxyForJson)]) {
|
||||
[self appendValue:[fragment proxyForJson] into:json];
|
||||
|
||||
} else {
|
||||
[self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]];
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json {
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
[json appendString:@"["];
|
||||
|
||||
BOOL addComma = NO;
|
||||
for (id value in fragment) {
|
||||
if (addComma)
|
||||
[json appendString:@","];
|
||||
else
|
||||
addComma = YES;
|
||||
|
||||
if ([self humanReadable])
|
||||
[json appendString:[self indent]];
|
||||
|
||||
if (![self appendValue:value into:json]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
depth--;
|
||||
if ([self humanReadable] && [fragment count])
|
||||
[json appendString:[self indent]];
|
||||
[json appendString:@"]"];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json {
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
[json appendString:@"{"];
|
||||
|
||||
NSString *colon = [self humanReadable] ? @" : " : @":";
|
||||
BOOL addComma = NO;
|
||||
NSArray *keys = [fragment allKeys];
|
||||
if (self.sortKeys)
|
||||
keys = [keys sortedArrayUsingSelector:@selector(compare:)];
|
||||
|
||||
for (id value in keys) {
|
||||
if (addComma)
|
||||
[json appendString:@","];
|
||||
else
|
||||
addComma = YES;
|
||||
|
||||
if ([self humanReadable])
|
||||
[json appendString:[self indent]];
|
||||
|
||||
if (![value isKindOfClass:[NSString class]]) {
|
||||
[self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (![self appendString:value into:json])
|
||||
return NO;
|
||||
|
||||
[json appendString:colon];
|
||||
if (![self appendValue:[fragment objectForKey:value] into:json]) {
|
||||
[self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
depth--;
|
||||
if ([self humanReadable] && [fragment count])
|
||||
[json appendString:[self indent]];
|
||||
[json appendString:@"}"];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json {
|
||||
|
||||
[json appendString:@"\""];
|
||||
|
||||
NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars];
|
||||
if ( !esc.length ) {
|
||||
// No special chars -- can just add the raw string:
|
||||
[json appendString:fragment];
|
||||
|
||||
} else {
|
||||
NSUInteger length = [fragment length];
|
||||
for (NSUInteger i = 0; i < length; i++) {
|
||||
unichar uc = [fragment characterAtIndex:i];
|
||||
switch (uc) {
|
||||
case '"': [json appendString:@"\\\""]; break;
|
||||
case '\\': [json appendString:@"\\\\"]; break;
|
||||
case '\t': [json appendString:@"\\t"]; break;
|
||||
case '\n': [json appendString:@"\\n"]; break;
|
||||
case '\r': [json appendString:@"\\r"]; break;
|
||||
case '\b': [json appendString:@"\\b"]; break;
|
||||
case '\f': [json appendString:@"\\f"]; break;
|
||||
default:
|
||||
if (uc < 0x20) {
|
||||
[json appendFormat:@"\\u%04x", uc];
|
||||
} else {
|
||||
CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[json appendString:@"\""];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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>
|
||||
|
||||
extern NSString * SBJSONErrorDomain;
|
||||
|
||||
|
||||
enum {
|
||||
EUNSUPPORTED = 1,
|
||||
EPARSENUM,
|
||||
EPARSE,
|
||||
EFRAGMENT,
|
||||
ECTRL,
|
||||
EUNICODE,
|
||||
EDEPTH,
|
||||
EESCAPE,
|
||||
ETRAILCOMMA,
|
||||
ETRAILGARBAGE,
|
||||
EEOF,
|
||||
EINPUT
|
||||
};
|
||||
|
||||
/**
|
||||
@brief Common base class for parsing & writing.
|
||||
|
||||
This class contains the common error-handling code and option between the parser/writer.
|
||||
*/
|
||||
@interface SBJsonBase : NSObject {
|
||||
NSMutableArray *errorTrace;
|
||||
|
||||
@protected
|
||||
NSUInteger depth, maxDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief The maximum recursing depth.
|
||||
|
||||
Defaults to 512. If the input is nested deeper than this the input will be deemed to be
|
||||
malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
|
||||
turn off this security feature by setting the maxDepth value to 0.
|
||||
*/
|
||||
@property NSUInteger maxDepth;
|
||||
|
||||
/**
|
||||
@brief Return an error trace, or nil if there was no errors.
|
||||
|
||||
Note that this method returns the trace of the last method that failed.
|
||||
You need to check the return value of the call you're making to figure out
|
||||
if the call actually failed, before you know call this method.
|
||||
*/
|
||||
@property(copy,readonly) NSArray* errorTrace;
|
||||
|
||||
/// @internal for use in subclasses to add errors to the stack trace
|
||||
- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str;
|
||||
|
||||
/// @internal for use in subclasess to clear the error before a new parsing attempt
|
||||
- (void)clearErrorTrace;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (C) 2007-2009 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 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 OWNER 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 "NSString+SBJSON.h"
|
||||
#import "SBJsonParser.h"
|
||||
|
||||
@implementation NSString (NSString_SBJSON)
|
||||
|
||||
- (id)JSONFragmentValue
|
||||
{
|
||||
SBJsonParser *jsonParser = [SBJsonParser new];
|
||||
id repr = [jsonParser fragmentWithString:self];
|
||||
if (!repr)
|
||||
//CCLOG(@"-JSONFragmentValue failed. Error trace is: %@", [jsonParser errorTrace]);
|
||||
[jsonParser release];
|
||||
return repr;
|
||||
}
|
||||
|
||||
- (id)JSONValue
|
||||
{
|
||||
SBJsonParser *jsonParser = [SBJsonParser new];
|
||||
id repr = [jsonParser objectWithString:self];
|
||||
if (!repr)
|
||||
//CCLOG(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]);
|
||||
[jsonParser release];
|
||||
return repr;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonBase.h"
|
||||
|
||||
/**
|
||||
@brief Options for the writer class.
|
||||
|
||||
This exists so the SBJSON facade can implement the options in the writer without having to re-declare them.
|
||||
*/
|
||||
@protocol SBJsonWriter
|
||||
|
||||
/**
|
||||
@brief Whether we are generating human-readable (multiline) JSON.
|
||||
|
||||
Set whether or not to generate human-readable JSON. The default is NO, which produces
|
||||
JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable
|
||||
JSON with linebreaks after each array value and dictionary key/value pair, indented two
|
||||
spaces per nesting level.
|
||||
*/
|
||||
@property BOOL humanReadable;
|
||||
|
||||
/**
|
||||
@brief Whether or not to sort the dictionary keys in the output.
|
||||
|
||||
If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
|
||||
(This is useful if you need to compare two structures, for example.) The default is NO.
|
||||
*/
|
||||
@property BOOL sortKeys;
|
||||
|
||||
/**
|
||||
@brief Return JSON representation (or fragment) for the given object.
|
||||
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value any instance that can be represented as a JSON fragment
|
||||
|
||||
*/
|
||||
- (NSString*)stringWithObject:(id)value;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
@brief The JSON writer class.
|
||||
|
||||
Objective-C types are mapped to JSON types in the following way:
|
||||
|
||||
@li NSNull -> Null
|
||||
@li NSString -> String
|
||||
@li NSArray -> Array
|
||||
@li NSDictionary -> Object
|
||||
@li NSNumber (-initWithBool:) -> Boolean
|
||||
@li NSNumber -> Number
|
||||
|
||||
In JSON the keys of an object must be strings. NSDictionary keys need
|
||||
not be, but attempting to convert an NSDictionary with non-string keys
|
||||
into JSON will throw an exception.
|
||||
|
||||
NSNumber instances created with the +initWithBool: method are
|
||||
converted into the JSON boolean "true" and "false" values, and vice
|
||||
versa. Any other NSNumber instances are converted to a JSON number the
|
||||
way you would expect.
|
||||
|
||||
*/
|
||||
@interface SBJsonWriter : SBJsonBase <SBJsonWriter> {
|
||||
|
||||
@private
|
||||
BOOL sortKeys, humanReadable;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// don't use - exists for backwards compatibility. Will be removed in 2.3.
|
||||
@interface SBJsonWriter (Private)
|
||||
- (NSString*)stringWithFragment:(id)value;
|
||||
@end
|
||||
|
||||
/**
|
||||
@brief Allows generation of JSON for otherwise unsupported classes.
|
||||
|
||||
If you have a custom class that you want to create a JSON representation for you can implement
|
||||
this method in your class. It should return a representation of your object defined
|
||||
in terms of objects that can be translated into JSON. For example, a Person
|
||||
object might implement it like this:
|
||||
|
||||
@code
|
||||
- (id)jsonProxyObject {
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
name, @"name",
|
||||
phone, @"phone",
|
||||
email, @"email",
|
||||
nil];
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
||||
@interface NSObject (SBProxyForJson)
|
||||
- (id)proxyForJson;
|
||||
@end
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright (C) 2007-2009 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 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 OWNER 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 "SBJSON.h"
|
||||
|
||||
@implementation SBJSON
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
jsonWriter = [SBJsonWriter new];
|
||||
jsonParser = [SBJsonParser new];
|
||||
[self setMaxDepth:512];
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[jsonWriter release];
|
||||
[jsonParser release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#pragma mark Writer
|
||||
|
||||
|
||||
- (NSString *)stringWithObject:(id)obj {
|
||||
NSString *repr = [jsonWriter stringWithObject:obj];
|
||||
if (repr)
|
||||
return repr;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonWriter errorTrace] mutableCopy];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value any instance that can be represented as a JSON fragment
|
||||
@param allowScalar wether to return json fragments for scalar objects
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (NSString*)stringWithObject:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
|
||||
|
||||
NSString *json = allowScalar ? [jsonWriter stringWithFragment:value] : [jsonWriter stringWithObject:value];
|
||||
if (json)
|
||||
return json;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonWriter errorTrace] mutableCopy];
|
||||
|
||||
if (error)
|
||||
*error = [errorTrace lastObject];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value any instance that can be represented as a JSON fragment
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (NSString*)stringWithFragment:(id)value error:(NSError**)error {
|
||||
return [self stringWithObject:value
|
||||
allowScalar:YES
|
||||
error:error];
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value a NSDictionary or NSArray instance
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
*/
|
||||
- (NSString*)stringWithObject:(id)value error:(NSError**)error {
|
||||
return [self stringWithObject:value
|
||||
allowScalar:NO
|
||||
error:error];
|
||||
}
|
||||
|
||||
#pragma mark Parsing
|
||||
|
||||
- (id)objectWithString:(NSString *)repr {
|
||||
id obj = [jsonParser objectWithString:repr];
|
||||
if (obj)
|
||||
return obj;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonParser errorTrace] mutableCopy];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object can be
|
||||
a string, number, boolean, null, array or dictionary.
|
||||
|
||||
@param value the json string to parse
|
||||
@param allowScalar whether to return objects for JSON fragments
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (id)objectWithString:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
|
||||
|
||||
id obj = allowScalar ? [jsonParser fragmentWithString:value] : [jsonParser objectWithString:value];
|
||||
if (obj)
|
||||
return obj;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonParser errorTrace] mutableCopy];
|
||||
|
||||
if (error)
|
||||
*error = [errorTrace lastObject];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object can be
|
||||
a string, number, boolean, null, array or dictionary.
|
||||
|
||||
@param repr the json string to parse
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (id)fragmentWithString:(NSString*)repr error:(NSError**)error {
|
||||
return [self objectWithString:repr
|
||||
allowScalar:YES
|
||||
error:error];
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object
|
||||
will be either a dictionary or an array.
|
||||
|
||||
@param repr the json string to parse
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
*/
|
||||
- (id)objectWithString:(NSString*)repr error:(NSError**)error {
|
||||
return [self objectWithString:repr
|
||||
allowScalar:NO
|
||||
error:error];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark Properties - parsing
|
||||
|
||||
- (NSUInteger)maxDepth {
|
||||
return jsonParser.maxDepth;
|
||||
}
|
||||
|
||||
- (void)setMaxDepth:(NSUInteger)d {
|
||||
jsonWriter.maxDepth = jsonParser.maxDepth = d;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Properties - writing
|
||||
|
||||
- (BOOL)humanReadable {
|
||||
return jsonWriter.humanReadable;
|
||||
}
|
||||
|
||||
- (void)setHumanReadable:(BOOL)x {
|
||||
jsonWriter.humanReadable = x;
|
||||
}
|
||||
|
||||
- (BOOL)sortKeys {
|
||||
return jsonWriter.sortKeys;
|
||||
}
|
||||
|
||||
- (void)setSortKeys:(BOOL)x {
|
||||
jsonWriter.sortKeys = x;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "NSObject+SBJSON.h"
|
||||
#import "SBJsonWriter.h"
|
||||
|
||||
@implementation NSObject (NSObject_SBJSON)
|
||||
|
||||
- (NSString *)JSONFragment {
|
||||
SBJsonWriter *jsonWriter = [SBJsonWriter new];
|
||||
NSString *json = [jsonWriter stringWithFragment:self];
|
||||
if (!json)
|
||||
// CCLOG(@"-JSONFragment failed. Error trace is: %@", [jsonWriter errorTrace]);
|
||||
[jsonWriter release];
|
||||
return json;
|
||||
}
|
||||
|
||||
- (NSString *)JSONRepresentation {
|
||||
SBJsonWriter *jsonWriter = [SBJsonWriter new];
|
||||
NSString *json = [jsonWriter stringWithObject:self];
|
||||
if (!json)
|
||||
// CCLOG(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]);
|
||||
[jsonWriter release];
|
||||
return json;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (C) 2007-2009 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 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 OWNER 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 "SBJsonParser.h"
|
||||
#import "SBJsonWriter.h"
|
||||
|
||||
/**
|
||||
@brief Facade for SBJsonWriter/SBJsonParser.
|
||||
|
||||
Requests are forwarded to instances of SBJsonWriter and SBJsonParser.
|
||||
*/
|
||||
@interface SBJSON : SBJsonBase <SBJsonParser, SBJsonWriter> {
|
||||
|
||||
@private
|
||||
SBJsonParser *jsonParser;
|
||||
SBJsonWriter *jsonWriter;
|
||||
}
|
||||
|
||||
|
||||
/// Return the fragment represented by the given string
|
||||
- (id)fragmentWithString:(NSString*)jsonrep
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Return the object represented by the given string
|
||||
- (id)objectWithString:(NSString*)jsonrep
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Parse the string and return the represented object (or scalar)
|
||||
- (id)objectWithString:(id)value
|
||||
allowScalar:(BOOL)x
|
||||
error:(NSError**)error;
|
||||
|
||||
|
||||
/// Return JSON representation of an array or dictionary
|
||||
- (NSString*)stringWithObject:(id)value
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Return JSON representation of any legal JSON value
|
||||
- (NSString*)stringWithFragment:(id)value
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Return JSON representation (or fragment) for the given object
|
||||
- (NSString*)stringWithObject:(id)value
|
||||
allowScalar:(BOOL)x
|
||||
error:(NSError**)error;
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonParser.h"
|
||||
|
||||
@interface SBJsonParser ()
|
||||
|
||||
- (BOOL)scanValue:(NSObject **)o;
|
||||
|
||||
- (BOOL)scanRestOfArray:(NSMutableArray **)o;
|
||||
- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o;
|
||||
- (BOOL)scanRestOfNull:(NSNull **)o;
|
||||
- (BOOL)scanRestOfFalse:(NSNumber **)o;
|
||||
- (BOOL)scanRestOfTrue:(NSNumber **)o;
|
||||
- (BOOL)scanRestOfString:(NSMutableString **)o;
|
||||
|
||||
// Cannot manage without looking at the first digit
|
||||
- (BOOL)scanNumber:(NSNumber **)o;
|
||||
|
||||
- (BOOL)scanHexQuad:(unichar *)x;
|
||||
- (BOOL)scanUnicodeChar:(unichar *)x;
|
||||
|
||||
- (BOOL)scanIsAtEnd;
|
||||
|
||||
@end
|
||||
|
||||
#define skipWhitespace(c) while (isspace(*c)) c++
|
||||
#define skipDigits(c) while (isdigit(*c)) c++
|
||||
|
||||
|
||||
@implementation SBJsonParser
|
||||
|
||||
static char ctrl[0x22];
|
||||
|
||||
|
||||
+ (void)initialize {
|
||||
ctrl[0] = '\"';
|
||||
ctrl[1] = '\\';
|
||||
for (int i = 1; i < 0x20; i++)
|
||||
ctrl[i+1] = i;
|
||||
ctrl[0x21] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@deprecated This exists in order to provide fragment support in older APIs in one more version.
|
||||
It should be removed in the next major version.
|
||||
*/
|
||||
- (id)fragmentWithString:(id)repr {
|
||||
[self clearErrorTrace];
|
||||
|
||||
if (!repr) {
|
||||
[self addErrorWithCode:EINPUT description:@"Input was 'nil'"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
depth = 0;
|
||||
c = [repr UTF8String];
|
||||
|
||||
id o;
|
||||
if (![self scanValue:&o]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// We found some valid JSON. But did it also contain something else?
|
||||
if (![self scanIsAtEnd]) {
|
||||
[self addErrorWithCode:ETRAILGARBAGE description:@"Garbage after JSON"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSAssert1(o, @"Should have a valid object from %@", repr);
|
||||
return o;
|
||||
}
|
||||
|
||||
- (id)objectWithString:(NSString *)repr {
|
||||
|
||||
id o = [self fragmentWithString:repr];
|
||||
if (!o)
|
||||
return nil;
|
||||
|
||||
// Check that the object we've found is a valid JSON container.
|
||||
if (![o isKindOfClass:[NSDictionary class]] && ![o isKindOfClass:[NSArray class]]) {
|
||||
[self addErrorWithCode:EFRAGMENT description:@"Valid fragment, but not JSON"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
/*
|
||||
In contrast to the public methods, it is an error to omit the error parameter here.
|
||||
*/
|
||||
- (BOOL)scanValue:(NSObject **)o
|
||||
{
|
||||
skipWhitespace(c);
|
||||
|
||||
switch (*c++) {
|
||||
case '{':
|
||||
return [self scanRestOfDictionary:(NSMutableDictionary **)o];
|
||||
break;
|
||||
case '[':
|
||||
return [self scanRestOfArray:(NSMutableArray **)o];
|
||||
break;
|
||||
case '"':
|
||||
return [self scanRestOfString:(NSMutableString **)o];
|
||||
break;
|
||||
case 'f':
|
||||
return [self scanRestOfFalse:(NSNumber **)o];
|
||||
break;
|
||||
case 't':
|
||||
return [self scanRestOfTrue:(NSNumber **)o];
|
||||
break;
|
||||
case 'n':
|
||||
return [self scanRestOfNull:(NSNull **)o];
|
||||
break;
|
||||
case '-':
|
||||
case '0'...'9':
|
||||
c--; // cannot verify number correctly without the first character
|
||||
return [self scanNumber:(NSNumber **)o];
|
||||
break;
|
||||
case '+':
|
||||
[self addErrorWithCode:EPARSENUM description: @"Leading + disallowed in number"];
|
||||
return NO;
|
||||
break;
|
||||
case 0x0:
|
||||
[self addErrorWithCode:EEOF description:@"Unexpected end of string"];
|
||||
return NO;
|
||||
break;
|
||||
default:
|
||||
[self addErrorWithCode:EPARSE description: @"Unrecognised leading character"];
|
||||
return NO;
|
||||
break;
|
||||
}
|
||||
|
||||
NSAssert(0, @"Should never get here");
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfTrue:(NSNumber **)o
|
||||
{
|
||||
if (!strncmp(c, "rue", 3)) {
|
||||
c += 3;
|
||||
*o = [NSNumber numberWithBool:YES];
|
||||
return YES;
|
||||
}
|
||||
[self addErrorWithCode:EPARSE description:@"Expected 'true'"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfFalse:(NSNumber **)o
|
||||
{
|
||||
if (!strncmp(c, "alse", 4)) {
|
||||
c += 4;
|
||||
*o = [NSNumber numberWithBool:NO];
|
||||
return YES;
|
||||
}
|
||||
[self addErrorWithCode:EPARSE description: @"Expected 'false'"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfNull:(NSNull **)o {
|
||||
if (!strncmp(c, "ull", 3)) {
|
||||
c += 3;
|
||||
*o = [NSNull null];
|
||||
return YES;
|
||||
}
|
||||
[self addErrorWithCode:EPARSE description: @"Expected 'null'"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfArray:(NSMutableArray **)o {
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
*o = [NSMutableArray arrayWithCapacity:8];
|
||||
|
||||
for (; *c ;) {
|
||||
id v;
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == ']' && c++) {
|
||||
depth--;
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (![self scanValue:&v]) {
|
||||
[self addErrorWithCode:EPARSE description:@"Expected value while parsing array"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
[*o addObject:v];
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == ',' && c++) {
|
||||
skipWhitespace(c);
|
||||
if (*c == ']') {
|
||||
[self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in array"];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self addErrorWithCode:EEOF description: @"End of input while parsing array"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o
|
||||
{
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
*o = [NSMutableDictionary dictionaryWithCapacity:7];
|
||||
|
||||
for (; *c ;) {
|
||||
id k, v;
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == '}' && c++) {
|
||||
depth--;
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (!(*c == '\"' && c++ && [self scanRestOfString:&k])) {
|
||||
[self addErrorWithCode:EPARSE description: @"Object key string expected"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c != ':') {
|
||||
[self addErrorWithCode:EPARSE description: @"Expected ':' separating key and value"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
c++;
|
||||
if (![self scanValue:&v]) {
|
||||
NSString *string = [NSString stringWithFormat:@"Object value expected for key: %@", k];
|
||||
[self addErrorWithCode:EPARSE description: string];
|
||||
return NO;
|
||||
}
|
||||
|
||||
[*o setObject:v forKey:k];
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == ',' && c++) {
|
||||
skipWhitespace(c);
|
||||
if (*c == '}') {
|
||||
[self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in object"];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self addErrorWithCode:EEOF description: @"End of input while parsing object"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfString:(NSMutableString **)o
|
||||
{
|
||||
*o = [NSMutableString stringWithCapacity:16];
|
||||
do {
|
||||
// First see if there's a portion we can grab in one go.
|
||||
// Doing this caused a massive speedup on the long string.
|
||||
size_t len = strcspn(c, ctrl);
|
||||
if (len) {
|
||||
// check for
|
||||
id t = [[NSString alloc] initWithBytesNoCopy:(char*)c
|
||||
length:len
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
if (t) {
|
||||
[*o appendString:t];
|
||||
[t release];
|
||||
c += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (*c == '"') {
|
||||
c++;
|
||||
return YES;
|
||||
|
||||
} else if (*c == '\\') {
|
||||
unichar uc = *++c;
|
||||
switch (uc) {
|
||||
case '\\':
|
||||
case '/':
|
||||
case '"':
|
||||
break;
|
||||
|
||||
case 'b': uc = '\b'; break;
|
||||
case 'n': uc = '\n'; break;
|
||||
case 'r': uc = '\r'; break;
|
||||
case 't': uc = '\t'; break;
|
||||
case 'f': uc = '\f'; break;
|
||||
|
||||
case 'u':
|
||||
c++;
|
||||
if (![self scanUnicodeChar:&uc]) {
|
||||
[self addErrorWithCode:EUNICODE description: @"Broken unicode character"];
|
||||
return NO;
|
||||
}
|
||||
c--; // hack.
|
||||
break;
|
||||
default:
|
||||
[self addErrorWithCode:EESCAPE description: [NSString stringWithFormat:@"Illegal escape sequence '0x%x'", uc]];
|
||||
return NO;
|
||||
break;
|
||||
}
|
||||
CFStringAppendCharacters((CFMutableStringRef)*o, &uc, 1);
|
||||
c++;
|
||||
|
||||
} else if (*c < 0x20) {
|
||||
[self addErrorWithCode:ECTRL description: [NSString stringWithFormat:@"Unescaped control character '0x%x'", *c]];
|
||||
return NO;
|
||||
|
||||
} else {
|
||||
// CCLOG(@"should not be able to get here");
|
||||
}
|
||||
} while (*c);
|
||||
|
||||
[self addErrorWithCode:EEOF description:@"Unexpected EOF while parsing string"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanUnicodeChar:(unichar *)x
|
||||
{
|
||||
unichar hi, lo;
|
||||
|
||||
if (![self scanHexQuad:&hi]) {
|
||||
[self addErrorWithCode:EUNICODE description: @"Missing hex quad"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (hi >= 0xd800) { // high surrogate char?
|
||||
if (hi < 0xdc00) { // yes - expect a low char
|
||||
|
||||
if (!(*c == '\\' && ++c && *c == 'u' && ++c && [self scanHexQuad:&lo])) {
|
||||
[self addErrorWithCode:EUNICODE description: @"Missing low character in surrogate pair"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (lo < 0xdc00 || lo >= 0xdfff) {
|
||||
[self addErrorWithCode:EUNICODE description:@"Invalid low surrogate char"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
hi = (hi - 0xd800) * 0x400 + (lo - 0xdc00) + 0x10000;
|
||||
|
||||
} else if (hi < 0xe000) {
|
||||
[self addErrorWithCode:EUNICODE description:@"Invalid high character in surrogate pair"];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
*x = hi;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)scanHexQuad:(unichar *)x
|
||||
{
|
||||
*x = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
unichar uc = *c;
|
||||
c++;
|
||||
int d = (uc >= '0' && uc <= '9')
|
||||
? uc - '0' : (uc >= 'a' && uc <= 'f')
|
||||
? (uc - 'a' + 10) : (uc >= 'A' && uc <= 'F')
|
||||
? (uc - 'A' + 10) : -1;
|
||||
if (d == -1) {
|
||||
[self addErrorWithCode:EUNICODE description:@"Missing hex digit in quad"];
|
||||
return NO;
|
||||
}
|
||||
*x *= 16;
|
||||
*x += d;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)scanNumber:(NSNumber **)o
|
||||
{
|
||||
const char *ns = c;
|
||||
|
||||
// The logic to test for validity of the number formatting is relicensed
|
||||
// from JSON::XS with permission from its author Marc Lehmann.
|
||||
// (Available at the CPAN: http://search.cpan.org/dist/JSON-XS/ .)
|
||||
|
||||
if ('-' == *c)
|
||||
c++;
|
||||
|
||||
if ('0' == *c && c++) {
|
||||
if (isdigit(*c)) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"Leading 0 disallowed in number"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
} else if (!isdigit(*c) && c != ns) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"No digits after initial minus"];
|
||||
return NO;
|
||||
|
||||
} else {
|
||||
skipDigits(c);
|
||||
}
|
||||
|
||||
// Fractional part
|
||||
if ('.' == *c && c++) {
|
||||
|
||||
if (!isdigit(*c)) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"No digits after decimal point"];
|
||||
return NO;
|
||||
}
|
||||
skipDigits(c);
|
||||
}
|
||||
|
||||
// Exponential part
|
||||
if ('e' == *c || 'E' == *c) {
|
||||
c++;
|
||||
|
||||
if ('-' == *c || '+' == *c)
|
||||
c++;
|
||||
|
||||
if (!isdigit(*c)) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"No digits after exponent"];
|
||||
return NO;
|
||||
}
|
||||
skipDigits(c);
|
||||
}
|
||||
|
||||
id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns
|
||||
length:c - ns
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
[str autorelease];
|
||||
if (str && (*o = [NSDecimalNumber decimalNumberWithString:str]))
|
||||
return YES;
|
||||
|
||||
[self addErrorWithCode:EPARSENUM description: @"Failed creating decimal instance"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanIsAtEnd
|
||||
{
|
||||
skipWhitespace(c);
|
||||
return !*c;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@mainpage A strict JSON parser and generator for Objective-C
|
||||
|
||||
JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
format. This framework provides two apis for parsing and generating
|
||||
JSON. One standard object-based and a higher level api consisting of
|
||||
categories added to existing Objective-C classes.
|
||||
|
||||
Learn more on the http://code.google.com/p/json-framework project site.
|
||||
|
||||
This framework does its best to be as strict as possible, both in what it
|
||||
accepts and what it generates. For example, it does not support trailing commas
|
||||
in arrays or objects. Nor does it support embedded comments, or
|
||||
anything else not in the JSON specification. This is considered a feature.
|
||||
|
||||
*/
|
||||
|
||||
#import "SBJSON.h"
|
||||
#import "NSObject+SBJSON.h"
|
||||
#import "NSString+SBJSON.h"
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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>
|
||||
|
||||
|
||||
/**
|
||||
@brief Adds JSON generation to Foundation classes
|
||||
|
||||
This is a category on NSObject that adds methods for returning JSON representations
|
||||
of standard objects to the objects themselves. This means you can call the
|
||||
-JSONRepresentation method on an NSArray object and it'll do what you want.
|
||||
*/
|
||||
@interface NSObject (NSObject_SBJSON)
|
||||
|
||||
/**
|
||||
@brief Returns a string containing the receiver encoded as a JSON fragment.
|
||||
|
||||
This method is added as a category on NSObject but is only actually
|
||||
supported for the following objects:
|
||||
@li NSDictionary
|
||||
@li NSArray
|
||||
@li NSString
|
||||
@li NSNumber (also used for booleans)
|
||||
@li NSNull
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (NSString *)JSONFragment;
|
||||
|
||||
/**
|
||||
@brief Returns a string containing the receiver encoded in JSON.
|
||||
|
||||
This method is added as a category on NSObject but is only actually
|
||||
supported for the following objects:
|
||||
@li NSDictionary
|
||||
@li NSArray
|
||||
*/
|
||||
- (NSString *)JSONRepresentation;
|
||||
|
||||
@end
|
||||
|
||||
BIN
msext/Class/SGGateway/JSON/.svn/wc.db
Executable file
BIN
msext/Class/SGGateway/JSON/.svn/wc.db
Executable file
Binary file not shown.
50
msext/Class/SGGateway/JSON/JSON.h
Executable file
50
msext/Class/SGGateway/JSON/JSON.h
Executable file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
@mainpage A strict JSON parser and generator for Objective-C
|
||||
|
||||
JSON (JavaScript Object Notation) is a lightweight data-interchange
|
||||
format. This framework provides two apis for parsing and generating
|
||||
JSON. One standard object-based and a higher level api consisting of
|
||||
categories added to existing Objective-C classes.
|
||||
|
||||
Learn more on the http://code.google.com/p/json-framework project site.
|
||||
|
||||
This framework does its best to be as strict as possible, both in what it
|
||||
accepts and what it generates. For example, it does not support trailing commas
|
||||
in arrays or objects. Nor does it support embedded comments, or
|
||||
anything else not in the JSON specification. This is considered a feature.
|
||||
|
||||
*/
|
||||
|
||||
#import "SBJSON.h"
|
||||
#import "NSObject+SBJSON.h"
|
||||
#import "NSString+SBJSON.h"
|
||||
|
||||
68
msext/Class/SGGateway/JSON/NSObject+SBJSON.h
Executable file
68
msext/Class/SGGateway/JSON/NSObject+SBJSON.h
Executable file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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>
|
||||
|
||||
|
||||
/**
|
||||
@brief Adds JSON generation to Foundation classes
|
||||
|
||||
This is a category on NSObject that adds methods for returning JSON representations
|
||||
of standard objects to the objects themselves. This means you can call the
|
||||
-JSONRepresentation method on an NSArray object and it'll do what you want.
|
||||
*/
|
||||
@interface NSObject (NSObject_SBJSON)
|
||||
|
||||
/**
|
||||
@brief Returns a string containing the receiver encoded as a JSON fragment.
|
||||
|
||||
This method is added as a category on NSObject but is only actually
|
||||
supported for the following objects:
|
||||
@li NSDictionary
|
||||
@li NSArray
|
||||
@li NSString
|
||||
@li NSNumber (also used for booleans)
|
||||
@li NSNull
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (NSString *)JSONFragment;
|
||||
|
||||
/**
|
||||
@brief Returns a string containing the receiver encoded in JSON.
|
||||
|
||||
This method is added as a category on NSObject but is only actually
|
||||
supported for the following objects:
|
||||
@li NSDictionary
|
||||
@li NSArray
|
||||
*/
|
||||
- (NSString *)JSONRepresentation;
|
||||
|
||||
@end
|
||||
|
||||
53
msext/Class/SGGateway/JSON/NSObject+SBJSON.m
Executable file
53
msext/Class/SGGateway/JSON/NSObject+SBJSON.m
Executable file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "NSObject+SBJSON.h"
|
||||
#import "SBJsonWriter.h"
|
||||
|
||||
@implementation NSObject (NSObject_SBJSON)
|
||||
|
||||
- (NSString *)JSONFragment {
|
||||
SBJsonWriter *jsonWriter = [SBJsonWriter new];
|
||||
NSString *json = [jsonWriter stringWithFragment:self];
|
||||
if (!json)
|
||||
// CCLOG(@"-JSONFragment failed. Error trace is: %@", [jsonWriter errorTrace]);
|
||||
[jsonWriter release];
|
||||
return json;
|
||||
}
|
||||
|
||||
- (NSString *)JSONRepresentation {
|
||||
SBJsonWriter *jsonWriter = [SBJsonWriter new];
|
||||
NSString *json = [jsonWriter stringWithObject:self];
|
||||
if (!json)
|
||||
// CCLOG(@"-JSONRepresentation failed. Error trace is: %@", [jsonWriter errorTrace]);
|
||||
[jsonWriter release];
|
||||
return json;
|
||||
}
|
||||
|
||||
@end
|
||||
58
msext/Class/SGGateway/JSON/NSString+SBJSON.h
Executable file
58
msext/Class/SGGateway/JSON/NSString+SBJSON.h
Executable file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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>
|
||||
|
||||
/**
|
||||
@brief Adds JSON parsing methods to NSString
|
||||
|
||||
This is a category on NSString that adds methods for parsing the target string.
|
||||
*/
|
||||
@interface NSString (NSString_SBJSON)
|
||||
|
||||
|
||||
/**
|
||||
@brief Returns the object represented in the receiver, or nil on error.
|
||||
|
||||
Returns a a scalar object represented by the string's JSON fragment representation.
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (id)JSONFragmentValue;
|
||||
|
||||
/**
|
||||
@brief Returns the NSDictionary or NSArray represented by the current string's JSON representation.
|
||||
|
||||
Returns the dictionary or array represented in the receiver, or nil on error.
|
||||
|
||||
Returns the NSDictionary or NSArray represented by the current string's JSON representation.
|
||||
*/
|
||||
- (id)JSONValue;
|
||||
|
||||
@end
|
||||
55
msext/Class/SGGateway/JSON/NSString+SBJSON.m
Executable file
55
msext/Class/SGGateway/JSON/NSString+SBJSON.m
Executable file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (C) 2007-2009 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 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 OWNER 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 "NSString+SBJSON.h"
|
||||
#import "SBJsonParser.h"
|
||||
|
||||
@implementation NSString (NSString_SBJSON)
|
||||
|
||||
- (id)JSONFragmentValue
|
||||
{
|
||||
SBJsonParser *jsonParser = [SBJsonParser new];
|
||||
id repr = [jsonParser fragmentWithString:self];
|
||||
if (!repr)
|
||||
//CCLOG(@"-JSONFragmentValue failed. Error trace is: %@", [jsonParser errorTrace]);
|
||||
[jsonParser release];
|
||||
return repr;
|
||||
}
|
||||
|
||||
- (id)JSONValue
|
||||
{
|
||||
SBJsonParser *jsonParser = [SBJsonParser new];
|
||||
id repr = [jsonParser objectWithString:self];
|
||||
if (!repr)
|
||||
//CCLOG(@"-JSONValue failed. Error trace is: %@", [jsonParser errorTrace]);
|
||||
[jsonParser release];
|
||||
return repr;
|
||||
}
|
||||
|
||||
@end
|
||||
75
msext/Class/SGGateway/JSON/SBJSON.h
Executable file
75
msext/Class/SGGateway/JSON/SBJSON.h
Executable file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright (C) 2007-2009 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 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 OWNER 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 "SBJsonParser.h"
|
||||
#import "SBJsonWriter.h"
|
||||
|
||||
/**
|
||||
@brief Facade for SBJsonWriter/SBJsonParser.
|
||||
|
||||
Requests are forwarded to instances of SBJsonWriter and SBJsonParser.
|
||||
*/
|
||||
@interface SBJSON : SBJsonBase <SBJsonParser, SBJsonWriter> {
|
||||
|
||||
@private
|
||||
SBJsonParser *jsonParser;
|
||||
SBJsonWriter *jsonWriter;
|
||||
}
|
||||
|
||||
|
||||
/// Return the fragment represented by the given string
|
||||
- (id)fragmentWithString:(NSString*)jsonrep
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Return the object represented by the given string
|
||||
- (id)objectWithString:(NSString*)jsonrep
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Parse the string and return the represented object (or scalar)
|
||||
- (id)objectWithString:(id)value
|
||||
allowScalar:(BOOL)x
|
||||
error:(NSError**)error;
|
||||
|
||||
|
||||
/// Return JSON representation of an array or dictionary
|
||||
- (NSString*)stringWithObject:(id)value
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Return JSON representation of any legal JSON value
|
||||
- (NSString*)stringWithFragment:(id)value
|
||||
error:(NSError**)error;
|
||||
|
||||
/// Return JSON representation (or fragment) for the given object
|
||||
- (NSString*)stringWithObject:(id)value
|
||||
allowScalar:(BOOL)x
|
||||
error:(NSError**)error;
|
||||
|
||||
|
||||
@end
|
||||
212
msext/Class/SGGateway/JSON/SBJSON.m
Executable file
212
msext/Class/SGGateway/JSON/SBJSON.m
Executable file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright (C) 2007-2009 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 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 OWNER 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 "SBJSON.h"
|
||||
|
||||
@implementation SBJSON
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
jsonWriter = [SBJsonWriter new];
|
||||
jsonParser = [SBJsonParser new];
|
||||
[self setMaxDepth:512];
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[jsonWriter release];
|
||||
[jsonParser release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
#pragma mark Writer
|
||||
|
||||
|
||||
- (NSString *)stringWithObject:(id)obj {
|
||||
NSString *repr = [jsonWriter stringWithObject:obj];
|
||||
if (repr)
|
||||
return repr;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonWriter errorTrace] mutableCopy];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value any instance that can be represented as a JSON fragment
|
||||
@param allowScalar wether to return json fragments for scalar objects
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (NSString*)stringWithObject:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
|
||||
|
||||
NSString *json = allowScalar ? [jsonWriter stringWithFragment:value] : [jsonWriter stringWithObject:value];
|
||||
if (json)
|
||||
return json;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonWriter errorTrace] mutableCopy];
|
||||
|
||||
if (error)
|
||||
*error = [errorTrace lastObject];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value any instance that can be represented as a JSON fragment
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (NSString*)stringWithFragment:(id)value error:(NSError**)error {
|
||||
return [self stringWithObject:value
|
||||
allowScalar:YES
|
||||
error:error];
|
||||
}
|
||||
|
||||
/**
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value a NSDictionary or NSArray instance
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
*/
|
||||
- (NSString*)stringWithObject:(id)value error:(NSError**)error {
|
||||
return [self stringWithObject:value
|
||||
allowScalar:NO
|
||||
error:error];
|
||||
}
|
||||
|
||||
#pragma mark Parsing
|
||||
|
||||
- (id)objectWithString:(NSString *)repr {
|
||||
id obj = [jsonParser objectWithString:repr];
|
||||
if (obj)
|
||||
return obj;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonParser errorTrace] mutableCopy];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object can be
|
||||
a string, number, boolean, null, array or dictionary.
|
||||
|
||||
@param value the json string to parse
|
||||
@param allowScalar whether to return objects for JSON fragments
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (id)objectWithString:(id)value allowScalar:(BOOL)allowScalar error:(NSError**)error {
|
||||
|
||||
id obj = allowScalar ? [jsonParser fragmentWithString:value] : [jsonParser objectWithString:value];
|
||||
if (obj)
|
||||
return obj;
|
||||
|
||||
[errorTrace release];
|
||||
errorTrace = [[jsonParser errorTrace] mutableCopy];
|
||||
|
||||
if (error)
|
||||
*error = [errorTrace lastObject];
|
||||
return nil;
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object can be
|
||||
a string, number, boolean, null, array or dictionary.
|
||||
|
||||
@param repr the json string to parse
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
|
||||
@deprecated Given we bill ourselves as a "strict" JSON library, this method should be removed.
|
||||
*/
|
||||
- (id)fragmentWithString:(NSString*)repr error:(NSError**)error {
|
||||
return [self objectWithString:repr
|
||||
allowScalar:YES
|
||||
error:error];
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object
|
||||
will be either a dictionary or an array.
|
||||
|
||||
@param repr the json string to parse
|
||||
@param error used to return an error by reference (pass NULL if this is not desired)
|
||||
*/
|
||||
- (id)objectWithString:(NSString*)repr error:(NSError**)error {
|
||||
return [self objectWithString:repr
|
||||
allowScalar:NO
|
||||
error:error];
|
||||
}
|
||||
|
||||
|
||||
|
||||
#pragma mark Properties - parsing
|
||||
|
||||
- (NSUInteger)maxDepth {
|
||||
return jsonParser.maxDepth;
|
||||
}
|
||||
|
||||
- (void)setMaxDepth:(NSUInteger)d {
|
||||
jsonWriter.maxDepth = jsonParser.maxDepth = d;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Properties - writing
|
||||
|
||||
- (BOOL)humanReadable {
|
||||
return jsonWriter.humanReadable;
|
||||
}
|
||||
|
||||
- (void)setHumanReadable:(BOOL)x {
|
||||
jsonWriter.humanReadable = x;
|
||||
}
|
||||
|
||||
- (BOOL)sortKeys {
|
||||
return jsonWriter.sortKeys;
|
||||
}
|
||||
|
||||
- (void)setSortKeys:(BOOL)x {
|
||||
jsonWriter.sortKeys = x;
|
||||
}
|
||||
|
||||
@end
|
||||
86
msext/Class/SGGateway/JSON/SBJsonBase.h
Executable file
86
msext/Class/SGGateway/JSON/SBJsonBase.h
Executable file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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>
|
||||
|
||||
extern NSString * SBJSONErrorDomain;
|
||||
|
||||
|
||||
enum {
|
||||
EUNSUPPORTED = 1,
|
||||
EPARSENUM,
|
||||
EPARSE,
|
||||
EFRAGMENT,
|
||||
ECTRL,
|
||||
EUNICODE,
|
||||
EDEPTH,
|
||||
EESCAPE,
|
||||
ETRAILCOMMA,
|
||||
ETRAILGARBAGE,
|
||||
EEOF,
|
||||
EINPUT
|
||||
};
|
||||
|
||||
/**
|
||||
@brief Common base class for parsing & writing.
|
||||
|
||||
This class contains the common error-handling code and option between the parser/writer.
|
||||
*/
|
||||
@interface SBJsonBase : NSObject {
|
||||
NSMutableArray *errorTrace;
|
||||
|
||||
@protected
|
||||
NSUInteger depth, maxDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
@brief The maximum recursing depth.
|
||||
|
||||
Defaults to 512. If the input is nested deeper than this the input will be deemed to be
|
||||
malicious and the parser returns nil, signalling an error. ("Nested too deep".) You can
|
||||
turn off this security feature by setting the maxDepth value to 0.
|
||||
*/
|
||||
@property NSUInteger maxDepth;
|
||||
|
||||
/**
|
||||
@brief Return an error trace, or nil if there was no errors.
|
||||
|
||||
Note that this method returns the trace of the last method that failed.
|
||||
You need to check the return value of the call you're making to figure out
|
||||
if the call actually failed, before you know call this method.
|
||||
*/
|
||||
@property(copy,readonly) NSArray* errorTrace;
|
||||
|
||||
/// @internal for use in subclasses to add errors to the stack trace
|
||||
- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str;
|
||||
|
||||
/// @internal for use in subclasess to clear the error before a new parsing attempt
|
||||
- (void)clearErrorTrace;
|
||||
|
||||
@end
|
||||
78
msext/Class/SGGateway/JSON/SBJsonBase.m
Executable file
78
msext/Class/SGGateway/JSON/SBJsonBase.m
Executable file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonBase.h"
|
||||
NSString * SBJSONErrorDomain = @"org.brautaset.JSON.ErrorDomain";
|
||||
|
||||
|
||||
@implementation SBJsonBase
|
||||
|
||||
@synthesize errorTrace;
|
||||
@synthesize maxDepth;
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self)
|
||||
self.maxDepth = 512;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[errorTrace release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)addErrorWithCode:(NSUInteger)code description:(NSString*)str {
|
||||
NSDictionary *userInfo;
|
||||
if (!errorTrace) {
|
||||
errorTrace = [NSMutableArray new];
|
||||
userInfo = [NSDictionary dictionaryWithObject:str forKey:NSLocalizedDescriptionKey];
|
||||
|
||||
} else {
|
||||
userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
str, NSLocalizedDescriptionKey,
|
||||
[errorTrace lastObject], NSUnderlyingErrorKey,
|
||||
nil];
|
||||
}
|
||||
|
||||
NSError *error = [NSError errorWithDomain:SBJSONErrorDomain code:code userInfo:userInfo];
|
||||
|
||||
[self willChangeValueForKey:@"errorTrace"];
|
||||
[errorTrace addObject:error];
|
||||
[self didChangeValueForKey:@"errorTrace"];
|
||||
}
|
||||
|
||||
- (void)clearErrorTrace {
|
||||
[self willChangeValueForKey:@"errorTrace"];
|
||||
[errorTrace release];
|
||||
errorTrace = nil;
|
||||
[self didChangeValueForKey:@"errorTrace"];
|
||||
}
|
||||
|
||||
@end
|
||||
87
msext/Class/SGGateway/JSON/SBJsonParser.h
Executable file
87
msext/Class/SGGateway/JSON/SBJsonParser.h
Executable file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonBase.h"
|
||||
|
||||
/**
|
||||
@brief Options for the parser class.
|
||||
|
||||
This exists so the SBJSON facade can implement the options in the parser without having to re-declare them.
|
||||
*/
|
||||
@protocol SBJsonParser
|
||||
|
||||
/**
|
||||
@brief Return the object represented by the given string.
|
||||
|
||||
Returns the object represented by the passed-in string or nil on error. The returned object can be
|
||||
a string, number, boolean, null, array or dictionary.
|
||||
|
||||
@param repr the json string to parse
|
||||
*/
|
||||
- (id)objectWithString:(NSString *)repr;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
@brief The JSON parser class.
|
||||
|
||||
JSON is mapped to Objective-C types in the following way:
|
||||
|
||||
@li Null -> NSNull
|
||||
@li String -> NSMutableString
|
||||
@li Array -> NSMutableArray
|
||||
@li Object -> NSMutableDictionary
|
||||
@li Boolean -> NSNumber (initialised with -initWithBool:)
|
||||
@li Number -> NSDecimalNumber
|
||||
|
||||
Since Objective-C doesn't have a dedicated class for boolean values, these turns into NSNumber
|
||||
instances. These are initialised with the -initWithBool: method, and
|
||||
round-trip back to JSON properly. (They won't silently suddenly become 0 or 1; they'll be
|
||||
represented as 'true' and 'false' again.)
|
||||
|
||||
JSON numbers turn into NSDecimalNumber instances,
|
||||
as we can thus avoid any loss of precision. (JSON allows ridiculously large numbers.)
|
||||
|
||||
*/
|
||||
@interface SBJsonParser : SBJsonBase <SBJsonParser> {
|
||||
|
||||
@private
|
||||
const char *c;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// don't use - exists for backwards compatibility with 2.1.x only. Will be removed in 2.3.
|
||||
@interface SBJsonParser (Private)
|
||||
- (id)fragmentWithString:(id)repr;
|
||||
@end
|
||||
|
||||
|
||||
475
msext/Class/SGGateway/JSON/SBJsonParser.m
Executable file
475
msext/Class/SGGateway/JSON/SBJsonParser.m
Executable file
@@ -0,0 +1,475 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonParser.h"
|
||||
|
||||
@interface SBJsonParser ()
|
||||
|
||||
- (BOOL)scanValue:(NSObject **)o;
|
||||
|
||||
- (BOOL)scanRestOfArray:(NSMutableArray **)o;
|
||||
- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o;
|
||||
- (BOOL)scanRestOfNull:(NSNull **)o;
|
||||
- (BOOL)scanRestOfFalse:(NSNumber **)o;
|
||||
- (BOOL)scanRestOfTrue:(NSNumber **)o;
|
||||
- (BOOL)scanRestOfString:(NSMutableString **)o;
|
||||
|
||||
// Cannot manage without looking at the first digit
|
||||
- (BOOL)scanNumber:(NSNumber **)o;
|
||||
|
||||
- (BOOL)scanHexQuad:(unichar *)x;
|
||||
- (BOOL)scanUnicodeChar:(unichar *)x;
|
||||
|
||||
- (BOOL)scanIsAtEnd;
|
||||
|
||||
@end
|
||||
|
||||
#define skipWhitespace(c) while (isspace(*c)) c++
|
||||
#define skipDigits(c) while (isdigit(*c)) c++
|
||||
|
||||
|
||||
@implementation SBJsonParser
|
||||
|
||||
static char ctrl[0x22];
|
||||
|
||||
|
||||
+ (void)initialize {
|
||||
ctrl[0] = '\"';
|
||||
ctrl[1] = '\\';
|
||||
for (int i = 1; i < 0x20; i++)
|
||||
ctrl[i+1] = i;
|
||||
ctrl[0x21] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@deprecated This exists in order to provide fragment support in older APIs in one more version.
|
||||
It should be removed in the next major version.
|
||||
*/
|
||||
- (id)fragmentWithString:(id)repr {
|
||||
[self clearErrorTrace];
|
||||
|
||||
if (!repr) {
|
||||
[self addErrorWithCode:EINPUT description:@"Input was 'nil'"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
depth = 0;
|
||||
c = [repr UTF8String];
|
||||
|
||||
id o;
|
||||
if (![self scanValue:&o]) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
// We found some valid JSON. But did it also contain something else?
|
||||
if (![self scanIsAtEnd]) {
|
||||
[self addErrorWithCode:ETRAILGARBAGE description:@"Garbage after JSON"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSAssert1(o, @"Should have a valid object from %@", repr);
|
||||
return o;
|
||||
}
|
||||
|
||||
- (id)objectWithString:(NSString *)repr {
|
||||
|
||||
id o = [self fragmentWithString:repr];
|
||||
if (!o)
|
||||
return nil;
|
||||
|
||||
// Check that the object we've found is a valid JSON container.
|
||||
if (![o isKindOfClass:[NSDictionary class]] && ![o isKindOfClass:[NSArray class]]) {
|
||||
[self addErrorWithCode:EFRAGMENT description:@"Valid fragment, but not JSON"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
/*
|
||||
In contrast to the public methods, it is an error to omit the error parameter here.
|
||||
*/
|
||||
- (BOOL)scanValue:(NSObject **)o
|
||||
{
|
||||
skipWhitespace(c);
|
||||
|
||||
switch (*c++) {
|
||||
case '{':
|
||||
return [self scanRestOfDictionary:(NSMutableDictionary **)o];
|
||||
break;
|
||||
case '[':
|
||||
return [self scanRestOfArray:(NSMutableArray **)o];
|
||||
break;
|
||||
case '"':
|
||||
return [self scanRestOfString:(NSMutableString **)o];
|
||||
break;
|
||||
case 'f':
|
||||
return [self scanRestOfFalse:(NSNumber **)o];
|
||||
break;
|
||||
case 't':
|
||||
return [self scanRestOfTrue:(NSNumber **)o];
|
||||
break;
|
||||
case 'n':
|
||||
return [self scanRestOfNull:(NSNull **)o];
|
||||
break;
|
||||
case '-':
|
||||
case '0'...'9':
|
||||
c--; // cannot verify number correctly without the first character
|
||||
return [self scanNumber:(NSNumber **)o];
|
||||
break;
|
||||
case '+':
|
||||
[self addErrorWithCode:EPARSENUM description: @"Leading + disallowed in number"];
|
||||
return NO;
|
||||
break;
|
||||
case 0x0:
|
||||
[self addErrorWithCode:EEOF description:@"Unexpected end of string"];
|
||||
return NO;
|
||||
break;
|
||||
default:
|
||||
[self addErrorWithCode:EPARSE description: @"Unrecognised leading character"];
|
||||
return NO;
|
||||
break;
|
||||
}
|
||||
|
||||
NSAssert(0, @"Should never get here");
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfTrue:(NSNumber **)o
|
||||
{
|
||||
if (!strncmp(c, "rue", 3)) {
|
||||
c += 3;
|
||||
*o = [NSNumber numberWithBool:YES];
|
||||
return YES;
|
||||
}
|
||||
[self addErrorWithCode:EPARSE description:@"Expected 'true'"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfFalse:(NSNumber **)o
|
||||
{
|
||||
if (!strncmp(c, "alse", 4)) {
|
||||
c += 4;
|
||||
*o = [NSNumber numberWithBool:NO];
|
||||
return YES;
|
||||
}
|
||||
[self addErrorWithCode:EPARSE description: @"Expected 'false'"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfNull:(NSNull **)o {
|
||||
if (!strncmp(c, "ull", 3)) {
|
||||
c += 3;
|
||||
*o = [NSNull null];
|
||||
return YES;
|
||||
}
|
||||
[self addErrorWithCode:EPARSE description: @"Expected 'null'"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfArray:(NSMutableArray **)o {
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
*o = [NSMutableArray arrayWithCapacity:8];
|
||||
|
||||
for (; *c ;) {
|
||||
id v;
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == ']' && c++) {
|
||||
depth--;
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (![self scanValue:&v]) {
|
||||
[self addErrorWithCode:EPARSE description:@"Expected value while parsing array"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
[*o addObject:v];
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == ',' && c++) {
|
||||
skipWhitespace(c);
|
||||
if (*c == ']') {
|
||||
[self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in array"];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self addErrorWithCode:EEOF description: @"End of input while parsing array"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfDictionary:(NSMutableDictionary **)o
|
||||
{
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
*o = [NSMutableDictionary dictionaryWithCapacity:7];
|
||||
|
||||
for (; *c ;) {
|
||||
id k, v;
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == '}' && c++) {
|
||||
depth--;
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (!(*c == '\"' && c++ && [self scanRestOfString:&k])) {
|
||||
[self addErrorWithCode:EPARSE description: @"Object key string expected"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c != ':') {
|
||||
[self addErrorWithCode:EPARSE description: @"Expected ':' separating key and value"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
c++;
|
||||
if (![self scanValue:&v]) {
|
||||
NSString *string = [NSString stringWithFormat:@"Object value expected for key: %@", k];
|
||||
[self addErrorWithCode:EPARSE description: string];
|
||||
return NO;
|
||||
}
|
||||
|
||||
[*o setObject:v forKey:k];
|
||||
|
||||
skipWhitespace(c);
|
||||
if (*c == ',' && c++) {
|
||||
skipWhitespace(c);
|
||||
if (*c == '}') {
|
||||
[self addErrorWithCode:ETRAILCOMMA description: @"Trailing comma disallowed in object"];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[self addErrorWithCode:EEOF description: @"End of input while parsing object"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanRestOfString:(NSMutableString **)o
|
||||
{
|
||||
*o = [NSMutableString stringWithCapacity:16];
|
||||
do {
|
||||
// First see if there's a portion we can grab in one go.
|
||||
// Doing this caused a massive speedup on the long string.
|
||||
size_t len = strcspn(c, ctrl);
|
||||
if (len) {
|
||||
// check for
|
||||
id t = [[NSString alloc] initWithBytesNoCopy:(char*)c
|
||||
length:len
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
if (t) {
|
||||
[*o appendString:t];
|
||||
[t release];
|
||||
c += len;
|
||||
}
|
||||
}
|
||||
|
||||
if (*c == '"') {
|
||||
c++;
|
||||
return YES;
|
||||
|
||||
} else if (*c == '\\') {
|
||||
unichar uc = *++c;
|
||||
switch (uc) {
|
||||
case '\\':
|
||||
case '/':
|
||||
case '"':
|
||||
break;
|
||||
|
||||
case 'b': uc = '\b'; break;
|
||||
case 'n': uc = '\n'; break;
|
||||
case 'r': uc = '\r'; break;
|
||||
case 't': uc = '\t'; break;
|
||||
case 'f': uc = '\f'; break;
|
||||
|
||||
case 'u':
|
||||
c++;
|
||||
if (![self scanUnicodeChar:&uc]) {
|
||||
[self addErrorWithCode:EUNICODE description: @"Broken unicode character"];
|
||||
return NO;
|
||||
}
|
||||
c--; // hack.
|
||||
break;
|
||||
default:
|
||||
[self addErrorWithCode:EESCAPE description: [NSString stringWithFormat:@"Illegal escape sequence '0x%x'", uc]];
|
||||
return NO;
|
||||
break;
|
||||
}
|
||||
CFStringAppendCharacters((CFMutableStringRef)*o, &uc, 1);
|
||||
c++;
|
||||
|
||||
} else if (*c < 0x20) {
|
||||
[self addErrorWithCode:ECTRL description: [NSString stringWithFormat:@"Unescaped control character '0x%x'", *c]];
|
||||
return NO;
|
||||
|
||||
} else {
|
||||
// CCLOG(@"should not be able to get here");
|
||||
}
|
||||
} while (*c);
|
||||
|
||||
[self addErrorWithCode:EEOF description:@"Unexpected EOF while parsing string"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanUnicodeChar:(unichar *)x
|
||||
{
|
||||
unichar hi, lo;
|
||||
|
||||
if (![self scanHexQuad:&hi]) {
|
||||
[self addErrorWithCode:EUNICODE description: @"Missing hex quad"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (hi >= 0xd800) { // high surrogate char?
|
||||
if (hi < 0xdc00) { // yes - expect a low char
|
||||
|
||||
if (!(*c == '\\' && ++c && *c == 'u' && ++c && [self scanHexQuad:&lo])) {
|
||||
[self addErrorWithCode:EUNICODE description: @"Missing low character in surrogate pair"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (lo < 0xdc00 || lo >= 0xdfff) {
|
||||
[self addErrorWithCode:EUNICODE description:@"Invalid low surrogate char"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
hi = (hi - 0xd800) * 0x400 + (lo - 0xdc00) + 0x10000;
|
||||
|
||||
} else if (hi < 0xe000) {
|
||||
[self addErrorWithCode:EUNICODE description:@"Invalid high character in surrogate pair"];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
*x = hi;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)scanHexQuad:(unichar *)x
|
||||
{
|
||||
*x = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
unichar uc = *c;
|
||||
c++;
|
||||
int d = (uc >= '0' && uc <= '9')
|
||||
? uc - '0' : (uc >= 'a' && uc <= 'f')
|
||||
? (uc - 'a' + 10) : (uc >= 'A' && uc <= 'F')
|
||||
? (uc - 'A' + 10) : -1;
|
||||
if (d == -1) {
|
||||
[self addErrorWithCode:EUNICODE description:@"Missing hex digit in quad"];
|
||||
return NO;
|
||||
}
|
||||
*x *= 16;
|
||||
*x += d;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)scanNumber:(NSNumber **)o
|
||||
{
|
||||
const char *ns = c;
|
||||
|
||||
// The logic to test for validity of the number formatting is relicensed
|
||||
// from JSON::XS with permission from its author Marc Lehmann.
|
||||
// (Available at the CPAN: http://search.cpan.org/dist/JSON-XS/ .)
|
||||
|
||||
if ('-' == *c)
|
||||
c++;
|
||||
|
||||
if ('0' == *c && c++) {
|
||||
if (isdigit(*c)) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"Leading 0 disallowed in number"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
} else if (!isdigit(*c) && c != ns) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"No digits after initial minus"];
|
||||
return NO;
|
||||
|
||||
} else {
|
||||
skipDigits(c);
|
||||
}
|
||||
|
||||
// Fractional part
|
||||
if ('.' == *c && c++) {
|
||||
|
||||
if (!isdigit(*c)) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"No digits after decimal point"];
|
||||
return NO;
|
||||
}
|
||||
skipDigits(c);
|
||||
}
|
||||
|
||||
// Exponential part
|
||||
if ('e' == *c || 'E' == *c) {
|
||||
c++;
|
||||
|
||||
if ('-' == *c || '+' == *c)
|
||||
c++;
|
||||
|
||||
if (!isdigit(*c)) {
|
||||
[self addErrorWithCode:EPARSENUM description: @"No digits after exponent"];
|
||||
return NO;
|
||||
}
|
||||
skipDigits(c);
|
||||
}
|
||||
|
||||
id str = [[NSString alloc] initWithBytesNoCopy:(char*)ns
|
||||
length:c - ns
|
||||
encoding:NSUTF8StringEncoding
|
||||
freeWhenDone:NO];
|
||||
[str autorelease];
|
||||
if (str && (*o = [NSDecimalNumber decimalNumberWithString:str]))
|
||||
return YES;
|
||||
|
||||
[self addErrorWithCode:EPARSENUM description: @"Failed creating decimal instance"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)scanIsAtEnd
|
||||
{
|
||||
skipWhitespace(c);
|
||||
return !*c;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
129
msext/Class/SGGateway/JSON/SBJsonWriter.h
Executable file
129
msext/Class/SGGateway/JSON/SBJsonWriter.h
Executable file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonBase.h"
|
||||
|
||||
/**
|
||||
@brief Options for the writer class.
|
||||
|
||||
This exists so the SBJSON facade can implement the options in the writer without having to re-declare them.
|
||||
*/
|
||||
@protocol SBJsonWriter
|
||||
|
||||
/**
|
||||
@brief Whether we are generating human-readable (multiline) JSON.
|
||||
|
||||
Set whether or not to generate human-readable JSON. The default is NO, which produces
|
||||
JSON without any whitespace. (Except inside strings.) If set to YES, generates human-readable
|
||||
JSON with linebreaks after each array value and dictionary key/value pair, indented two
|
||||
spaces per nesting level.
|
||||
*/
|
||||
@property BOOL humanReadable;
|
||||
|
||||
/**
|
||||
@brief Whether or not to sort the dictionary keys in the output.
|
||||
|
||||
If this is set to YES, the dictionary keys in the JSON output will be in sorted order.
|
||||
(This is useful if you need to compare two structures, for example.) The default is NO.
|
||||
*/
|
||||
@property BOOL sortKeys;
|
||||
|
||||
/**
|
||||
@brief Return JSON representation (or fragment) for the given object.
|
||||
|
||||
Returns a string containing JSON representation of the passed in value, or nil on error.
|
||||
If nil is returned and @p error is not NULL, @p *error can be interrogated to find the cause of the error.
|
||||
|
||||
@param value any instance that can be represented as a JSON fragment
|
||||
|
||||
*/
|
||||
- (NSString*)stringWithObject:(id)value;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/**
|
||||
@brief The JSON writer class.
|
||||
|
||||
Objective-C types are mapped to JSON types in the following way:
|
||||
|
||||
@li NSNull -> Null
|
||||
@li NSString -> String
|
||||
@li NSArray -> Array
|
||||
@li NSDictionary -> Object
|
||||
@li NSNumber (-initWithBool:) -> Boolean
|
||||
@li NSNumber -> Number
|
||||
|
||||
In JSON the keys of an object must be strings. NSDictionary keys need
|
||||
not be, but attempting to convert an NSDictionary with non-string keys
|
||||
into JSON will throw an exception.
|
||||
|
||||
NSNumber instances created with the +initWithBool: method are
|
||||
converted into the JSON boolean "true" and "false" values, and vice
|
||||
versa. Any other NSNumber instances are converted to a JSON number the
|
||||
way you would expect.
|
||||
|
||||
*/
|
||||
@interface SBJsonWriter : SBJsonBase <SBJsonWriter> {
|
||||
|
||||
@private
|
||||
BOOL sortKeys, humanReadable;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
// don't use - exists for backwards compatibility. Will be removed in 2.3.
|
||||
@interface SBJsonWriter (Private)
|
||||
- (NSString*)stringWithFragment:(id)value;
|
||||
@end
|
||||
|
||||
/**
|
||||
@brief Allows generation of JSON for otherwise unsupported classes.
|
||||
|
||||
If you have a custom class that you want to create a JSON representation for you can implement
|
||||
this method in your class. It should return a representation of your object defined
|
||||
in terms of objects that can be translated into JSON. For example, a Person
|
||||
object might implement it like this:
|
||||
|
||||
@code
|
||||
- (id)jsonProxyObject {
|
||||
return [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
name, @"name",
|
||||
phone, @"phone",
|
||||
email, @"email",
|
||||
nil];
|
||||
}
|
||||
@endcode
|
||||
|
||||
*/
|
||||
@interface NSObject (SBProxyForJson)
|
||||
- (id)proxyForJson;
|
||||
@end
|
||||
|
||||
237
msext/Class/SGGateway/JSON/SBJsonWriter.m
Executable file
237
msext/Class/SGGateway/JSON/SBJsonWriter.m
Executable file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
Copyright (C) 2009 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 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 OWNER 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 "SBJsonWriter.h"
|
||||
|
||||
@interface SBJsonWriter ()
|
||||
|
||||
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json;
|
||||
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json;
|
||||
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json;
|
||||
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json;
|
||||
|
||||
- (NSString*)indent;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SBJsonWriter
|
||||
|
||||
static NSMutableCharacterSet *kEscapeChars;
|
||||
|
||||
+ (void)initialize {
|
||||
kEscapeChars = [[NSMutableCharacterSet characterSetWithRange: NSMakeRange(0,32)] retain];
|
||||
[kEscapeChars addCharactersInString: @"\"\\"];
|
||||
}
|
||||
|
||||
|
||||
@synthesize sortKeys;
|
||||
@synthesize humanReadable;
|
||||
|
||||
/**
|
||||
@deprecated This exists in order to provide fragment support in older APIs in one more version.
|
||||
It should be removed in the next major version.
|
||||
*/
|
||||
- (NSString*)stringWithFragment:(id)value {
|
||||
[self clearErrorTrace];
|
||||
depth = 0;
|
||||
NSMutableString *json = [NSMutableString stringWithCapacity:128];
|
||||
|
||||
if ([self appendValue:value into:json])
|
||||
return json;
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (NSString*)stringWithObject:(id)value {
|
||||
|
||||
if ([value isKindOfClass:[NSDictionary class]] || [value isKindOfClass:[NSArray class]]) {
|
||||
return [self stringWithFragment:value];
|
||||
}
|
||||
|
||||
if ([value respondsToSelector:@selector(proxyForJson)]) {
|
||||
NSString *tmp = [self stringWithObject:[value proxyForJson]];
|
||||
if (tmp)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
[self clearErrorTrace];
|
||||
[self addErrorWithCode:EFRAGMENT description:@"Not valid type for JSON"];
|
||||
return nil;
|
||||
}
|
||||
|
||||
|
||||
- (NSString*)indent {
|
||||
return [@"\n" stringByPaddingToLength:1 + 2 * depth withString:@" " startingAtIndex:0];
|
||||
}
|
||||
|
||||
- (BOOL)appendValue:(id)fragment into:(NSMutableString*)json {
|
||||
if ([fragment isKindOfClass:[NSDictionary class]]) {
|
||||
if (![self appendDictionary:fragment into:json])
|
||||
return NO;
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSArray class]]) {
|
||||
if (![self appendArray:fragment into:json])
|
||||
return NO;
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSString class]]) {
|
||||
if (![self appendString:fragment into:json])
|
||||
return NO;
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSNumber class]]) {
|
||||
if ('c' == *[fragment objCType])
|
||||
[json appendString:[fragment boolValue] ? @"true" : @"false"];
|
||||
else
|
||||
[json appendString:[fragment stringValue]];
|
||||
|
||||
} else if ([fragment isKindOfClass:[NSNull class]]) {
|
||||
[json appendString:@"null"];
|
||||
} else if ([fragment respondsToSelector:@selector(proxyForJson)]) {
|
||||
[self appendValue:[fragment proxyForJson] into:json];
|
||||
|
||||
} else {
|
||||
[self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"JSON serialisation not supported for %@", [fragment class]]];
|
||||
return NO;
|
||||
}
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)appendArray:(NSArray*)fragment into:(NSMutableString*)json {
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
[json appendString:@"["];
|
||||
|
||||
BOOL addComma = NO;
|
||||
for (id value in fragment) {
|
||||
if (addComma)
|
||||
[json appendString:@","];
|
||||
else
|
||||
addComma = YES;
|
||||
|
||||
if ([self humanReadable])
|
||||
[json appendString:[self indent]];
|
||||
|
||||
if (![self appendValue:value into:json]) {
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
depth--;
|
||||
if ([self humanReadable] && [fragment count])
|
||||
[json appendString:[self indent]];
|
||||
[json appendString:@"]"];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)appendDictionary:(NSDictionary*)fragment into:(NSMutableString*)json {
|
||||
if (maxDepth && ++depth > maxDepth) {
|
||||
[self addErrorWithCode:EDEPTH description: @"Nested too deep"];
|
||||
return NO;
|
||||
}
|
||||
[json appendString:@"{"];
|
||||
|
||||
NSString *colon = [self humanReadable] ? @" : " : @":";
|
||||
BOOL addComma = NO;
|
||||
NSArray *keys = [fragment allKeys];
|
||||
if (self.sortKeys)
|
||||
keys = [keys sortedArrayUsingSelector:@selector(compare:)];
|
||||
|
||||
for (id value in keys) {
|
||||
if (addComma)
|
||||
[json appendString:@","];
|
||||
else
|
||||
addComma = YES;
|
||||
|
||||
if ([self humanReadable])
|
||||
[json appendString:[self indent]];
|
||||
|
||||
if (![value isKindOfClass:[NSString class]]) {
|
||||
[self addErrorWithCode:EUNSUPPORTED description: @"JSON object key must be string"];
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (![self appendString:value into:json])
|
||||
return NO;
|
||||
|
||||
[json appendString:colon];
|
||||
if (![self appendValue:[fragment objectForKey:value] into:json]) {
|
||||
[self addErrorWithCode:EUNSUPPORTED description:[NSString stringWithFormat:@"Unsupported value for key %@ in object", value]];
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
depth--;
|
||||
if ([self humanReadable] && [fragment count])
|
||||
[json appendString:[self indent]];
|
||||
[json appendString:@"}"];
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)appendString:(NSString*)fragment into:(NSMutableString*)json {
|
||||
|
||||
[json appendString:@"\""];
|
||||
|
||||
NSRange esc = [fragment rangeOfCharacterFromSet:kEscapeChars];
|
||||
if ( !esc.length ) {
|
||||
// No special chars -- can just add the raw string:
|
||||
[json appendString:fragment];
|
||||
|
||||
} else {
|
||||
NSUInteger length = [fragment length];
|
||||
for (NSUInteger i = 0; i < length; i++) {
|
||||
unichar uc = [fragment characterAtIndex:i];
|
||||
switch (uc) {
|
||||
case '"': [json appendString:@"\\\""]; break;
|
||||
case '\\': [json appendString:@"\\\\"]; break;
|
||||
case '\t': [json appendString:@"\\t"]; break;
|
||||
case '\n': [json appendString:@"\\n"]; break;
|
||||
case '\r': [json appendString:@"\\r"]; break;
|
||||
case '\b': [json appendString:@"\\b"]; break;
|
||||
case '\f': [json appendString:@"\\f"]; break;
|
||||
default:
|
||||
if (uc < 0x20) {
|
||||
[json appendFormat:@"\\u%04x", uc];
|
||||
} else {
|
||||
CFStringAppendCharacters((CFMutableStringRef)json, &uc, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[json appendString:@"\""];
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
15
msext/Class/SGGateway/SGGateway.h
Executable file
15
msext/Class/SGGateway/SGGateway.h
Executable file
@@ -0,0 +1,15 @@
|
||||
//
|
||||
// Gateway.h
|
||||
// PublicFuncClass
|
||||
//
|
||||
// Created by an chen on 12-8-30.
|
||||
// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SGGateway : NSObject
|
||||
+(SGGateway*)defaultGateway;
|
||||
-(void)gateway:(id)mv func:(SEL)returnFunc
|
||||
obj:(NSMutableDictionary*)obj_do obj_post:(NSMutableDictionary*)param_post STR:(NSString*)str HTTPMethod:(NSString*)_method;
|
||||
@end
|
||||
56
msext/Class/SGGateway/SGGateway.m
Executable file
56
msext/Class/SGGateway/SGGateway.m
Executable file
@@ -0,0 +1,56 @@
|
||||
//
|
||||
// Gateway.m
|
||||
// PublicFuncClass
|
||||
//
|
||||
// Created by an chen on 12-8-30.
|
||||
// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SGGateway.h"
|
||||
#import "SGGatewayApi.h"
|
||||
#import "SGDefineInfo.h"
|
||||
@implementation SGGateway
|
||||
static SGGateway* _instanceGateway = nil;
|
||||
/*
|
||||
* 获得本类实例
|
||||
*/
|
||||
+(SGGateway*)defaultGateway
|
||||
{
|
||||
if( _instanceGateway == nil )
|
||||
_instanceGateway = [[SGGateway alloc] init];
|
||||
return _instanceGateway;
|
||||
}
|
||||
/*
|
||||
* 参数:
|
||||
*
|
||||
* mv: 回调的目标类
|
||||
*
|
||||
* returnFunc: 回调的方法
|
||||
*
|
||||
* obj_do: 于后台交互成功后,将信息传回mv类
|
||||
*
|
||||
* param_post: 于后交互的相关参数
|
||||
*
|
||||
* str: url信息
|
||||
*
|
||||
*/
|
||||
-(void)gateway:(id)mv func:(SEL)returnFunc
|
||||
obj:(NSMutableDictionary*)obj_do obj_post:(NSMutableDictionary*)param_post STR:(NSString*)str HTTPMethod:(NSString*)_method
|
||||
{
|
||||
SGGatewayApi* api = [[SGGatewayApi alloc] init];
|
||||
[api gateway:mv func:returnFunc obj_post:obj_do obj_post:param_post STR:str HTTPMethod:_method];
|
||||
SG_RELEASE(api);
|
||||
}
|
||||
|
||||
//使用介绍
|
||||
/*
|
||||
NSMutableDictionary* obj_do = [[NSMutableDictionary alloc] init];
|
||||
NSMutableDictionary* obj_post = [[NSMutableDictionary alloc] init];
|
||||
[obj_post setObject:@"123" forKey:@"i"];
|
||||
[obj_post setObject:@"get_group_pic" forKey:@"t"];
|
||||
[[SGGateway defaultGateway] gateway:self func:@selector(ReturnInfo:) obj:obj_do obj_post:obj_post STR:@"" HTTPMethod:@"Get"];//POST
|
||||
-(void)ReturnInfo:(NSMutableDictionary*)obj_do
|
||||
{
|
||||
}
|
||||
*/
|
||||
@end
|
||||
35
msext/Class/SGGateway/SGGatewayApi.h
Executable file
35
msext/Class/SGGateway/SGGatewayApi.h
Executable file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// GatewayApi.h
|
||||
// PublicFuncClass
|
||||
//
|
||||
// Created by an chen on 12-8-30.
|
||||
// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface SGGatewayApi : NSObject
|
||||
{
|
||||
|
||||
NSString* _act;//事件名
|
||||
id _mvReturn;//需要返回的处理界面
|
||||
SEL _returnFunction;
|
||||
NSString* _mUrl; //调用的url
|
||||
NSMutableData* receivedBufferData;//返回的信息
|
||||
NSMutableDictionary* _objDo;//传递到接口时带的变量,成功后直接返回这个对象
|
||||
NSTimer* _DelayerTimer;
|
||||
BOOL DelayerErro;//通信失败
|
||||
BOOL OnceAlert;
|
||||
}
|
||||
|
||||
@property (readwrite,retain) NSString* _act;
|
||||
@property (readwrite,retain) id _mvReturn;//需要返回的处理界面
|
||||
@property (nonatomic,readwrite) SEL _returnFunction;
|
||||
@property (nonatomic,retain) NSString* _mUrl;
|
||||
@property (nonatomic,retain) NSMutableData* receivedBufferData;//返回的信息
|
||||
@property (nonatomic,retain) NSMutableDictionary* _objDo;
|
||||
|
||||
-(void)gateway:(id)mv func:(SEL)returnFunc obj_post:(NSMutableDictionary*)obj_post obj_post:(NSMutableDictionary*)param_post STR:(NSString*)str HTTPMethod:(NSString*)_method;
|
||||
|
||||
- (NSData*)generateFormDataFromPostDictionary:(NSDictionary*)dict;
|
||||
@end
|
||||
261
msext/Class/SGGateway/SGGatewayApi.m
Executable file
261
msext/Class/SGGateway/SGGatewayApi.m
Executable file
@@ -0,0 +1,261 @@
|
||||
//
|
||||
// GatewayApi.m
|
||||
// PublicFuncClass
|
||||
//
|
||||
// Created by an chen on 12-8-30.
|
||||
// Copyright (c) 2012年 __MyCompanyName__. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* 释放
|
||||
*/
|
||||
#import "SGGatewayApi.h"
|
||||
#import "NSString+SBJSON.h"
|
||||
#import "SBJSON.h"
|
||||
#import "FuncPublic.h"
|
||||
#import "SGGateway.h"
|
||||
#import "SGDefineInfo.h"
|
||||
#import "FuncPublic.h"
|
||||
@implementation SGGatewayApi
|
||||
|
||||
@synthesize _mUrl;
|
||||
@synthesize _mvReturn;
|
||||
@synthesize _returnFunction;
|
||||
@synthesize _act;
|
||||
@synthesize receivedBufferData;//返回的信息
|
||||
@synthesize _objDo;
|
||||
-(id)init
|
||||
{
|
||||
if((self=[super init]))
|
||||
{
|
||||
receivedBufferData = [[NSMutableData alloc]init];
|
||||
//(**)
|
||||
_objDo = [[NSMutableDictionary alloc]init];
|
||||
_act = [[NSString alloc] initWithString:@""];
|
||||
DelayerErro = NO;
|
||||
OnceAlert=YES;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
-(void)dealloc
|
||||
{
|
||||
NSLog(@"释放:%@",_act);
|
||||
SG_RELEASE(receivedBufferData);
|
||||
SG_RELEASE(_mUrl);
|
||||
SG_RELEASE(_act);
|
||||
SG_RELEASE(_objDo);
|
||||
[super dealloc];
|
||||
}
|
||||
/*
|
||||
* 延时处理
|
||||
*/
|
||||
-(void)delayer
|
||||
{
|
||||
[_DelayerTimer invalidate];
|
||||
[[FuncPublic SharedFuncPublic] StopActivityAnimation];
|
||||
NSLog(@"通信失败:%@",_act);
|
||||
if (OnceAlert) {
|
||||
|
||||
// OnceAlert=NO;
|
||||
// [self performSelector:@selector(ComeBack) withObject:nil afterDelay:50.0f];
|
||||
// UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"网络不可用"
|
||||
// message:@"无法与服务器通讯,请连接到移动数据网络或者WIFI"
|
||||
// delegate:self
|
||||
// cancelButtonTitle:@"确定"
|
||||
// otherButtonTitles:nil, nil];
|
||||
// [alert show];
|
||||
// [alert release];
|
||||
[FuncPublic ShowAlert:@"无法与服务器通讯,请连接到移动数据网络或者WIFI" title:@"网络不可用" viewController:nil];
|
||||
}
|
||||
|
||||
//[_mvReturn performSelector:_returnFunction withObject:nil];
|
||||
DelayerErro = YES;
|
||||
}
|
||||
-(void)ComeBack
|
||||
{
|
||||
OnceAlert=YES;
|
||||
}
|
||||
/*
|
||||
* 参数:
|
||||
*
|
||||
* mv: 回调的目标类
|
||||
*
|
||||
* returnFunc: 回调的方法
|
||||
*
|
||||
* obj_do: 于后台交互成功后,将信息传回mv类
|
||||
*
|
||||
* param_post: 于后交互的相关参数
|
||||
*
|
||||
* str: url信息
|
||||
*
|
||||
*/
|
||||
-(void)gateway:(id)mv func:(SEL)returnFunc obj_post:(NSMutableDictionary*)obj_post obj_post:(NSMutableDictionary*)param_post STR:(NSString*)str HTTPMethod:(NSString*)_method{
|
||||
/*
|
||||
* 延时处理,如果通信超过指定时间,则结束通信
|
||||
*/
|
||||
if (![str isEqualToString:@"UpdateAPNSDevice.aspx"]) {
|
||||
[[FuncPublic SharedFuncPublic] StartActivityAnimation:mv];
|
||||
}
|
||||
|
||||
_DelayerTimer = [NSTimer scheduledTimerWithTimeInterval:GATEWAY_DELAYER target:self selector:@selector(delayer) userInfo:nil repeats:NO];
|
||||
|
||||
_mvReturn = mv;
|
||||
_returnFunction = returnFunc;
|
||||
_objDo = obj_post;
|
||||
|
||||
if( ![[param_post objectForKey:@"t"] isEqual:@""] )//关键联接名
|
||||
{
|
||||
if( [param_post objectForKey:@"t"] == nil )
|
||||
{
|
||||
_act = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
_act = [param_post objectForKey:@"t"];
|
||||
}
|
||||
}
|
||||
_mUrl = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%@%@",SERVER,str]];
|
||||
|
||||
/*
|
||||
* 增加一些固传参数 code start
|
||||
*/
|
||||
if( [param_post objectForKey:@"code"] != nil )
|
||||
{
|
||||
NSArray *array = [param_post allKeys];//[[param_post allKeys]sortedArrayUsingSelector: @selector(compare:)];
|
||||
NSString* post = @"";
|
||||
for(int i = 0; i<[array count]; i++){
|
||||
if( [[param_post objectForKey:[array objectAtIndex:i]] isEqualToString:@"nn"])
|
||||
continue;
|
||||
post = [post stringByAppendingString:[param_post objectForKey:[array objectAtIndex:i]]];
|
||||
}
|
||||
post = [post stringByAppendingFormat:@"WERTY#$&(HJKfghjWERTYUIFGJFGHadf2222"];
|
||||
post = [FuncPublic md5:post];
|
||||
[param_post setObject:post forKey:@"code"];
|
||||
}
|
||||
/*
|
||||
* code end
|
||||
*/
|
||||
//生成post的数据
|
||||
NSData *postData = [self generateFormDataFromPostDictionary:param_post];//将传入的单独obj_post中的key使用=和&组合
|
||||
|
||||
|
||||
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; //post的长度
|
||||
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
|
||||
|
||||
[request setHTTPMethod:@"POST"]; //设置使用的方法
|
||||
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];//设置数据的长度
|
||||
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];//数据的类型
|
||||
[request setHTTPBody:postData]; //设置发送的数据
|
||||
|
||||
NSString* post_string = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];//将nsdata转为encoding
|
||||
if( [_method isEqualToString:@"POST"] )
|
||||
{
|
||||
[request setURL:[NSURL URLWithString:_mUrl]];
|
||||
}else if( [_method isEqualToString:@"POSTtwo"] )
|
||||
{
|
||||
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@%@",SERVERTwo,str]]];
|
||||
|
||||
}else
|
||||
{
|
||||
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?%@",_mUrl,post_string ]]]; //设置调用的url
|
||||
}
|
||||
NSLog(@"%@",[NSString stringWithFormat:@"%@?%@",_mUrl,post_string ]);
|
||||
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self]; //开始连接后台
|
||||
|
||||
if (conn) {
|
||||
|
||||
} else {
|
||||
|
||||
}
|
||||
SG_RELEASE(post_string);
|
||||
[param_post removeAllObjects];
|
||||
SG_RELEASE(param_post);
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)conn didReceiveResponse:(NSURLResponse *)res {
|
||||
[receivedBufferData setLength:0];
|
||||
}
|
||||
|
||||
|
||||
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)receivedData {
|
||||
[receivedBufferData appendData:receivedData]; //添加记录的资料
|
||||
}
|
||||
|
||||
|
||||
- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error {
|
||||
|
||||
}
|
||||
-(NSString *)HandelData:(NSString *)str_
|
||||
{
|
||||
NSString *string=nil;
|
||||
//ValidateUserIDAndPassword.aspx UpdateAPNSDevice.aspx InsertBookComment.aspx
|
||||
if ([_act isEqualToString:@"InsertSuggestInfo.aspx"]||[_act isEqualToString:@"UpdateAPNSDevice.aspx"]||[_act isEqualToString:@"InsertBookComment.aspx"]) {
|
||||
string=[NSString stringWithFormat:@"{\"data\":[{\"result\":%@}]}",str_];
|
||||
return string;
|
||||
}
|
||||
string=str_;
|
||||
|
||||
return string;
|
||||
}
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)conn {
|
||||
NSLog(@"apiReturnOk:%@",_act);
|
||||
if( DelayerErro ) return;
|
||||
[_DelayerTimer invalidate];
|
||||
NSString* stra = [[NSString alloc] initWithData:receivedBufferData encoding:NSUTF8StringEncoding]; //转换信息
|
||||
//去除两边空格
|
||||
NSString* str = [[NSString alloc]initWithFormat:@"%@",[stra stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
|
||||
|
||||
SG_RELEASE(stra);
|
||||
if ([str isEqualToString: @""] == YES) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(1){
|
||||
NSLog(@"[%@]",str);
|
||||
}
|
||||
NSString *handleStr=[self HandelData:str];
|
||||
NSMutableDictionary * obj_return = [handleStr JSONValue];//使用js解压
|
||||
if( obj_return == nil )
|
||||
{
|
||||
[[FuncPublic SharedFuncPublic] StopActivityAnimation];//需要于funcpublic共用
|
||||
// [FuncPublic ShowAlert:@"Api错误!"];
|
||||
// [FuncPublic ShowAlert:@"没有数据!"];
|
||||
[FuncPublic ShowAlert:@"没有数据!" title:nil viewController:nil];
|
||||
return;
|
||||
}
|
||||
NSLog(@"jsonDecode完成:%@",_act);
|
||||
|
||||
|
||||
[_objDo setObject:obj_return forKey:@"apiReturnData"];//将当前返回的信息和之前传入的参数,整合
|
||||
NSLog(@"开始回调:%@",_act);
|
||||
[_mvReturn performSelector:_returnFunction withObject:_objDo];//传到想应的方法中 _objDo:之前如果有传参进来,一并返回
|
||||
SG_RELEASE(str);
|
||||
NSLog(@"接口%@完成",_act);
|
||||
[[FuncPublic SharedFuncPublic] StopActivityAnimation];
|
||||
}
|
||||
- (NSData*)generateFormDataFromPostDictionary:(NSDictionary*)dict
|
||||
{
|
||||
NSArray* keys = [dict allKeys];
|
||||
NSMutableData* result = [NSMutableData data];
|
||||
|
||||
for (int i = 0; i < [keys count]; i++)
|
||||
{
|
||||
id value = [dict valueForKey: [keys objectAtIndex:i]];
|
||||
if(i > 0){
|
||||
[result appendData:[@"&" dataUsingEncoding:NSUTF8StringEncoding]];//NSASCIIStringEncoding
|
||||
}
|
||||
[result appendData:[[NSString stringWithFormat:@"%@" ,[keys objectAtIndex:i]] dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
|
||||
[result appendData:[@"=" dataUsingEncoding:NSUTF8StringEncoding]];
|
||||
if ([value isKindOfClass:[NSData class]])
|
||||
{
|
||||
[result appendData:value];
|
||||
}
|
||||
else {
|
||||
[result appendData:DATA(value)];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@end
|
||||
Reference in New Issue
Block a user