ObjFW  Check-in [243a96fc2d]

Overview
Comment:Add JSON encoding.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 243a96fc2d0cd35fbc11ac63b7289b5045c548a7b097c8990ec72b026f3b1360
User & Date: js on 2011-12-10 13:17:52
Other Links: manifest | tags
Context
2011-12-10
18:17
Fix wrong -[description] for an empty OFDictionary. check-in: 4e87bc9862 user: js tags: trunk
13:17
Add JSON encoding. check-in: 243a96fc2d user: js tags: trunk
2011-12-08
04:19
Add a property for -[OFStream isAtEndOfStream].
This makes stream.atEndOfStream work.
check-in: d64e1d5727 user: js tags: trunk
Changes

Modified src/Makefile from [30874743de] to [c5a6ef9f8f].

62
63
64
65
66
67
68

69
70
71
72
73
74
75
       base64.m				\
       of_asprintf.m			\
       of_strptime.m			\
       unicode.m

INCLUDES := ${SRCS:.m=.h}	\
	    OFCollection.h	\

	    OFSerialization.h	\
	    ObjFW.h		\
	    asprintf.h		\
	    ${ATOMIC_H}		\
	    macros.h		\
	    objfw-defs.h	\
	    ${THREADING_H}







>







62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
       base64.m				\
       of_asprintf.m			\
       of_strptime.m			\
       unicode.m

INCLUDES := ${SRCS:.m=.h}	\
	    OFCollection.h	\
	    OFJSON.h		\
	    OFSerialization.h	\
	    ObjFW.h		\
	    asprintf.h		\
	    ${ATOMIC_H}		\
	    macros.h		\
	    objfw-defs.h	\
	    ${THREADING_H}

Modified src/OFArray.h from [f99b463989] to [7771b2d583].

16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

#include <stdarg.h>

#import "OFObject.h"
#import "OFCollection.h"
#import "OFEnumerator.h"
#import "OFSerialization.h"


@class OFString;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_array_enumeration_block_t)(id object, size_t index,
    BOOL *stop);
typedef BOOL (^of_array_filter_block_t)(id odject, size_t index);
typedef id (^of_array_map_block_t)(id object, size_t index);
typedef id (^of_array_fold_block_t)(id left, id right);
#endif

/**
 * \brief An abstract class for storing objects in an array.
 */
@interface OFArray: OFObject <OFCopying, OFMutableCopying, OFCollection,
    OFSerialization>
/**
 * \brief Creates a new OFArray.
 *
 * \return A new autoreleased OFArray
 */
+ array;








>















|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

#include <stdarg.h>

#import "OFObject.h"
#import "OFCollection.h"
#import "OFEnumerator.h"
#import "OFSerialization.h"
#import "OFJSON.h"

@class OFString;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_array_enumeration_block_t)(id object, size_t index,
    BOOL *stop);
typedef BOOL (^of_array_filter_block_t)(id odject, size_t index);
typedef id (^of_array_map_block_t)(id object, size_t index);
typedef id (^of_array_fold_block_t)(id left, id right);
#endif

/**
 * \brief An abstract class for storing objects in an array.
 */
@interface OFArray: OFObject <OFCopying, OFMutableCopying, OFCollection,
    OFSerialization, OFJSON>
/**
 * \brief Creates a new OFArray.
 *
 * \return A new autoreleased OFArray
 */
+ array;

228
229
230
231
232
233
234











235
236
237
238
239
240
241
 * \brief Creates a string by joining all objects of the array.
 *
 * \param separator The string with which the objects should be joined
 * \return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator;












/**
 * \brief Performs the specified selector on all objects in the array.
 *
 * \param selector The selector to perform on all objects in the array
 */
- (void)makeObjectsPerformSelector: (SEL)selector;








>
>
>
>
>
>
>
>
>
>
>







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
 * \brief Creates a string by joining all objects of the array.
 *
 * \param separator The string with which the objects should be joined
 * \return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator;

/**
 * \brief Creates a string by calling the selector on all objects of the array
 *	  and joining the strings returned by calling the selector.
 *
 * \param separator The string with which the objects should be joined
 * \param selector The selector to perform on the objects
 * \return A string containing all objects joined by the separator
 */
- (OFString*)componentsJoinedByString: (OFString*)separator
			usingSelector: (SEL)selector;

/**
 * \brief Performs the specified selector on all objects in the array.
 *
 * \param selector The selector to perform on all objects in the array
 */
- (void)makeObjectsPerformSelector: (SEL)selector;

Modified src/OFArray.m from [b2464cd374] to [53e138918e].

361
362
363
364
365
366
367







368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389

390
391
392
393
394

395
396
397
398
399
400
401
		[self freeMemory: buffer];
	}

	return ret;
}

- (OFString*)componentsJoinedByString: (OFString*)separator







{
	OFAutoreleasePool *pool, *pool2;
	OFMutableString *ret;
	id *cArray;
	size_t i, count = [self count];
	IMP append;

	if (count == 0)
		return @"";
	if (count == 1)
		return [[self firstObject] description];

	ret = [OFMutableString string];
	append = [ret methodForSelector: @selector(appendString:)];

	pool = [[OFAutoreleasePool alloc] init];
	cArray = [self cArray];

	pool2 = [[OFAutoreleasePool alloc] init];

	for (i = 0; i < count - 1; i++) {
		append(ret, @selector(appendString:), [cArray[i] description]);

		append(ret, @selector(appendString:), separator);

		[pool2 releaseObjects];
	}
	append(ret, @selector(appendString:), [cArray[i] description]);


	[ret makeImmutable];

	[pool release];

	return ret;
}







>
>
>
>
>
>
>










|










|
>




|
>







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
		[self freeMemory: buffer];
	}

	return ret;
}

- (OFString*)componentsJoinedByString: (OFString*)separator
{
	return [self componentsJoinedByString: separator
				usingSelector: @selector(description)];
}

- (OFString*)componentsJoinedByString: (OFString*)separator
			usingSelector: (SEL)selector
{
	OFAutoreleasePool *pool, *pool2;
	OFMutableString *ret;
	id *cArray;
	size_t i, count = [self count];
	IMP append;

	if (count == 0)
		return @"";
	if (count == 1)
		return [[self firstObject] performSelector: selector];

	ret = [OFMutableString string];
	append = [ret methodForSelector: @selector(appendString:)];

	pool = [[OFAutoreleasePool alloc] init];
	cArray = [self cArray];

	pool2 = [[OFAutoreleasePool alloc] init];

	for (i = 0; i < count - 1; i++) {
		append(ret, @selector(appendString:),
		    [cArray[i] performSelector: selector]);
		append(ret, @selector(appendString:), separator);

		[pool2 releaseObjects];
	}
	append(ret, @selector(appendString:),
	    [cArray[i] performSelector: selector]);

	[ret makeImmutable];

	[pool release];

	return ret;
}
500
501
502
503
504
505
506



















507
508
509
510
511
512
513

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}




















- (void)makeObjectsPerformSelector: (SEL)selector
{
	id *cArray = [self cArray];
	size_t i, count = [self count];

	for (i = 0; i < count; i++)







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}

- (OFString*)JSONRepresentation
{
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
	OFMutableString *JSON;

	JSON = [[self componentsJoinedByString: @","
				 usingSelector: @selector(JSONRepresentation)]
	    mutableCopy];
	[pool release];
	[JSON autorelease];

	[JSON prependString: @"["];
	[JSON appendString: @"]"];

	[JSON makeImmutable];

	return JSON;
}

- (void)makeObjectsPerformSelector: (SEL)selector
{
	id *cArray = [self cArray];
	size_t i, count = [self count];

	for (i = 0; i < count; i++)

Modified src/OFDictionary.h from [49fd4f5b5a] to [944558101d].

16
17
18
19
20
21
22

23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

#include <stdarg.h>

#import "OFObject.h"
#import "OFCollection.h"
#import "OFEnumerator.h"
#import "OFSerialization.h"


@class OFArray;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_dictionary_enumeration_block_t)(id key, id object,
     BOOL *stop);
typedef BOOL (^of_dictionary_filter_block_t)(id key, id object);
typedef id (^of_dictionary_map_block_t)(id key, id object);
#endif

/**
 * \brief An abstract class for storing objects in a dictionary.
 *
 * Keys are copied and thus must conform to the OFCopying protocol.
 *
 * Note: Fast enumeration on a dictionary enumerates through the keys of the
 * dictionary.
 */
@interface OFDictionary: OFObject <OFCopying, OFMutableCopying, OFCollection,
    OFSerialization>
/**
 * \brief Creates a new OFDictionary.
 *
 * \return A new autoreleased OFDictionary
 */
+ dictionary;








>



















|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

#include <stdarg.h>

#import "OFObject.h"
#import "OFCollection.h"
#import "OFEnumerator.h"
#import "OFSerialization.h"
#import "OFJSON.h"

@class OFArray;

#ifdef OF_HAVE_BLOCKS
typedef void (^of_dictionary_enumeration_block_t)(id key, id object,
     BOOL *stop);
typedef BOOL (^of_dictionary_filter_block_t)(id key, id object);
typedef id (^of_dictionary_map_block_t)(id key, id object);
#endif

/**
 * \brief An abstract class for storing objects in a dictionary.
 *
 * Keys are copied and thus must conform to the OFCopying protocol.
 *
 * Note: Fast enumeration on a dictionary enumerates through the keys of the
 * dictionary.
 */
@interface OFDictionary: OFObject <OFCopying, OFMutableCopying, OFCollection,
    OFSerialization, OFJSON>
/**
 * \brief Creates a new OFDictionary.
 *
 * \return A new autoreleased OFDictionary
 */
+ dictionary;

Modified src/OFDictionary.m from [8d738e01c8] to [fa0065ee5f].

538
539
540
541
542
543
544
































545

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}
































@end







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}

- (OFString*)JSONRepresentation
{
	OFMutableString *JSON = [OFMutableString stringWithString: @"{"];
	OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init], *pool2;
	OFEnumerator *keyEnumerator = [self keyEnumerator];
	OFEnumerator *objectEnumerator = [self objectEnumerator];
	size_t i = 0, count = [self count];
	OFString *key;
	OFString *object;

	pool2 = [[OFAutoreleasePool alloc] init];

	while ((key = [keyEnumerator nextObject]) != nil &&
	    (object = [objectEnumerator nextObject]) != nil) {
		[JSON appendString: [key JSONRepresentation]];
		[JSON appendString: @":"];
		[JSON appendString: [object JSONRepresentation]];

		if (++i < count)
			[JSON appendString: @","];

		[pool2 releaseObjects];
	}

	[pool release];

	[JSON appendString: @"}"];
	[JSON makeImmutable];

	return JSON;
}
@end

Added src/OFJSON.h version [ec0c31fdfa].



























































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
 * Copyright (c) 2008, 2009, 2010, 2011
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

@class OFString;

/**
 * \brief A category implemented by classes that support a JSON representation.
 */
@protocol OFJSON
/**
 * \brief Returns the JSON representation of the object as a string.
 *
 * \return The JSON representation of the object as a string.
 */
- (OFString*)JSONRepresentation;
@end

Modified src/OFNull.h from [5dd85e8d3c] to [b87e070d6d].

12
13
14
15
16
17
18

19
20
21
22
23
24
25
26
27
28
29
30
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFSerialization.h"


/**
 * \brief A class for representing null values in collections.
 */
@interface OFNull: OFObject <OFCopying, OFSerialization>
/**
 * \brief Returns an OFNull singleton.
 *
 * \return An OFNull singleton
 */
+ null;
@end







>




|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFSerialization.h"
#import "OFJSON.h"

/**
 * \brief A class for representing null values in collections.
 */
@interface OFNull: OFObject <OFCopying, OFSerialization, OFJSON>
/**
 * \brief Returns an OFNull singleton.
 *
 * \return An OFNull singleton
 */
+ null;
@end

Modified src/OFNull.m from [6eac9873fd] to [ea32d25e3f].

75
76
77
78
79
80
81





82
83
84
85
86
87
88

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}






- autorelease
{
	return self;
}

- retain







>
>
>
>
>







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}

- (OFString*)JSONRepresentation
{
	return @"null";
}

- autorelease
{
	return self;
}

- retain

Modified src/OFNumber.h from [6c0dda2992] to [434b0d067a].

14
15
16
17
18
19
20

21
22
23
24
25
26
27
 * file.
 */

#include <sys/types.h>

#import "OFObject.h"
#import "OFSerialization.h"


/**
 * \brief The type of a number.
 */
typedef enum of_number_type_t {
	OF_NUMBER_BOOL,
	OF_NUMBER_CHAR,







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * file.
 */

#include <sys/types.h>

#import "OFObject.h"
#import "OFSerialization.h"
#import "OFJSON.h"

/**
 * \brief The type of a number.
 */
typedef enum of_number_type_t {
	OF_NUMBER_BOOL,
	OF_NUMBER_CHAR,
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
	OF_NUMBER_FLOAT,
	OF_NUMBER_DOUBLE,
} of_number_type_t;

/**
 * \brief Provides a way to store a number in an object.
 */
@interface OFNumber: OFObject <OFCopying, OFSerialization>
{
	union of_number_value {
		BOOL	       bool_;
		signed char    char_;
		signed short   short_;
		signed int     int_;
		signed long    long_;







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
	OF_NUMBER_FLOAT,
	OF_NUMBER_DOUBLE,
} of_number_type_t;

/**
 * \brief Provides a way to store a number in an object.
 */
@interface OFNumber: OFObject <OFCopying, OFSerialization, OFJSON>
{
	union of_number_value {
		BOOL	       bool_;
		signed char    char_;
		signed short   short_;
		signed int     int_;
		signed long    long_;

Modified src/OFNumber.m from [5cb0489783] to [388be18efd].

1237
1238
1239
1240
1241
1242
1243








1244

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}








@end







>
>
>
>
>
>
>
>

1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}

- (OFString*)JSONRepresentation
{
	if (type == OF_NUMBER_BOOL)
		return (value.bool_ ? @"true" : @"false");

	return [self description];
}
@end

Modified src/OFString.h from [8719bc5cf6] to [63071797b5].

16
17
18
19
20
21
22

23
24
25
26
27
28
29

#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>

#import "OFObject.h"
#import "OFSerialization.h"


#import "macros.h"

@class OFConstantString;

typedef uint32_t of_unichar_t;








>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>

#import "OFObject.h"
#import "OFSerialization.h"
#import "OFJSON.h"

#import "macros.h"

@class OFConstantString;

typedef uint32_t of_unichar_t;

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 * <b>Warning:</b> If you add methods to OFString using a category, you are not
 * allowed to access the ivars directly, as these might be still uninitialized
 * for a constant string and get initialized on the first message! Therefore,
 * you should use the corresponding methods to get the ivars, which ensures the
 * constant string is initialized.
 */
@interface OFString: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFSerialization>
#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t length;
#endif

/**
 * \brief Creates a new OFString.
 *







|







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
 * <b>Warning:</b> If you add methods to OFString using a category, you are not
 * allowed to access the ivars directly, as these might be still uninitialized
 * for a constant string and get initialized on the first message! Therefore,
 * you should use the corresponding methods to get the ivars, which ensures the
 * constant string is initialized.
 */
@interface OFString: OFObject <OFCopying, OFMutableCopying, OFComparing,
    OFSerialization, OFJSON>
#ifdef OF_HAVE_PROPERTIES
@property (readonly) size_t length;
#endif

/**
 * \brief Creates a new OFString.
 *

Modified src/OFString.m from [598d9c6c56] to [ff90d8d582].

1133
1134
1135
1136
1137
1138
1139




























1140
1141
1142
1143
1144
1145
1146

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}





























- (size_t)indexOfFirstOccurrenceOfString: (OFString*)string
{
	OFAutoreleasePool *pool;
	const of_unichar_t *unicodeString, *searchString;
	size_t i, length, searchLength;








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174

	[element retain];
	[pool release];
	[element autorelease];

	return element;
}

- (OFString*)JSONRepresentation
{
	OFMutableString *JSON = [[self mutableCopy] autorelease];

	/* FIXME: This is slow! Write it in pure C! */
	[JSON replaceOccurrencesOfString: @"\\"
			      withString: @"\\\\"];
	[JSON replaceOccurrencesOfString: @"\""
			      withString: @"\\\""];
	[JSON replaceOccurrencesOfString: @"\b"
			      withString: @"\\b"];
	[JSON replaceOccurrencesOfString: @"\f"
			      withString: @"\\f"];
	[JSON replaceOccurrencesOfString: @"\n"
			      withString: @"\\n"];
	[JSON replaceOccurrencesOfString: @"\r"
			      withString: @"\\r"];
	[JSON replaceOccurrencesOfString: @"\t"
			      withString: @"\\t"];

	[JSON prependString: @"\""];
	[JSON appendString: @"\""];

	[JSON makeImmutable];

	return JSON;
}

- (size_t)indexOfFirstOccurrenceOfString: (OFString*)string
{
	OFAutoreleasePool *pool;
	const of_unichar_t *unicodeString, *searchString;
	size_t i, length, searchLength;