@@ -40,10 +40,63 @@ { while (*pointer < stop && (**pointer == ' ' || **pointer == '\t' || **pointer == '\r' || **pointer == '\n')) (*pointer)++; } + +static void +skipComment(const char *restrict *pointer, const char *stop) +{ + if (**pointer != '/') + return; + + if (*pointer + 1 >= stop) + return; + + (*pointer)++; + + if (**pointer == '*') { + BOOL lastIsAsterisk = NO; + + (*pointer)++; + + while (*pointer < stop) { + if (lastIsAsterisk && **pointer == '/') { + (*pointer)++; + return; + } + + lastIsAsterisk = (**pointer == '*'); + + (*pointer)++; + } + } else { + (*pointer)++; + + while (*pointer < stop) { + if (**pointer == '\r' || **pointer == '\n') { + (*pointer)++; + return; + } + + (*pointer)++; + } + } +} + +static void +skipWhitespacesAndComments(const char *restrict *pointer, const char *stop) +{ + const char *old = NULL; + + while (old != *pointer) { + old = *pointer; + + skipWhitespaces(pointer, stop); + skipComment(pointer, stop); + } +} static OF_INLINE uint16_t parseUnicodeEscape(const char *pointer, const char *stop) { uint16_t ret = 0; @@ -215,11 +268,11 @@ return nil; while (**pointer != ']') { id object; - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer >= stop) return nil; if (**pointer == ']') break; @@ -227,17 +280,17 @@ if ((object = nextObject(pointer, stop)) == nil) return nil; [array addObject: object]; - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer >= stop) return nil; if (**pointer == ',') { (*pointer)++; - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer >= stop) return nil; } else if (**pointer != ']') return nil; @@ -259,21 +312,21 @@ return nil; while (**pointer != '}') { id key, object; - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer >= stop) return nil; if (**pointer == '}') break; if ((key = nextObject(pointer, stop)) == nil) return nil; - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer + 1 >= stop || **pointer != ':') return nil; (*pointer)++; @@ -281,17 +334,17 @@ return nil; [dictionary setObject: object forKey: key]; - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer >= stop) return nil; if (**pointer == ',') { (*pointer)++; - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer >= stop) return nil; } else if (**pointer != '}') return nil; @@ -342,11 +395,11 @@ } static id nextObject(const char *restrict *pointer, const char *stop) { - skipWhitespaces(pointer, stop); + skipWhitespacesAndComments(pointer, stop); if (*pointer >= stop) return nil; switch (**pointer) { @@ -409,13 +462,13 @@ const char *pointer = [self UTF8String]; const char *stop = pointer + [self UTF8StringLength]; id object; object = nextObject(&pointer, stop); - skipWhitespaces(&pointer, stop); + skipWhitespacesAndComments(&pointer, stop); if (pointer < stop || object == nil) @throw [OFInvalidEncodingException exceptionWithClass: isa]; return object; } @end