︙ | | |
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
-
+
|
#import "OFInvalidJSONException.h"
#import "macros.h"
int _OFString_JSONValue_reference;
static id nextObject(const char *restrict *, const char*,
size_t *restrict line);
size_t *restrict line, size_t depth, size_t depthLimit);
static void
skipWhitespaces(const char *restrict *pointer, const char *stop,
size_t *restrict line)
{
while (*pointer < stop && (**pointer == ' ' || **pointer == '\t' ||
**pointer == '\r' || **pointer == '\n')) {
|
︙ | | |
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
|
-
+
+
+
+
|
* reach stop.
*/
return nil;
}
static inline OFMutableArray*
parseArray(const char *restrict *pointer, const char *stop,
size_t *restrict line)
size_t *restrict 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)
return nil;
|
︙ | | |
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
|
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
|
-
+
+
|
if (*pointer >= stop || **pointer != ']')
return nil;
break;
}
if ((object = nextObject(pointer, stop, line)) == nil)
object = nextObject(pointer, stop, line, depth, depthLimit);
if (object == nil)
return nil;
[array addObject: object];
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
return nil;
|
︙ | | |
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
|
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
|
-
+
+
+
+
|
(*pointer)++;
return array;
}
static inline OFMutableDictionary*
parseDictionary(const char *restrict *pointer, const char *stop,
size_t *restrict line)
size_t *restrict 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)
return nil;
|
︙ | | |
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
|
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
509
510
511
|
-
+
+
-
+
+
|
return nil;
if ((**pointer >= 'a' && **pointer <= 'z') ||
(**pointer >= 'A' && **pointer <= 'Z') ||
**pointer == '_' || **pointer == '$' || **pointer == '\\')
key = parseIdentifier(pointer, stop);
else
key = nextObject(pointer, stop, line);
key = nextObject(pointer, stop, line,
depth, depthLimit);
if (key == nil)
return nil;
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer + 1 >= stop || **pointer != ':')
return nil;
(*pointer)++;
if ((object = nextObject(pointer, stop, line)) == nil)
object = nextObject(pointer, stop, line, depth, depthLimit);
if (object == nil)
return nil;
[dictionary setObject: object
forKey: key];
skipWhitespacesAndComments(pointer, stop, line);
if (*pointer >= stop)
|
︙ | | |
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
|
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 *restrict *pointer, const char *stop,
size_t *restrict line)
size_t *restrict 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);
return parseArray(pointer, stop, line, depth, depthLimit);
case '{':
return parseDictionary(pointer, stop, line);
return parseDictionary(pointer, stop, line, depth, depthLimit);
case 't':
if (*pointer + 3 >= stop)
return nil;
if (memcmp(*pointer, "true", 4))
return nil;
|
︙ | | |
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
|
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
|
+
+
+
+
+
-
+
|
return nil;
}
}
@implementation OFString (JSONValue)
- (id)JSONValue
{
return [self JSONValueWithDepthLimit: 32];
}
- (id)JSONValueWithDepthLimit: (size_t)depthLimit
{
const char *pointer = [self UTF8String];
const char *stop = pointer + [self UTF8StringLength];
id object;
size_t line = 1;
object = nextObject(&pointer, stop, &line);
object = nextObject(&pointer, stop, &line, 0, depthLimit);
skipWhitespacesAndComments(&pointer, stop, &line);
if (pointer < stop || object == nil)
@throw [OFInvalidJSONException exceptionWithClass: [self class]
line: line];
return object;
}
@end
|