adding adNetwork SDKs for AdWhirl and AdMob

This commit is contained in:
techdragon.nguyen@gmail.com
2011-12-15 11:18:37 +00:00
parent dc7d52c48c
commit 9c10f47daa
160 changed files with 23482 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
//
// CJSONDataSerializer.h
// TouchCode
//
// Created by Jonathan Wight on 12/07/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@interface CJSONDataSerializer : NSObject {
}
+ (id)serializer;
/// Take any JSON compatible object (generally NSNull, NSNumber, NSString, NSArray and NSDictionary) and produce an NSData containing the serialized JSON.
- (NSData *)serializeObject:(id)inObject;
- (NSData *)serializeNull:(NSNull *)inNull;
- (NSData *)serializeNumber:(NSNumber *)inNumber;
- (NSData *)serializeString:(NSString *)inString;
- (NSData *)serializeArray:(NSArray *)inArray;
- (NSData *)serializeDictionary:(NSDictionary *)inDictionary;
@end

View File

@@ -0,0 +1,225 @@
//
// CJSONDataSerializer.m
// TouchCode
//
// Created by Jonathan Wight on 12/07/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import "CJSONDataSerializer.h"
#import "CSerializedJSONData.h"
static NSData *kNULL = NULL;
static NSData *kFalse = NULL;
static NSData *kTrue = NULL;
@implementation CJSONDataSerializer
+ (void)initialize
{
NSAutoreleasePool *thePool = [[NSAutoreleasePool alloc] init];
@synchronized(@"CJSONDataSerializer")
{
if (kNULL == NULL)
kNULL = [[NSData alloc] initWithBytesNoCopy:"null" length:4 freeWhenDone:NO];
if (kFalse == NULL)
kFalse = [[NSData alloc] initWithBytesNoCopy:"false" length:5 freeWhenDone:NO];
if (kTrue == NULL)
kTrue = [[NSData alloc] initWithBytesNoCopy:"true" length:4 freeWhenDone:NO];
}
[thePool release];
}
+ (id)serializer
{
return([[[self alloc] init] autorelease]);
}
- (NSData *)serializeObject:(id)inObject;
{
NSData *theResult = NULL;
if ([inObject isKindOfClass:[NSNull class]])
{
theResult = [self serializeNull:inObject];
}
else if ([inObject isKindOfClass:[NSNumber class]])
{
theResult = [self serializeNumber:inObject];
}
else if ([inObject isKindOfClass:[NSString class]])
{
theResult = [self serializeString:inObject];
}
else if ([inObject isKindOfClass:[NSArray class]])
{
theResult = [self serializeArray:inObject];
}
else if ([inObject isKindOfClass:[NSDictionary class]])
{
theResult = [self serializeDictionary:inObject];
}
else if ([inObject isKindOfClass:[NSData class]])
{
NSString *theString = [[[NSString alloc] initWithData:inObject encoding:NSUTF8StringEncoding] autorelease];
theResult = [self serializeString:theString];
}
else if ([inObject isKindOfClass:[CSerializedJSONData class]])
{
theResult = [inObject data];
}
else
{
[NSException raise:NSGenericException format:@"Cannot serialize data of type '%@'", NSStringFromClass([inObject class])];
}
if (theResult == NULL)
[NSException raise:NSGenericException format:@"Could not serialize object '%@'", inObject];
return(theResult);
}
- (NSData *)serializeNull:(NSNull *)inNull
{
#pragma unused (inNull)
return(kNULL);
}
- (NSData *)serializeNumber:(NSNumber *)inNumber
{
NSData *theResult = NULL;
switch (CFNumberGetType((CFNumberRef)inNumber))
{
case kCFNumberCharType:
{
int theValue = [inNumber intValue];
if (theValue == 0)
theResult = kFalse;
else if (theValue == 1)
theResult = kTrue;
else
theResult = [[inNumber stringValue] dataUsingEncoding:NSASCIIStringEncoding];
}
break;
case kCFNumberFloat32Type:
case kCFNumberFloat64Type:
case kCFNumberFloatType:
case kCFNumberDoubleType:
case kCFNumberSInt8Type:
case kCFNumberSInt16Type:
case kCFNumberSInt32Type:
case kCFNumberSInt64Type:
case kCFNumberShortType:
case kCFNumberIntType:
case kCFNumberLongType:
case kCFNumberLongLongType:
case kCFNumberCFIndexType:
default:
theResult = [[inNumber stringValue] dataUsingEncoding:NSASCIIStringEncoding];
break;
}
return(theResult);
}
- (NSData *)serializeString:(NSString *)inString
{
NSMutableString *theMutableCopy = [[inString mutableCopy] autorelease];
[theMutableCopy replaceOccurrencesOfString:@"\\" withString:@"\\\\" options:0 range:NSMakeRange(0, [theMutableCopy length])];
[theMutableCopy replaceOccurrencesOfString:@"\"" withString:@"\\\"" options:0 range:NSMakeRange(0, [theMutableCopy length])];
[theMutableCopy replaceOccurrencesOfString:@"/" withString:@"\\/" options:0 range:NSMakeRange(0, [theMutableCopy length])];
[theMutableCopy replaceOccurrencesOfString:@"\b" withString:@"\\b" options:0 range:NSMakeRange(0, [theMutableCopy length])];
[theMutableCopy replaceOccurrencesOfString:@"\f" withString:@"\\f" options:0 range:NSMakeRange(0, [theMutableCopy length])];
[theMutableCopy replaceOccurrencesOfString:@"\n" withString:@"\\n" options:0 range:NSMakeRange(0, [theMutableCopy length])];
[theMutableCopy replaceOccurrencesOfString:@"\r" withString:@"\\r" options:0 range:NSMakeRange(0, [theMutableCopy length])];
[theMutableCopy replaceOccurrencesOfString:@"\t" withString:@"\\t" options:0 range:NSMakeRange(0, [theMutableCopy length])];
/*
case 'u':
{
theCharacter = 0;
int theShift;
for (theShift = 12; theShift >= 0; theShift -= 4)
{
int theDigit = HexToInt([self scanCharacter]);
if (theDigit == -1)
{
[self setScanLocation:theScanLocation];
return(NO);
}
theCharacter |= (theDigit << theShift);
}
}
*/
return([[NSString stringWithFormat:@"\"%@\"", theMutableCopy] dataUsingEncoding:NSUTF8StringEncoding]);
}
- (NSData *)serializeArray:(NSArray *)inArray
{
NSMutableData *theData = [NSMutableData data];
[theData appendBytes:"[" length:1];
NSEnumerator *theEnumerator = [inArray objectEnumerator];
id theValue = NULL;
NSUInteger i = 0;
while ((theValue = [theEnumerator nextObject]) != NULL)
{
[theData appendData:[self serializeObject:theValue]];
if (++i < [inArray count])
[theData appendBytes:"," length:1];
}
[theData appendBytes:"]" length:1];
return(theData);
}
- (NSData *)serializeDictionary:(NSDictionary *)inDictionary
{
NSMutableData *theData = [NSMutableData data];
[theData appendBytes:"{" length:1];
NSArray *theKeys = [inDictionary allKeys];
NSEnumerator *theEnumerator = [theKeys objectEnumerator];
NSString *theKey = NULL;
while ((theKey = [theEnumerator nextObject]) != NULL)
{
id theValue = [inDictionary objectForKey:theKey];
[theData appendData:[self serializeString:theKey]];
[theData appendBytes:":" length:1];
[theData appendData:[self serializeObject:theValue]];
if (theKey != [theKeys lastObject])
[theData appendData:[@"," dataUsingEncoding:NSASCIIStringEncoding]];
}
[theData appendBytes:"}" length:1];
return(theData);
}
@end

View File

@@ -0,0 +1,45 @@
//
// CJSONDeserializer.h
// TouchCode
//
// Created by Jonathan Wight on 12/15/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
extern NSString *const kJSONDeserializerErrorDomain /* = @"CJSONDeserializerErrorDomain" */;
@interface CJSONDeserializer : NSObject {
}
+ (id)deserializer;
- (id)deserialize:(NSData *)inData error:(NSError **)outError;
- (id)deserializeAsDictionary:(NSData *)inData error:(NSError **)outError;
- (id)deserializeAsArray:(NSData *)inData error:(NSError **)outError;
@end

View File

@@ -0,0 +1,95 @@
//
// CJSONDeserializer.m
// TouchCode
//
// Created by Jonathan Wight on 12/15/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import "CJSONDeserializer.h"
#import "CJSONScanner.h"
#import "CDataScanner.h"
NSString *const kJSONDeserializerErrorDomain = @"CJSONDeserializerErrorDomain";
@implementation CJSONDeserializer
+ (id)deserializer
{
return([[[self alloc] init] autorelease]);
}
- (id)deserialize:(NSData *)inData error:(NSError **)outError
{
if (inData == NULL || [inData length] == 0)
{
if (outError)
*outError = [NSError errorWithDomain:kJSONDeserializerErrorDomain code:-1 userInfo:NULL];
return(NULL);
}
CJSONScanner *theScanner = [CJSONScanner scannerWithData:inData];
id theObject = NULL;
if ([theScanner scanJSONObject:&theObject error:outError] == YES)
return(theObject);
else
return(NULL);
}
- (id)deserializeAsDictionary:(NSData *)inData error:(NSError **)outError;
{
if (inData == NULL || [inData length] == 0)
{
if (outError)
*outError = [NSError errorWithDomain:kJSONDeserializerErrorDomain code:-1 userInfo:NULL];
return(NULL);
}
CJSONScanner *theScanner = [CJSONScanner scannerWithData:inData];
NSDictionary *theDictionary = NULL;
if ([theScanner scanJSONDictionary:&theDictionary error:outError] == YES)
return(theDictionary);
else
return(NULL);
}
- (id)deserializeAsArray:(NSData *)inData error:(NSError **)outError;
{
if (inData == NULL || [inData length] == 0)
{
if (outError)
*outError = [NSError errorWithDomain:kJSONDeserializerErrorDomain code:-1 userInfo:NULL];
return(NULL);
}
CJSONScanner *theScanner = [CJSONScanner scannerWithData:inData];
NSArray *theArray = NULL;
if ([theScanner scanJSONArray:&theArray error:outError] == YES)
return(theArray);
else
return(NULL);
}
@end

View File

@@ -0,0 +1,44 @@
//
// CJSONScanner.h
// TouchCode
//
// Created by Jonathan Wight on 12/07/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import "CDataScanner.h"
/// CDataScanner subclass that understands JSON syntax natively. You should generally use CJSONDeserializer instead of this class. (TODO - this could have been a category?)
@interface CJSONScanner : CDataScanner {
}
- (BOOL)scanJSONObject:(id *)outObject error:(NSError **)outError;
- (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outError;
- (BOOL)scanJSONArray:(NSArray **)outArray error:(NSError **)outError;
- (BOOL)scanJSONStringConstant:(NSString **)outStringConstant error:(NSError **)outError;
- (BOOL)scanJSONNumberConstant:(NSNumber **)outNumberConstant error:(NSError **)outError;
@end
extern NSString *const kJSONScannerErrorDomain /* = @"CJSONScannerErrorDomain" */;

View File

@@ -0,0 +1,539 @@
//
// CJSONScanner.m
// TouchCode
//
// Created by Jonathan Wight on 12/07/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import "CJSONScanner.h"
#import "NSCharacterSet_Extensions.h"
#import "CDataScanner_Extensions.h"
#if !defined(TREAT_COMMENTS_AS_WHITESPACE)
#define TREAT_COMMENTS_AS_WHITESPACE 0
#endif // !defined(TREAT_COMMENTS_AS_WHITESPACE)
NSString *const kJSONScannerErrorDomain = @"CJSONScannerErrorDomain";
inline static int HexToInt(char inCharacter)
{
int theValues[] = { 0x0 /* 48 '0' */, 0x1 /* 49 '1' */, 0x2 /* 50 '2' */, 0x3 /* 51 '3' */, 0x4 /* 52 '4' */, 0x5 /* 53 '5' */, 0x6 /* 54 '6' */, 0x7 /* 55 '7' */, 0x8 /* 56 '8' */, 0x9 /* 57 '9' */, -1 /* 58 ':' */, -1 /* 59 ';' */, -1 /* 60 '<' */, -1 /* 61 '=' */, -1 /* 62 '>' */, -1 /* 63 '?' */, -1 /* 64 '@' */, 0xa /* 65 'A' */, 0xb /* 66 'B' */, 0xc /* 67 'C' */, 0xd /* 68 'D' */, 0xe /* 69 'E' */, 0xf /* 70 'F' */, -1 /* 71 'G' */, -1 /* 72 'H' */, -1 /* 73 'I' */, -1 /* 74 'J' */, -1 /* 75 'K' */, -1 /* 76 'L' */, -1 /* 77 'M' */, -1 /* 78 'N' */, -1 /* 79 'O' */, -1 /* 80 'P' */, -1 /* 81 'Q' */, -1 /* 82 'R' */, -1 /* 83 'S' */, -1 /* 84 'T' */, -1 /* 85 'U' */, -1 /* 86 'V' */, -1 /* 87 'W' */, -1 /* 88 'X' */, -1 /* 89 'Y' */, -1 /* 90 'Z' */, -1 /* 91 '[' */, -1 /* 92 '\' */, -1 /* 93 ']' */, -1 /* 94 '^' */, -1 /* 95 '_' */, -1 /* 96 '`' */, 0xa /* 97 'a' */, 0xb /* 98 'b' */, 0xc /* 99 'c' */, 0xd /* 100 'd' */, 0xe /* 101 'e' */, 0xf /* 102 'f' */, };
if (inCharacter >= '0' && inCharacter <= 'f')
return(theValues[inCharacter - '0']);
else
return(-1);
}
@interface CJSONScanner ()
- (BOOL)scanNotQuoteCharactersIntoString:(NSString **)outValue;
@end
#pragma mark -
@implementation CJSONScanner
- (id)init
{
if ((self = [super init]) != nil)
{
}
return(self);
}
- (void)dealloc
{
//
[super dealloc];
}
#pragma mark -
- (void)setData:(NSData *)inData
{
NSData *theData = inData;
if (theData && theData.length >= 4)
{
// This code is lame, but it works. Because the first character of any JSON string will always be a (ascii) control character we can work out the Unicode encoding by the bit pattern. See section 3 of http://www.ietf.org/rfc/rfc4627.txt
const char *theChars = theData.bytes;
NSStringEncoding theEncoding = NSUTF8StringEncoding;
if (theChars[0] != 0 && theChars[1] == 0)
{
if (theChars[2] != 0 && theChars[3] == 0)
theEncoding = NSUTF16LittleEndianStringEncoding;
else if (theChars[2] == 0 && theChars[3] == 0)
theEncoding = NSUTF32LittleEndianStringEncoding;
}
else if (theChars[0] == 0 && theChars[2] == 0 && theChars[3] != 0)
{
if (theChars[1] == 0)
theEncoding = NSUTF32BigEndianStringEncoding;
else if (theChars[1] != 0)
theEncoding = NSUTF16BigEndianStringEncoding;
}
if (theEncoding != NSUTF8StringEncoding)
{
NSString *theString = [[NSString alloc] initWithData:theData encoding:theEncoding];
theData = [theString dataUsingEncoding:NSUTF8StringEncoding];
[theString release];
}
}
[super setData:theData];
}
#pragma mark -
- (BOOL)scanJSONObject:(id *)outObject error:(NSError **)outError
{
BOOL theResult = YES;
[self skipWhitespace];
id theObject = NULL;
const unichar C = [self currentCharacter];
switch (C)
{
case 't':
if ([self scanUTF8String:"true" intoString:NULL])
{
theObject = [NSNumber numberWithBool:YES];
}
break;
case 'f':
if ([self scanUTF8String:"false" intoString:NULL])
{
theObject = [NSNumber numberWithBool:NO];
}
break;
case 'n':
if ([self scanUTF8String:"null" intoString:NULL])
{
theObject = [NSNull null];
}
break;
case '\"':
case '\'':
theResult = [self scanJSONStringConstant:&theObject error:outError];
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-':
theResult = [self scanJSONNumberConstant:&theObject error:outError];
break;
case '{':
theResult = [self scanJSONDictionary:&theObject error:outError];
break;
case '[':
theResult = [self scanJSONArray:&theObject error:outError];
break;
default:
break;
}
if (outObject != NULL)
*outObject = theObject;
return(theResult);
}
- (BOOL)scanJSONDictionary:(NSDictionary **)outDictionary error:(NSError **)outError
{
NSUInteger theScanLocation = [self scanLocation];
if ([self scanCharacter:'{'] == NO)
{
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Dictionary that does not start with '{' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-1 userInfo:theUserInfo];
}
return(NO);
}
NSMutableDictionary *theDictionary = [[NSMutableDictionary alloc] init];
while ([self currentCharacter] != '}')
{
[self skipWhitespace];
if ([self currentCharacter] == '}')
break;
NSString *theKey = NULL;
if ([self scanJSONStringConstant:&theKey error:outError] == NO)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Failed to scan a key.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-2 userInfo:theUserInfo];
}
[theDictionary release];
return(NO);
}
[self skipWhitespace];
if ([self scanCharacter:':'] == NO)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Key was not terminated with a ':' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-3 userInfo:theUserInfo];
}
[theDictionary release];
return(NO);
}
id theValue = NULL;
if ([self scanJSONObject:&theValue error:outError] == NO)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Failed to scan a value.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-4 userInfo:theUserInfo];
}
[theDictionary release];
return(NO);
}
[theDictionary setValue:theValue forKey:theKey];
[self skipWhitespace];
if ([self scanCharacter:','] == NO)
{
if ([self currentCharacter] != '}')
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Key value pairs not delimited with a ',' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-5 userInfo:theUserInfo];
}
[theDictionary release];
return(NO);
}
break;
}
else
{
[self skipWhitespace];
if ([self currentCharacter] == '}')
break;
}
}
if ([self scanCharacter:'}'] == NO)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan dictionary. Dictionary not terminated by a '}' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-6 userInfo:theUserInfo];
}
[theDictionary release];
return(NO);
}
if (outDictionary != NULL)
*outDictionary = [[theDictionary copy] autorelease];
[theDictionary release];
return(YES);
}
- (BOOL)scanJSONArray:(NSArray **)outArray error:(NSError **)outError
{
NSUInteger theScanLocation = [self scanLocation];
if ([self scanCharacter:'['] == NO)
{
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Array not started by a '{' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-7 userInfo:theUserInfo];
}
return(NO);
}
NSMutableArray *theArray = [[NSMutableArray alloc] init];
[self skipWhitespace];
while ([self currentCharacter] != ']')
{
NSString *theValue = NULL;
if ([self scanJSONObject:&theValue error:outError] == NO)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Could not scan a value.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-8 userInfo:theUserInfo];
}
[theArray release];
return(NO);
}
[theArray addObject:theValue];
[self skipWhitespace];
if ([self scanCharacter:','] == NO)
{
[self skipWhitespace];
if ([self currentCharacter] != ']')
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Array not terminated by a ']' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-9 userInfo:theUserInfo];
}
[theArray release];
return(NO);
}
break;
}
[self skipWhitespace];
}
[self skipWhitespace];
if ([self scanCharacter:']'] == NO)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan array. Array not terminated by a ']' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-10 userInfo:theUserInfo];
}
[theArray release];
return(NO);
}
if (outArray != NULL)
*outArray = [[theArray copy] autorelease];
[theArray release];
return(YES);
}
- (BOOL)scanJSONStringConstant:(NSString **)outStringConstant error:(NSError **)outError
{
NSUInteger theScanLocation = [self scanLocation];
[self skipWhitespace]; // TODO - i want to remove this method. But breaks unit tests.
NSMutableString *theString = [[NSMutableString alloc] init];
if ([self scanCharacter:'"'] == NO)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan string constant. String not started by a '\"' character.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-11 userInfo:theUserInfo];
}
[theString release];
return(NO);
}
while ([self scanCharacter:'"'] == NO)
{
NSString *theStringChunk = NULL;
if ([self scanNotQuoteCharactersIntoString:&theStringChunk])
{
[theString appendString:theStringChunk];
}
if ([self scanCharacter:'\\'] == YES)
{
unichar theCharacter = [self scanCharacter];
switch (theCharacter)
{
case '"':
case '\\':
case '/':
break;
case 'b':
theCharacter = '\b';
break;
case 'f':
theCharacter = '\f';
break;
case 'n':
theCharacter = '\n';
break;
case 'r':
theCharacter = '\r';
break;
case 't':
theCharacter = '\t';
break;
case 'u':
{
theCharacter = 0;
int theShift;
for (theShift = 12; theShift >= 0; theShift -= 4)
{
const int theDigit = HexToInt([self scanCharacter]);
if (theDigit == -1)
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan string constant. Unicode character could not be decoded.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-12 userInfo:theUserInfo];
}
[theString release];
return(NO);
}
theCharacter |= (theDigit << theShift);
}
}
break;
default:
{
[self setScanLocation:theScanLocation];
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan string constant. Unknown escape code.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-13 userInfo:theUserInfo];
}
[theString release];
return(NO);
}
break;
}
CFStringAppendCharacters((CFMutableStringRef)theString, &theCharacter, 1);
}
}
if (outStringConstant != NULL)
*outStringConstant = [[theString copy] autorelease];
[theString release];
return(YES);
}
- (BOOL)scanJSONNumberConstant:(NSNumber **)outNumberConstant error:(NSError **)outError
{
NSNumber *theNumber = NULL;
if ([self scanNumber:&theNumber] == YES)
{
if (outNumberConstant != NULL)
*outNumberConstant = theNumber;
return(YES);
}
else
{
if (outError)
{
NSDictionary *theUserInfo = [NSDictionary dictionaryWithObjectsAndKeys:
@"Could not scan number constant.", NSLocalizedDescriptionKey,
NULL];
*outError = [NSError errorWithDomain:kJSONScannerErrorDomain code:-14 userInfo:theUserInfo];
}
return(NO);
}
}
#if TREAT_COMMENTS_AS_WHITESPACE
- (void)skipWhitespace
{
[super skipWhitespace];
[self scanCStyleComment:NULL];
[self scanCPlusPlusStyleComment:NULL];
[super skipWhitespace];
}
#endif // TREAT_COMMENTS_AS_WHITESPACE
#pragma mark -
- (BOOL)scanNotQuoteCharactersIntoString:(NSString **)outValue
{
u_int8_t *P;
for (P = current; P < end && *P != '\"' && *P != '\\'; ++P)
;
if (P == current)
{
return(NO);
}
if (outValue)
{
*outValue = [[[NSString alloc] initWithBytes:current length:P - current encoding:NSUTF8StringEncoding] autorelease];
}
current = P;
return(YES);
}
@end

View File

@@ -0,0 +1,47 @@
//
// CJSONSerializer.h
// TouchCode
//
// Created by Jonathan Wight on 12/07/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@class CJSONDataSerializer;
/// Serialize JSON compatible objects (NSNull, NSNumber, NSString, NSArray, NSDictionary) into a JSON formatted string. Note this class is just a wrapper around CJSONDataSerializer which you really should be using instead.
@interface CJSONSerializer : NSObject {
CJSONDataSerializer *serializer;
}
+ (id)serializer;
/// Take any JSON compatible object (generally NSNull, NSNumber, NSString, NSArray and NSDictionary) and produce a JSON string.
- (NSString *)serializeObject:(id)inObject;
- (NSString *)serializeArray:(NSArray *)inArray;
- (NSString *)serializeDictionary:(NSDictionary *)inDictionary;
@end

View File

@@ -0,0 +1,75 @@
//
// CJSONSerializer.m
// TouchCode
//
// Created by Jonathan Wight on 12/07/2005.
// Copyright 2005 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import "CJSONSerializer.h"
#import "CJSONDataSerializer.h"
@implementation CJSONSerializer
+ (id)serializer
{
return([[[self alloc] init] autorelease]);
}
- (id)init
{
if ((self = [super init]) != NULL)
{
serializer = [[CJSONDataSerializer alloc] init];
}
return(self);
}
- (void)dealloc
{
[serializer release];
serializer = NULL;
//
[super dealloc];
}
- (NSString *)serializeObject:(id)inObject;
{
NSData *theData = [serializer serializeObject:inObject];
return([[[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding] autorelease]);
}
- (NSString *)serializeArray:(NSArray *)inArray
{
NSData *theData = [serializer serializeArray:inArray];
return([[[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding] autorelease]);
}
- (NSString *)serializeDictionary:(NSDictionary *)inDictionary;
{
NSData *theData = [serializer serializeDictionary:inDictionary];
return([[[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding] autorelease]);
}
@end

View File

@@ -0,0 +1,40 @@
//
// CSerializedJSONData.h
// TouchCode
//
// Created by Jonathan Wight on 10/23/09.
// Copyright 2009 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import <Foundation/Foundation.h>
@interface CSerializedJSONData : NSObject {
NSData *data;
}
@property (readonly, nonatomic, retain) NSData *data;
- (id)initWithData:(NSData *)inData;
@end

View File

@@ -0,0 +1,54 @@
//
// CSerializedJSONData.m
// TouchCode
//
// Created by Jonathan Wight on 10/23/09.
// Copyright 2009 toxicsoftware.com. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
#import "CSerializedJSONData.h"
@implementation CSerializedJSONData
@synthesize data;
- (id)initWithData:(NSData *)inData;
{
if ((self = [self init]) != NULL)
{
data = inData;
}
return(self);
}
- (void)dealloc
{
[data release];
data = NULL;
//
[super dealloc];
}
@end