︙ | | | ︙ | |
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#import "OFNull.h"
#import "OFInvalidJSONException.h"
int _OFString_JSONValue_reference;
static id nextObject(const char **pointer, const char *stop, size_t *line,
size_t depth, size_t depthLimit);
static void
skipWhitespaces(const char **pointer, const char *stop, size_t *line)
{
while (*pointer < stop && (**pointer == ' ' || **pointer == '\t' ||
**pointer == '\r' || **pointer == '\n')) {
if (**pointer == '\n')
|
|
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
#import "OFNull.h"
#import "OFInvalidJSONException.h"
int _OFString_JSONValue_reference;
static id nextObject(const char **pointer, const char *stop, size_t *line,
size_t depthLimit);
static void
skipWhitespaces(const char **pointer, const char *stop, size_t *line)
{
while (*pointer < stop && (**pointer == ' ' || **pointer == '\t' ||
**pointer == '\r' || **pointer == '\n')) {
if (**pointer == '\n')
|
︙ | | | ︙ | |
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
* reach stop.
*/
return nil;
}
static inline OFMutableArray *
parseArray(const char **pointer, const char *stop, size_t *line,
size_t depth, size_t depthLimit)
{
OFMutableArray *array = [OFMutableArray array];
if (++(*pointer) >= stop)
return nil;
if (++depth > depthLimit)
return nil;
while (**pointer != ']') {
id object;
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
|
|
|
|
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
* reach stop.
*/
return nil;
}
static inline OFMutableArray *
parseArray(const char **pointer, const char *stop, size_t *line,
size_t depthLimit)
{
OFMutableArray *array = [OFMutableArray array];
if (++(*pointer) >= stop)
return nil;
if (--depthLimit == 0)
return nil;
while (**pointer != ']') {
id object;
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
|
︙ | | | ︙ | |
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
if (*pointer >= stop || **pointer != ']')
return nil;
break;
}
object = nextObject(pointer, stop, line, depth, depthLimit);
if (object == nil)
return nil;
[array addObject: object];
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
|
|
|
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
if (*pointer >= stop || **pointer != ']')
return nil;
break;
}
object = nextObject(pointer, stop, line, depthLimit);
if (object == nil)
return nil;
[array addObject: object];
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
|
︙ | | | ︙ | |
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
|
(*pointer)++;
return array;
}
static inline OFMutableDictionary *
parseDictionary(const char **pointer, const char *stop, size_t *line,
size_t depth, size_t depthLimit)
{
OFMutableDictionary *dictionary = [OFMutableDictionary dictionary];
if (++(*pointer) >= stop)
return nil;
if (++depth > depthLimit)
return nil;
while (**pointer != '}') {
id key, object;
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
|
|
|
|
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
|
(*pointer)++;
return array;
}
static inline OFMutableDictionary *
parseDictionary(const char **pointer, const char *stop, size_t *line,
size_t depthLimit)
{
OFMutableDictionary *dictionary = [OFMutableDictionary dictionary];
if (++(*pointer) >= stop)
return nil;
if (--depthLimit == 0)
return nil;
while (**pointer != '}') {
id key, object;
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
|
︙ | | | ︙ | |
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
|
return nil;
if ((**pointer >= 'a' && **pointer <= 'z') ||
(**pointer >= 'A' && **pointer <= 'Z') ||
**pointer == '_' || **pointer == '$' || **pointer == '\\')
key = parseIdentifier(pointer, stop);
else
key = nextObject(pointer, stop, line,
depth, depthLimit);
if (key == nil)
return nil;
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer + 1 >= stop || **pointer != ':')
return nil;
(*pointer)++;
object = nextObject(pointer, stop, line, depth, depthLimit);
if (object == nil)
return nil;
[dictionary setObject: object
forKey: key];
skipWhitespacesAndComments(pointer, stop, line);
|
|
<
|
|
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
|
return nil;
if ((**pointer >= 'a' && **pointer <= 'z') ||
(**pointer >= 'A' && **pointer <= 'Z') ||
**pointer == '_' || **pointer == '$' || **pointer == '\\')
key = parseIdentifier(pointer, stop);
else
key = nextObject(pointer, stop, line, depthLimit);
if (key == nil)
return nil;
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer + 1 >= stop || **pointer != ':')
return nil;
(*pointer)++;
object = nextObject(pointer, stop, line, depthLimit);
if (object == nil)
return nil;
[dictionary setObject: object
forKey: key];
skipWhitespacesAndComments(pointer, stop, line);
|
︙ | | | ︙ | |
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
|
}
return number;
}
static id
nextObject(const char **pointer, const char *stop, size_t *line,
size_t depth, size_t depthLimit)
{
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
return nil;
switch (**pointer) {
case '"':
case '\'':
return parseString(pointer, stop, line);
case '[':
return parseArray(pointer, stop, line, depth, depthLimit);
case '{':
return parseDictionary(pointer, stop, line, depth, depthLimit);
case 't':
if (*pointer + 3 >= stop)
return nil;
if (memcmp(*pointer, "true", 4) != 0)
return nil;
|
|
|
|
|
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
|
}
return number;
}
static id
nextObject(const char **pointer, const char *stop, size_t *line,
size_t depthLimit)
{
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
return nil;
switch (**pointer) {
case '"':
case '\'':
return parseString(pointer, stop, line);
case '[':
return parseArray(pointer, stop, line, depthLimit);
case '{':
return parseDictionary(pointer, stop, line, depthLimit);
case 't':
if (*pointer + 3 >= stop)
return nil;
if (memcmp(*pointer, "true", 4) != 0)
return nil;
|
︙ | | | ︙ | |
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
|
{
void *pool = objc_autoreleasePoolPush();
const char *pointer = [self UTF8String];
const char *stop = pointer + [self UTF8StringLength];
id object;
size_t line = 1;
object = nextObject(&pointer, stop, &line, 0, depthLimit);
skipWhitespacesAndComments(&pointer, stop, &line);
if (pointer < stop || object == nil)
@throw [OFInvalidJSONException exceptionWithString: self
line: line];
[object retain];
objc_autoreleasePoolPop(pool);
return [object autorelease];
}
@end
|
|
|
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
|
{
void *pool = objc_autoreleasePoolPush();
const char *pointer = [self UTF8String];
const char *stop = pointer + [self UTF8StringLength];
id object;
size_t line = 1;
object = nextObject(&pointer, stop, &line, depthLimit);
skipWhitespacesAndComments(&pointer, stop, &line);
if (pointer < stop || object == nil)
@throw [OFInvalidJSONException exceptionWithString: self
line: line];
[object retain];
objc_autoreleasePoolPop(pool);
return [object autorelease];
}
@end
|