diff --git a/ChangeLog b/ChangeLog index a94a731b3..85ea28392 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2012-09-10 Richard Frith-Macdonald + + * Source/NSJSONSerialization.m: + * Source/NSPropertyList.m: + Improve serialisation of booleans. + 2012-09-10 Richard Frith-Macdonald * Headers/Foundation/NSDate.h: Declare new OSX method to add time diff --git a/Source/NSJSONSerialization.m b/Source/NSJSONSerialization.m index f7c6c5fee..0500b4e62 100644 --- a/Source/NSJSONSerialization.m +++ b/Source/NSJSONSerialization.m @@ -11,6 +11,11 @@ #import #import "GSFastEnumeration.h" +/* Boolean constants. + */ +static id boolN; +static id boolY; + /** * The number of (unicode) characters to fetch from the source at once. */ @@ -614,7 +619,7 @@ parseValue(ParserState *state) && (consumeChar(state) == 'e')) { consumeChar(state); - return [[NSNumber alloc] initWithBool: YES]; + return [boolY retain]; } break; } @@ -626,7 +631,7 @@ parseValue(ParserState *state) && (consumeChar(state) == 'e')) { consumeChar(state); - return [[NSNumber alloc] initWithBool: NO]; + return [boolN retain]; } break; } @@ -710,8 +715,11 @@ getEncoding(const uint8_t BOM[4], ParserState *state) /** * Classes that are permitted to be written. */ -static Class NSNullClass, NSArrayClass, NSStringClass, NSDictionaryClass, - NSNumberClass; +static Class NSArrayClass; +static Class NSDictionaryClass; +static Class NSNullClass; +static Class NSNumberClass; +static Class NSStringClass; static NSCharacterSet *escapeSet; @@ -814,23 +822,17 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs) [output appendFormat: @"\"%@\"", obj]; } } + else if (obj == boolN) + { + [output appendString: @"false"]; + } + else if (obj == boolY) + { + [output appendString: @"true"]; + } else if ([obj isKindOfClass: NSNumberClass]) { - if ([obj objCType][0] == @encode(BOOL)[0]) - { - if ([obj boolValue]) - { - [output appendString: @"true"]; - } - else - { - [output appendString: @"false"]; - } - } - else - { - [output appendFormat: @"%g", [obj doubleValue]]; - } + [output appendFormat: @"%g", [obj doubleValue]]; } else if ([obj isKindOfClass: NSNullClass]) { @@ -853,7 +855,8 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs) NSNumberClass = [NSNumber class]; escapeSet = [[NSCharacterSet characterSetWithCharactersInString: @"\"\\"] retain]; - + boolN = [[NSNumber numberWithBool: NO] retain]; + boolY = [[NSNumber numberWithBool: YES] retain]; } + (NSData*) dataWithJSONObject: (id)obj diff --git a/Source/NSPropertyList.m b/Source/NSPropertyList.m index 6fe877ca4..72ac7a649 100644 --- a/Source/NSPropertyList.m +++ b/Source/NSPropertyList.m @@ -51,6 +51,16 @@ #import "GSPrivate.h" +static id boolN = nil; +static id boolY = nil; + +static void +setupBooleans() +{ + if (nil == boolN) boolN = [[NSNumber numberWithBool: NO] retain]; + if (nil == boolY) boolY = [[NSNumber numberWithBool: YES] retain]; +} + @class GSSloppyXMLParser; #define inrange(ch,min,max) ((ch)>=(min) && (ch)<=(max)) @@ -331,11 +341,11 @@ foundIgnorableWhitespace: (NSString *)string } else if ([elementName isEqualToString: @"true"]) { - ASSIGN(plist, [NSNumber numberWithBool: YES]); + ASSIGN(plist, boolY); } else if ([elementName isEqualToString: @"false"]) { - ASSIGN(plist, [NSNumber numberWithBool: NO]); + ASSIGN(plist, boolN); } else if ([elementName isEqualToString: @"plist"]) { @@ -1155,11 +1165,11 @@ static id parsePlItem(pldata* pld) { if (ptr[0] == 'Y') { - result = [[NSNumber alloc] initWithBool: YES]; + result = [boolY retain]; } else if (ptr[0] == 'N') { - result = [[NSNumber alloc] initWithBool: NO]; + result = [boolN retain]; } else { @@ -1830,46 +1840,41 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step, PString(obj, dest); } } + else if (obj == boolY) + { + if (x == NSPropertyListXMLFormat_v1_0) + { + [dest appendBytes: "\n" length: 8]; + } + else if (x == NSPropertyListGNUstepFormat) + { + [dest appendBytes: "<*BY>" length: 5]; + } + else + { + PString([obj description], dest); + } + } + else if (obj == boolN) + { + if (x == NSPropertyListXMLFormat_v1_0) + { + [dest appendBytes: "\n" length: 9]; + } + else if (x == NSPropertyListGNUstepFormat) + { + [dest appendBytes: "<*BN>" length: 5]; + } + else + { + PString([obj description], dest); + } + } else if ([obj isKindOfClass: NSNumberClass]) { const char *t = [obj objCType]; - if (*t == 'c' || *t == 'C') - { - BOOL val = [obj boolValue]; - - if (val == YES) - { - if (x == NSPropertyListXMLFormat_v1_0) - { - [dest appendBytes: "\n" length: 8]; - } - else if (x == NSPropertyListGNUstepFormat) - { - [dest appendBytes: "<*BY>" length: 5]; - } - else - { - PString([obj description], dest); - } - } - else - { - if (x == NSPropertyListXMLFormat_v1_0) - { - [dest appendBytes: "\n" length: 9]; - } - else if (x == NSPropertyListGNUstepFormat) - { - [dest appendBytes: "<*BN>" length: 5]; - } - else - { - PString([obj description], dest); - } - } - } - else if (strchr("sSiIlLqQ", *t) != 0) + if (strchr("cCsSiIlLqQ", *t) != 0) { if (x == NSPropertyListXMLFormat_v1_0) { @@ -2369,6 +2374,7 @@ static BOOL classInitialized = NO; [plDictionary instanceMethodForSelector: @selector(setObject:forKey:)]; setupQuotables(); + setupBooleans(); } } @@ -2985,12 +2991,12 @@ NSAssert(pos + count < _length, NSInvalidArgumentException); if (next == 0x08) { // NO - result = [NSNumber numberWithBool: NO]; + result = boolN; } else if (next == 0x09) { // YES - result = [NSNumber numberWithBool: YES]; + result = boolY; } else if ((next >= 0x10) && (next < 0x17)) {