5 // Created by Jonathan Wight on 12/07/2005.
6 // Copyright 2005 Toxic Software. All rights reserved.
9 #import "CJSONSerializer.h"
11 @implementation CJSONSerializer
15 return([[[self alloc] init] autorelease]);
18 - (NSString *)serializeObject:(id)inObject;
20 NSString *theResult = @"";
22 if ([inObject isKindOfClass:[NSNull class]])
24 theResult = [self serializeNull:inObject];
26 else if ([inObject isKindOfClass:[NSNumber class]])
28 theResult = [self serializeNumber:inObject];
30 else if ([inObject isKindOfClass:[NSString class]])
32 theResult = [self serializeString:inObject];
34 else if ([inObject isKindOfClass:[NSArray class]])
36 theResult = [self serializeArray:inObject];
38 else if ([inObject isKindOfClass:[NSDictionary class]])
40 theResult = [self serializeDictionary:inObject];
42 else if ([inObject isKindOfClass:[NSData class]])
44 NSString *theString = [[[NSString alloc] initWithData:inObject encoding:NSUTF8StringEncoding] autorelease];
45 theResult = [self serializeString:theString];
49 [NSException raise:NSGenericException format:@"Cannot serialize data of type '%@'", NSStringFromClass([inObject class])];
51 if (theResult == NULL)
52 [NSException raise:NSGenericException format:@"Could not serialize object '%@'", inObject];
56 - (NSString *)serializeNull:(NSNull *)inNull
58 #pragma unused (inNull)
62 - (NSString *)serializeNumber:(NSNumber *)inNumber
64 NSString *theResult = NULL;
65 switch (CFNumberGetType((CFNumberRef)inNumber))
67 case kCFNumberCharType:
69 int theValue = [inNumber intValue];
72 else if (theValue == 1)
75 theResult = [inNumber stringValue];
78 case kCFNumberSInt8Type:
79 case kCFNumberSInt16Type:
80 case kCFNumberSInt32Type:
81 case kCFNumberSInt64Type:
82 case kCFNumberFloat32Type:
83 case kCFNumberFloat64Type:
84 case kCFNumberShortType:
85 case kCFNumberIntType:
86 case kCFNumberLongType:
87 case kCFNumberLongLongType:
88 case kCFNumberFloatType:
89 case kCFNumberDoubleType:
90 case kCFNumberCFIndexType:
92 theResult = [inNumber stringValue];
98 - (NSString *)serializeString:(NSString *)inString
100 NSMutableString *theMutableCopy = [[inString mutableCopy] autorelease];
101 [theMutableCopy replaceOccurrencesOfString:@"\\" withString:@"\\\\" options:0 range:NSMakeRange(0, [theMutableCopy length])];
102 [theMutableCopy replaceOccurrencesOfString:@"\"" withString:@"\\\"" options:0 range:NSMakeRange(0, [theMutableCopy length])];
103 [theMutableCopy replaceOccurrencesOfString:@"/" withString:@"\\/" options:0 range:NSMakeRange(0, [theMutableCopy length])];
104 [theMutableCopy replaceOccurrencesOfString:@"\b" withString:@"\\b" options:0 range:NSMakeRange(0, [theMutableCopy length])];
105 [theMutableCopy replaceOccurrencesOfString:@"\f" withString:@"\\f" options:0 range:NSMakeRange(0, [theMutableCopy length])];
106 [theMutableCopy replaceOccurrencesOfString:@"\n" withString:@"\\n" options:0 range:NSMakeRange(0, [theMutableCopy length])];
107 [theMutableCopy replaceOccurrencesOfString:@"\n" withString:@"\\n" options:0 range:NSMakeRange(0, [theMutableCopy length])];
108 [theMutableCopy replaceOccurrencesOfString:@"\t" withString:@"\\t" options:0 range:NSMakeRange(0, [theMutableCopy length])];
115 for (theShift = 12; theShift >= 0; theShift -= 4)
117 int theDigit = HexToInt([self scanCharacter]);
120 [self setScanLocation:theScanLocation];
123 theCharacter |= (theDigit << theShift);
127 return([NSString stringWithFormat:@"\"%@\"", theMutableCopy]);
130 - (NSString *)serializeArray:(NSArray *)inArray
132 NSMutableString *theString = [NSMutableString string];
134 NSEnumerator *theEnumerator = [inArray objectEnumerator];
136 while ((theValue = [theEnumerator nextObject]) != NULL)
138 [theString appendString:[self serializeObject:theValue]];
139 if (theValue != [inArray lastObject])
140 [theString appendString:@","];
142 return([NSString stringWithFormat:@"[%@]", theString]);
145 - (NSString *)serializeDictionary:(NSDictionary *)inDictionary
147 NSMutableString *theString = [NSMutableString string];
149 NSArray *theKeys = [inDictionary allKeys];
150 NSEnumerator *theEnumerator = [theKeys objectEnumerator];
151 NSString *theKey = NULL;
152 while ((theKey = [theEnumerator nextObject]) != NULL)
154 id theValue = [inDictionary valueForKey:theKey];
156 [theString appendFormat:@"%@:%@", [self serializeString:theKey], [self serializeObject:theValue]];
157 if (theKey != [theKeys lastObject])
158 [theString appendString:@","];
160 return([NSString stringWithFormat:@"{%@}", theString]);