@@ -36,10 +36,15 @@ #import "macros.h" static struct { Class isa; } placeholder; + +@interface OFArray (OF_PRIVATE_CATEGORY) +- (OFString*)OF_JSONRepresentationWithOptions: (int)options + depth: (size_t)depth; +@end @interface OFArray_placeholder: OFArray @end @implementation OFArray_placeholder @@ -542,25 +547,78 @@ return [element autorelease]; } - (OFString*)JSONRepresentation { + return [self OF_JSONRepresentationWithOptions: 0 + depth: 0]; +} + +- (OFString*)JSONRepresentationWithOptions: (int)options +{ + return [self OF_JSONRepresentationWithOptions: options + depth: 0]; +} + +- (OFString*)OF_JSONRepresentationWithOptions: (int)options + depth: (size_t)depth +{ + OFMutableString *JSON = [OFMutableString stringWithString: @"["]; void *pool = objc_autoreleasePoolPush(); - OFMutableString *JSON; - - JSON = [[self componentsJoinedByString: @"," - usingSelector: @selector(JSONRepresentation)] - mutableCopy]; - - [JSON prependString: @"["]; - [JSON appendString: @"]"]; - + OFEnumerator *enumerator = [self objectEnumerator]; + id object; + size_t i, count = [self count]; + + if (options & OF_JSON_REPRESENTATION_PRETTY) { + OFMutableString *indentation = [OFMutableString string]; + + for (i = 0; i < depth; i++) + [indentation appendString: @"\t"]; + + [JSON appendString: @"\n"]; + + i = 0; + while ((object = [enumerator nextObject]) != nil) { + void *pool2 = objc_autoreleasePoolPush(); + + [JSON appendString: indentation]; + [JSON appendString: @"\t"]; + [JSON appendString: [object + OF_JSONRepresentationWithOptions: options + depth: depth + 1]]; + + if (++i < count) + [JSON appendString: @",\n"]; + else + [JSON appendString: @"\n"]; + + objc_autoreleasePoolPop(pool2); + } + + [JSON appendString: indentation]; + } else { + i = 0; + while ((object = [enumerator nextObject]) != nil) { + void *pool2 = objc_autoreleasePoolPush(); + + [JSON appendString: [object + OF_JSONRepresentationWithOptions: options + depth: depth + 1]]; + + if (++i < count) + [JSON appendString: @","]; + + objc_autoreleasePoolPop(pool2); + } + } + + [JSON appendString: @"]"]; [JSON makeImmutable]; objc_autoreleasePoolPop(pool); - return [JSON autorelease]; + return JSON; } - (OFDataArray*)messagePackRepresentation { OFDataArray *data;