inline Iterator parseObject(Iterator begin, Iterator end, ObjectBodyParser objectBodyParser, ErrorHandler &errorHandler) { Iterator i = skipLeadingSpaces<spacePolicy>(begin, end); if (unlikely(i == end)) { goto prematureEnd; } if (unlikely(*i != u8"{"[0])) { goto malformedJson; } i = objectBodyParser(++i, end, errorHandler); if (unlikely(!errorHandler.valid())) { return end; } if (unlikely(i == end)) { goto prematureEnd; } if (unlikely(*i != u8"}"[0])) { goto malformedJson; } return skipTrailingSpaces<spacePolicy>(++i, end); prematureEnd: errorHandler.prematureEnd(); return end; malformedJson: errorHandler.malformedJson(i); return end; }
inline Iterator parseComma(Iterator begin, Iterator end, ErrorHandler &errorHandler) { Iterator i = skipLeadingSpaces<spacePolicy>(begin, end); if (unlikely(i == end)) { errorHandler.prematureEnd(); return end; } if (unlikely(*i != u8","[0])) { errorHandler.malformedJson(i); return i; } return skipTrailingSpaces<spacePolicy>(++i, end); }
inline Iterator parsePropertyValue(Iterator begin, Iterator end, const char * const propName, const std::size_t propNameSize, ValueParser valueParser, ErrorHandler &errorHandler) { Iterator i = skipLeadingSpaces<spacePolicy>(begin, end); // TODO optimise property name matching const char *realPropNameBegin; std::size_t realPropNameSize; auto propNameParser = [&](const char * const begin, const char * const end, ErrorHandler &errorHandler) -> const char * { // TODO support quotation marks in property name (make it optional for better performance. realPropNameBegin = begin; const char * const propNameEnd = std::find(begin, end, u8"\""[0]); realPropNameSize = propNameEnd - realPropNameBegin; return propNameEnd; }; // TODO support forward iterators; combine scanning and comparing into a single loop. i = afc::json::parseString<const char *, decltype(propNameParser) &, ErrorHandler, afc::json::noSpaces> (i, end, propNameParser, errorHandler); if (unlikely(!errorHandler.valid())) { return end; } if (unlikely(!afc::equal(propName, propNameSize, realPropNameBegin, realPropNameSize))) { errorHandler.malformedJson(i); return end; } i = afc::json::parseColon<const char *, ErrorHandler, spacePolicy>(i, end, errorHandler); if (unlikely(!errorHandler.valid())) { return end; } i = valueParser(i, end, errorHandler); if (unlikely(!errorHandler.valid())) { return end; } return skipTrailingSpaces<spacePolicy>(i, end); }
inline typename std::enable_if<!_impl::isRandomAccessIterator<Iterator>(), Iterator>::type parseBoolean(Iterator begin, Iterator end, bool &dest, ErrorHandler &errorHandler) { Iterator i = skipLeadingSpaces<spacePolicy>(begin, end); char c; if (unlikely(i == end)) { goto prematureEnd; } c = *i; if (c == u8"t"[0]) { if (unlikely(++i == end)) goto prematureEnd; if (unlikely(*i != u8"r"[0])) goto malformedJson; if (unlikely(++i == end)) goto prematureEnd; if (unlikely(*i != u8"u"[0])) goto malformedJson; if (unlikely(++i == end)) goto prematureEnd; if (unlikely(*i != u8"e"[0])) goto malformedJson; dest = true; } else if (c == u8"f"[0]) { if (unlikely(++i == end)) goto prematureEnd; if (unlikely(*i != u8"a"[0])) goto malformedJson; if (unlikely(++i == end)) goto prematureEnd; if (unlikely(*i != u8"l"[0])) goto malformedJson; if (unlikely(++i == end)) goto prematureEnd; if (unlikely(*i != u8"s"[0])) goto malformedJson; if (unlikely(++i == end)) goto prematureEnd; if (unlikely(*i != u8"e"[0])) goto malformedJson; dest = false; } else { goto malformedJson; } return skipTrailingSpaces<spacePolicy>(++i, end); prematureEnd: errorHandler.prematureEnd(); return end; malformedJson: errorHandler.malformedJson(i); return end; }
inline Iterator parseArray(Iterator begin, Iterator end, ArrayElementParser arrayElementParser, ErrorHandler &errorHandler) { Iterator i = skipLeadingSpaces<spacePolicy>(begin, end); if (unlikely(i == end)) { goto prematureEnd; } if (unlikely(*i != u8"["[0])) { goto malformedJson; } if (unlikely(++i == end)) { goto prematureEnd; } if (*i == u8"]"[0]) { return skipTrailingSpaces<spacePolicy>(++i, end); } for (;;) { i = arrayElementParser(i, end, errorHandler); if (unlikely(!errorHandler.valid())) { return end; } if (unlikely(i == end)) { goto prematureEnd; } const char c = *i; if (c == u8"]"[0]) { return skipTrailingSpaces<spacePolicy>(++i, end); } if (likely(c == u8","[0])) { ++i; } else { goto malformedJson; } } prematureEnd: errorHandler.prematureEnd(); return end; malformedJson: errorHandler.malformedJson(i); return end; }