mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-06 14:40:43 +00:00
NSJSONSerialization: Implement NSJSONWritingSortedKeys
This commit is contained in:
parent
0606cb9db4
commit
cc0d8d88e5
3 changed files with 58 additions and 10 deletions
|
@ -50,7 +50,13 @@ enum
|
||||||
* If this is not set, then the writer will not generate any superfluous
|
* If this is not set, then the writer will not generate any superfluous
|
||||||
* whitespace, producing space-efficient but not very human-friendly JSON.
|
* whitespace, producing space-efficient but not very human-friendly JSON.
|
||||||
*/
|
*/
|
||||||
NSJSONWritingPrettyPrinted = (1UL << 0)
|
NSJSONWritingPrettyPrinted = (1UL << 0),
|
||||||
|
#if OS_API_VERSION(MAC_OS_X_VERSION_10_13, GS_API_LATEST)
|
||||||
|
/**
|
||||||
|
* When writing JSON, sort keys in lexicographic order.
|
||||||
|
*/
|
||||||
|
NSJSONWritingSortedKeys = (1UL << 1)
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* A bitmask containing flags from the NSJSONWriting* set, specifying options
|
* A bitmask containing flags from the NSJSONWriting* set, specifying options
|
||||||
|
|
|
@ -860,7 +860,7 @@ writeNewline(NSMutableString *output, NSInteger tabs)
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL
|
static BOOL
|
||||||
writeObject(id obj, NSMutableString *output, NSInteger tabs)
|
writeObject(id obj, NSMutableString *output, NSInteger tabs, NSJSONWritingOptions opt)
|
||||||
{
|
{
|
||||||
if ([obj isKindOfClass: NSArrayClass])
|
if ([obj isKindOfClass: NSArrayClass])
|
||||||
{
|
{
|
||||||
|
@ -874,7 +874,7 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs)
|
||||||
writeComma = YES;
|
writeComma = YES;
|
||||||
writeNewline(output, tabs);
|
writeNewline(output, tabs);
|
||||||
writeTabs(output, tabs);
|
writeTabs(output, tabs);
|
||||||
writeObject(o, output, tabs + 1);
|
writeObject(o, output, tabs + 1, opt);
|
||||||
END_FOR_IN(obj)
|
END_FOR_IN(obj)
|
||||||
writeNewline(output, tabs);
|
writeNewline(output, tabs);
|
||||||
writeTabs(output, tabs);
|
writeTabs(output, tabs);
|
||||||
|
@ -883,8 +883,15 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs)
|
||||||
else if ([obj isKindOfClass: NSDictionaryClass])
|
else if ([obj isKindOfClass: NSDictionaryClass])
|
||||||
{
|
{
|
||||||
BOOL writeComma = NO;
|
BOOL writeComma = NO;
|
||||||
|
NSArray *keys = [obj allKeys];
|
||||||
[output appendString: @"{"];
|
[output appendString: @"{"];
|
||||||
FOR_IN(id, o, obj)
|
|
||||||
|
if ((opt & NSJSONWritingSortedKeys) == NSJSONWritingSortedKeys)
|
||||||
|
{
|
||||||
|
keys = [keys sortedArrayUsingSelector: @selector(compare:)];
|
||||||
|
}
|
||||||
|
|
||||||
|
FOR_IN(id, o, keys)
|
||||||
// Keys in dictionaries must be strings
|
// Keys in dictionaries must be strings
|
||||||
if (![o isKindOfClass: NSStringClass]) { return NO; }
|
if (![o isKindOfClass: NSStringClass]) { return NO; }
|
||||||
if (writeComma)
|
if (writeComma)
|
||||||
|
@ -894,10 +901,11 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs)
|
||||||
writeComma = YES;
|
writeComma = YES;
|
||||||
writeNewline(output, tabs);
|
writeNewline(output, tabs);
|
||||||
writeTabs(output, tabs);
|
writeTabs(output, tabs);
|
||||||
writeObject(o, output, tabs + 1);
|
writeObject(o, output, tabs + 1, opt);
|
||||||
[output appendString: @":"];
|
[output appendString: @":"];
|
||||||
writeObject([obj objectForKey: o], output, tabs + 1);
|
writeObject([obj objectForKey: o], output, tabs + 1, opt);
|
||||||
END_FOR_IN(obj)
|
END_FOR_IN(keys)
|
||||||
|
|
||||||
writeNewline(output, tabs);
|
writeNewline(output, tabs);
|
||||||
writeTabs(output, tabs);
|
writeTabs(output, tabs);
|
||||||
[output appendString: @"}"];
|
[output appendString: @"}"];
|
||||||
|
@ -1062,7 +1070,7 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs)
|
||||||
|
|
||||||
tabs = ((opt & NSJSONWritingPrettyPrinted) == NSJSONWritingPrettyPrinted) ?
|
tabs = ((opt & NSJSONWritingPrettyPrinted) == NSJSONWritingPrettyPrinted) ?
|
||||||
0 : NSIntegerMin;
|
0 : NSIntegerMin;
|
||||||
if (writeObject(obj, str, tabs))
|
if (writeObject(obj, str, tabs, opt))
|
||||||
{
|
{
|
||||||
data = [str dataUsingEncoding: NSUTF8StringEncoding];
|
data = [str dataUsingEncoding: NSUTF8StringEncoding];
|
||||||
if (NULL != error)
|
if (NULL != error)
|
||||||
|
@ -1089,7 +1097,7 @@ writeObject(id obj, NSMutableString *output, NSInteger tabs)
|
||||||
|
|
||||||
+ (BOOL) isValidJSONObject: (id)obj
|
+ (BOOL) isValidJSONObject: (id)obj
|
||||||
{
|
{
|
||||||
return writeObject(obj, nil, NSIntegerMin);
|
return writeObject(obj, nil, NSIntegerMin, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id) JSONObjectWithData: (NSData *)data
|
+ (id) JSONObjectWithData: (NSData *)data
|
||||||
|
|
34
Tests/base/NSJSONSerialization/sorted.m
Normal file
34
Tests/base/NSJSONSerialization/sorted.m
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "ObjectTesting.h"
|
||||||
|
|
||||||
|
void testLexicographicalOrder() {
|
||||||
|
NSArray *objects =
|
||||||
|
[NSArray arrayWithObjects:@"a", @"b", @"c", @"d", @"e", nil];
|
||||||
|
NSArray *keys = [NSArray
|
||||||
|
arrayWithObjects:@"c_ab", @"a_ab", @"d_ab", @"f_cb", @"f_ab", nil];
|
||||||
|
NSDictionary *dict = [NSDictionary dictionaryWithObjects:objects
|
||||||
|
forKeys:keys];
|
||||||
|
|
||||||
|
NSError *error = nil;
|
||||||
|
NSData *actualData =
|
||||||
|
[NSJSONSerialization dataWithJSONObject:dict
|
||||||
|
options:NSJSONWritingSortedKeys
|
||||||
|
error:&error];
|
||||||
|
PASS_EQUAL(error, nil, "no error occurred during serialisation");
|
||||||
|
|
||||||
|
|
||||||
|
NSString *actual = [[NSString alloc] initWithData:actualData
|
||||||
|
encoding:NSUTF8StringEncoding];
|
||||||
|
NSString *expected = @"{\"a_ab\":\"b\",\"c_ab\":\"a\",\"d_ab\":\"c\",\"f_"
|
||||||
|
"ab\":\"e\",\"f_cb\":\"d\"}";
|
||||||
|
PASS_EQUAL(actual, expected, "JSON is correctly sorted");
|
||||||
|
NSLog(@"%@", actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
NSAutoreleasePool *arp = [NSAutoreleasePool new];
|
||||||
|
|
||||||
|
testLexicographicalOrder();
|
||||||
|
|
||||||
|
[arp release];
|
||||||
|
}
|
Loading…
Reference in a new issue