11cb0ef41Sopenharmony_ci// This file is generated by Parser_cpp.template. 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ci// Copyright 2016 The Chromium Authors. All rights reserved. 41cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be 51cb0ef41Sopenharmony_ci// found in the LICENSE file. 61cb0ef41Sopenharmony_ci 71cb0ef41Sopenharmony_ci{% for namespace in config.protocol.namespace %} 81cb0ef41Sopenharmony_cinamespace {{namespace}} { 91cb0ef41Sopenharmony_ci{% endfor %} 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_cinamespace { 121cb0ef41Sopenharmony_ci 131cb0ef41Sopenharmony_ciconst int stackLimit = 1000; 141cb0ef41Sopenharmony_ci 151cb0ef41Sopenharmony_cienum Token { 161cb0ef41Sopenharmony_ci ObjectBegin, 171cb0ef41Sopenharmony_ci ObjectEnd, 181cb0ef41Sopenharmony_ci ArrayBegin, 191cb0ef41Sopenharmony_ci ArrayEnd, 201cb0ef41Sopenharmony_ci StringLiteral, 211cb0ef41Sopenharmony_ci Number, 221cb0ef41Sopenharmony_ci BoolTrue, 231cb0ef41Sopenharmony_ci BoolFalse, 241cb0ef41Sopenharmony_ci NullToken, 251cb0ef41Sopenharmony_ci ListSeparator, 261cb0ef41Sopenharmony_ci ObjectPairSeparator, 271cb0ef41Sopenharmony_ci InvalidToken, 281cb0ef41Sopenharmony_ci}; 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ciconst char* const nullString = "null"; 311cb0ef41Sopenharmony_ciconst char* const trueString = "true"; 321cb0ef41Sopenharmony_ciconst char* const falseString = "false"; 331cb0ef41Sopenharmony_ci 341cb0ef41Sopenharmony_cibool isASCII(uint16_t c) 351cb0ef41Sopenharmony_ci{ 361cb0ef41Sopenharmony_ci return !(c & ~0x7F); 371cb0ef41Sopenharmony_ci} 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_cibool isSpaceOrNewLine(uint16_t c) 401cb0ef41Sopenharmony_ci{ 411cb0ef41Sopenharmony_ci return isASCII(c) && c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); 421cb0ef41Sopenharmony_ci} 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_cidouble charactersToDouble(const uint16_t* characters, size_t length, bool* ok) 451cb0ef41Sopenharmony_ci{ 461cb0ef41Sopenharmony_ci std::vector<char> buffer; 471cb0ef41Sopenharmony_ci buffer.reserve(length + 1); 481cb0ef41Sopenharmony_ci for (size_t i = 0; i < length; ++i) { 491cb0ef41Sopenharmony_ci if (!isASCII(characters[i])) { 501cb0ef41Sopenharmony_ci *ok = false; 511cb0ef41Sopenharmony_ci return 0; 521cb0ef41Sopenharmony_ci } 531cb0ef41Sopenharmony_ci buffer.push_back(static_cast<char>(characters[i])); 541cb0ef41Sopenharmony_ci } 551cb0ef41Sopenharmony_ci buffer.push_back('\0'); 561cb0ef41Sopenharmony_ci return StringUtil::toDouble(buffer.data(), length, ok); 571cb0ef41Sopenharmony_ci} 581cb0ef41Sopenharmony_ci 591cb0ef41Sopenharmony_cidouble charactersToDouble(const uint8_t* characters, size_t length, bool* ok) 601cb0ef41Sopenharmony_ci{ 611cb0ef41Sopenharmony_ci std::string buffer(reinterpret_cast<const char*>(characters), length); 621cb0ef41Sopenharmony_ci return StringUtil::toDouble(buffer.data(), length, ok); 631cb0ef41Sopenharmony_ci} 641cb0ef41Sopenharmony_ci 651cb0ef41Sopenharmony_citemplate<typename Char> 661cb0ef41Sopenharmony_cibool parseConstToken(const Char* start, const Char* end, const Char** tokenEnd, const char* token) 671cb0ef41Sopenharmony_ci{ 681cb0ef41Sopenharmony_ci while (start < end && *token != '\0' && *start++ == *token++) { } 691cb0ef41Sopenharmony_ci if (*token != '\0') 701cb0ef41Sopenharmony_ci return false; 711cb0ef41Sopenharmony_ci *tokenEnd = start; 721cb0ef41Sopenharmony_ci return true; 731cb0ef41Sopenharmony_ci} 741cb0ef41Sopenharmony_ci 751cb0ef41Sopenharmony_citemplate<typename Char> 761cb0ef41Sopenharmony_cibool readInt(const Char* start, const Char* end, const Char** tokenEnd, bool canHaveLeadingZeros) 771cb0ef41Sopenharmony_ci{ 781cb0ef41Sopenharmony_ci if (start == end) 791cb0ef41Sopenharmony_ci return false; 801cb0ef41Sopenharmony_ci bool haveLeadingZero = '0' == *start; 811cb0ef41Sopenharmony_ci int length = 0; 821cb0ef41Sopenharmony_ci while (start < end && '0' <= *start && *start <= '9') { 831cb0ef41Sopenharmony_ci ++start; 841cb0ef41Sopenharmony_ci ++length; 851cb0ef41Sopenharmony_ci } 861cb0ef41Sopenharmony_ci if (!length) 871cb0ef41Sopenharmony_ci return false; 881cb0ef41Sopenharmony_ci if (!canHaveLeadingZeros && length > 1 && haveLeadingZero) 891cb0ef41Sopenharmony_ci return false; 901cb0ef41Sopenharmony_ci *tokenEnd = start; 911cb0ef41Sopenharmony_ci return true; 921cb0ef41Sopenharmony_ci} 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_citemplate<typename Char> 951cb0ef41Sopenharmony_cibool parseNumberToken(const Char* start, const Char* end, const Char** tokenEnd) 961cb0ef41Sopenharmony_ci{ 971cb0ef41Sopenharmony_ci // We just grab the number here. We validate the size in DecodeNumber. 981cb0ef41Sopenharmony_ci // According to RFC4627, a valid number is: [minus] int [frac] [exp] 991cb0ef41Sopenharmony_ci if (start == end) 1001cb0ef41Sopenharmony_ci return false; 1011cb0ef41Sopenharmony_ci Char c = *start; 1021cb0ef41Sopenharmony_ci if ('-' == c) 1031cb0ef41Sopenharmony_ci ++start; 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci if (!readInt(start, end, &start, false)) 1061cb0ef41Sopenharmony_ci return false; 1071cb0ef41Sopenharmony_ci if (start == end) { 1081cb0ef41Sopenharmony_ci *tokenEnd = start; 1091cb0ef41Sopenharmony_ci return true; 1101cb0ef41Sopenharmony_ci } 1111cb0ef41Sopenharmony_ci 1121cb0ef41Sopenharmony_ci // Optional fraction part 1131cb0ef41Sopenharmony_ci c = *start; 1141cb0ef41Sopenharmony_ci if ('.' == c) { 1151cb0ef41Sopenharmony_ci ++start; 1161cb0ef41Sopenharmony_ci if (!readInt(start, end, &start, true)) 1171cb0ef41Sopenharmony_ci return false; 1181cb0ef41Sopenharmony_ci if (start == end) { 1191cb0ef41Sopenharmony_ci *tokenEnd = start; 1201cb0ef41Sopenharmony_ci return true; 1211cb0ef41Sopenharmony_ci } 1221cb0ef41Sopenharmony_ci c = *start; 1231cb0ef41Sopenharmony_ci } 1241cb0ef41Sopenharmony_ci 1251cb0ef41Sopenharmony_ci // Optional exponent part 1261cb0ef41Sopenharmony_ci if ('e' == c || 'E' == c) { 1271cb0ef41Sopenharmony_ci ++start; 1281cb0ef41Sopenharmony_ci if (start == end) 1291cb0ef41Sopenharmony_ci return false; 1301cb0ef41Sopenharmony_ci c = *start; 1311cb0ef41Sopenharmony_ci if ('-' == c || '+' == c) { 1321cb0ef41Sopenharmony_ci ++start; 1331cb0ef41Sopenharmony_ci if (start == end) 1341cb0ef41Sopenharmony_ci return false; 1351cb0ef41Sopenharmony_ci } 1361cb0ef41Sopenharmony_ci if (!readInt(start, end, &start, true)) 1371cb0ef41Sopenharmony_ci return false; 1381cb0ef41Sopenharmony_ci } 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci *tokenEnd = start; 1411cb0ef41Sopenharmony_ci return true; 1421cb0ef41Sopenharmony_ci} 1431cb0ef41Sopenharmony_ci 1441cb0ef41Sopenharmony_citemplate<typename Char> 1451cb0ef41Sopenharmony_cibool readHexDigits(const Char* start, const Char* end, const Char** tokenEnd, int digits) 1461cb0ef41Sopenharmony_ci{ 1471cb0ef41Sopenharmony_ci if (end - start < digits) 1481cb0ef41Sopenharmony_ci return false; 1491cb0ef41Sopenharmony_ci for (int i = 0; i < digits; ++i) { 1501cb0ef41Sopenharmony_ci Char c = *start++; 1511cb0ef41Sopenharmony_ci if (!(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F'))) 1521cb0ef41Sopenharmony_ci return false; 1531cb0ef41Sopenharmony_ci } 1541cb0ef41Sopenharmony_ci *tokenEnd = start; 1551cb0ef41Sopenharmony_ci return true; 1561cb0ef41Sopenharmony_ci} 1571cb0ef41Sopenharmony_ci 1581cb0ef41Sopenharmony_citemplate<typename Char> 1591cb0ef41Sopenharmony_cibool parseStringToken(const Char* start, const Char* end, const Char** tokenEnd) 1601cb0ef41Sopenharmony_ci{ 1611cb0ef41Sopenharmony_ci while (start < end) { 1621cb0ef41Sopenharmony_ci Char c = *start++; 1631cb0ef41Sopenharmony_ci if ('\\' == c) { 1641cb0ef41Sopenharmony_ci if (start == end) 1651cb0ef41Sopenharmony_ci return false; 1661cb0ef41Sopenharmony_ci c = *start++; 1671cb0ef41Sopenharmony_ci // Make sure the escaped char is valid. 1681cb0ef41Sopenharmony_ci switch (c) { 1691cb0ef41Sopenharmony_ci case 'x': 1701cb0ef41Sopenharmony_ci if (!readHexDigits(start, end, &start, 2)) 1711cb0ef41Sopenharmony_ci return false; 1721cb0ef41Sopenharmony_ci break; 1731cb0ef41Sopenharmony_ci case 'u': 1741cb0ef41Sopenharmony_ci if (!readHexDigits(start, end, &start, 4)) 1751cb0ef41Sopenharmony_ci return false; 1761cb0ef41Sopenharmony_ci break; 1771cb0ef41Sopenharmony_ci case '\\': 1781cb0ef41Sopenharmony_ci case '/': 1791cb0ef41Sopenharmony_ci case 'b': 1801cb0ef41Sopenharmony_ci case 'f': 1811cb0ef41Sopenharmony_ci case 'n': 1821cb0ef41Sopenharmony_ci case 'r': 1831cb0ef41Sopenharmony_ci case 't': 1841cb0ef41Sopenharmony_ci case 'v': 1851cb0ef41Sopenharmony_ci case '"': 1861cb0ef41Sopenharmony_ci break; 1871cb0ef41Sopenharmony_ci default: 1881cb0ef41Sopenharmony_ci return false; 1891cb0ef41Sopenharmony_ci } 1901cb0ef41Sopenharmony_ci } else if ('"' == c) { 1911cb0ef41Sopenharmony_ci *tokenEnd = start; 1921cb0ef41Sopenharmony_ci return true; 1931cb0ef41Sopenharmony_ci } 1941cb0ef41Sopenharmony_ci } 1951cb0ef41Sopenharmony_ci return false; 1961cb0ef41Sopenharmony_ci} 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_citemplate<typename Char> 1991cb0ef41Sopenharmony_cibool skipComment(const Char* start, const Char* end, const Char** commentEnd) 2001cb0ef41Sopenharmony_ci{ 2011cb0ef41Sopenharmony_ci if (start == end) 2021cb0ef41Sopenharmony_ci return false; 2031cb0ef41Sopenharmony_ci 2041cb0ef41Sopenharmony_ci if (*start != '/' || start + 1 >= end) 2051cb0ef41Sopenharmony_ci return false; 2061cb0ef41Sopenharmony_ci ++start; 2071cb0ef41Sopenharmony_ci 2081cb0ef41Sopenharmony_ci if (*start == '/') { 2091cb0ef41Sopenharmony_ci // Single line comment, read to newline. 2101cb0ef41Sopenharmony_ci for (++start; start < end; ++start) { 2111cb0ef41Sopenharmony_ci if (*start == '\n' || *start == '\r') { 2121cb0ef41Sopenharmony_ci *commentEnd = start + 1; 2131cb0ef41Sopenharmony_ci return true; 2141cb0ef41Sopenharmony_ci } 2151cb0ef41Sopenharmony_ci } 2161cb0ef41Sopenharmony_ci *commentEnd = end; 2171cb0ef41Sopenharmony_ci // Comment reaches end-of-input, which is fine. 2181cb0ef41Sopenharmony_ci return true; 2191cb0ef41Sopenharmony_ci } 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci if (*start == '*') { 2221cb0ef41Sopenharmony_ci Char previous = '\0'; 2231cb0ef41Sopenharmony_ci // Block comment, read until end marker. 2241cb0ef41Sopenharmony_ci for (++start; start < end; previous = *start++) { 2251cb0ef41Sopenharmony_ci if (previous == '*' && *start == '/') { 2261cb0ef41Sopenharmony_ci *commentEnd = start + 1; 2271cb0ef41Sopenharmony_ci return true; 2281cb0ef41Sopenharmony_ci } 2291cb0ef41Sopenharmony_ci } 2301cb0ef41Sopenharmony_ci // Block comment must close before end-of-input. 2311cb0ef41Sopenharmony_ci return false; 2321cb0ef41Sopenharmony_ci } 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci return false; 2351cb0ef41Sopenharmony_ci} 2361cb0ef41Sopenharmony_ci 2371cb0ef41Sopenharmony_citemplate<typename Char> 2381cb0ef41Sopenharmony_civoid skipWhitespaceAndComments(const Char* start, const Char* end, const Char** whitespaceEnd) 2391cb0ef41Sopenharmony_ci{ 2401cb0ef41Sopenharmony_ci while (start < end) { 2411cb0ef41Sopenharmony_ci if (isSpaceOrNewLine(*start)) { 2421cb0ef41Sopenharmony_ci ++start; 2431cb0ef41Sopenharmony_ci } else if (*start == '/') { 2441cb0ef41Sopenharmony_ci const Char* commentEnd; 2451cb0ef41Sopenharmony_ci if (!skipComment(start, end, &commentEnd)) 2461cb0ef41Sopenharmony_ci break; 2471cb0ef41Sopenharmony_ci start = commentEnd; 2481cb0ef41Sopenharmony_ci } else { 2491cb0ef41Sopenharmony_ci break; 2501cb0ef41Sopenharmony_ci } 2511cb0ef41Sopenharmony_ci } 2521cb0ef41Sopenharmony_ci *whitespaceEnd = start; 2531cb0ef41Sopenharmony_ci} 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_citemplate<typename Char> 2561cb0ef41Sopenharmony_ciToken parseToken(const Char* start, const Char* end, const Char** tokenStart, const Char** tokenEnd) 2571cb0ef41Sopenharmony_ci{ 2581cb0ef41Sopenharmony_ci skipWhitespaceAndComments(start, end, tokenStart); 2591cb0ef41Sopenharmony_ci start = *tokenStart; 2601cb0ef41Sopenharmony_ci 2611cb0ef41Sopenharmony_ci if (start == end) 2621cb0ef41Sopenharmony_ci return InvalidToken; 2631cb0ef41Sopenharmony_ci 2641cb0ef41Sopenharmony_ci switch (*start) { 2651cb0ef41Sopenharmony_ci case 'n': 2661cb0ef41Sopenharmony_ci if (parseConstToken(start, end, tokenEnd, nullString)) 2671cb0ef41Sopenharmony_ci return NullToken; 2681cb0ef41Sopenharmony_ci break; 2691cb0ef41Sopenharmony_ci case 't': 2701cb0ef41Sopenharmony_ci if (parseConstToken(start, end, tokenEnd, trueString)) 2711cb0ef41Sopenharmony_ci return BoolTrue; 2721cb0ef41Sopenharmony_ci break; 2731cb0ef41Sopenharmony_ci case 'f': 2741cb0ef41Sopenharmony_ci if (parseConstToken(start, end, tokenEnd, falseString)) 2751cb0ef41Sopenharmony_ci return BoolFalse; 2761cb0ef41Sopenharmony_ci break; 2771cb0ef41Sopenharmony_ci case '[': 2781cb0ef41Sopenharmony_ci *tokenEnd = start + 1; 2791cb0ef41Sopenharmony_ci return ArrayBegin; 2801cb0ef41Sopenharmony_ci case ']': 2811cb0ef41Sopenharmony_ci *tokenEnd = start + 1; 2821cb0ef41Sopenharmony_ci return ArrayEnd; 2831cb0ef41Sopenharmony_ci case ',': 2841cb0ef41Sopenharmony_ci *tokenEnd = start + 1; 2851cb0ef41Sopenharmony_ci return ListSeparator; 2861cb0ef41Sopenharmony_ci case '{': 2871cb0ef41Sopenharmony_ci *tokenEnd = start + 1; 2881cb0ef41Sopenharmony_ci return ObjectBegin; 2891cb0ef41Sopenharmony_ci case '}': 2901cb0ef41Sopenharmony_ci *tokenEnd = start + 1; 2911cb0ef41Sopenharmony_ci return ObjectEnd; 2921cb0ef41Sopenharmony_ci case ':': 2931cb0ef41Sopenharmony_ci *tokenEnd = start + 1; 2941cb0ef41Sopenharmony_ci return ObjectPairSeparator; 2951cb0ef41Sopenharmony_ci case '0': 2961cb0ef41Sopenharmony_ci case '1': 2971cb0ef41Sopenharmony_ci case '2': 2981cb0ef41Sopenharmony_ci case '3': 2991cb0ef41Sopenharmony_ci case '4': 3001cb0ef41Sopenharmony_ci case '5': 3011cb0ef41Sopenharmony_ci case '6': 3021cb0ef41Sopenharmony_ci case '7': 3031cb0ef41Sopenharmony_ci case '8': 3041cb0ef41Sopenharmony_ci case '9': 3051cb0ef41Sopenharmony_ci case '-': 3061cb0ef41Sopenharmony_ci if (parseNumberToken(start, end, tokenEnd)) 3071cb0ef41Sopenharmony_ci return Number; 3081cb0ef41Sopenharmony_ci break; 3091cb0ef41Sopenharmony_ci case '"': 3101cb0ef41Sopenharmony_ci if (parseStringToken(start + 1, end, tokenEnd)) 3111cb0ef41Sopenharmony_ci return StringLiteral; 3121cb0ef41Sopenharmony_ci break; 3131cb0ef41Sopenharmony_ci } 3141cb0ef41Sopenharmony_ci return InvalidToken; 3151cb0ef41Sopenharmony_ci} 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_citemplate<typename Char> 3181cb0ef41Sopenharmony_ciint hexToInt(Char c) 3191cb0ef41Sopenharmony_ci{ 3201cb0ef41Sopenharmony_ci if ('0' <= c && c <= '9') 3211cb0ef41Sopenharmony_ci return c - '0'; 3221cb0ef41Sopenharmony_ci if ('A' <= c && c <= 'F') 3231cb0ef41Sopenharmony_ci return c - 'A' + 10; 3241cb0ef41Sopenharmony_ci if ('a' <= c && c <= 'f') 3251cb0ef41Sopenharmony_ci return c - 'a' + 10; 3261cb0ef41Sopenharmony_ci DCHECK(false); 3271cb0ef41Sopenharmony_ci return 0; 3281cb0ef41Sopenharmony_ci} 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_citemplate<typename Char> 3311cb0ef41Sopenharmony_cibool decodeString(const Char* start, const Char* end, StringBuilder* output) 3321cb0ef41Sopenharmony_ci{ 3331cb0ef41Sopenharmony_ci while (start < end) { 3341cb0ef41Sopenharmony_ci uint16_t c = *start++; 3351cb0ef41Sopenharmony_ci if ('\\' != c) { 3361cb0ef41Sopenharmony_ci StringUtil::builderAppend(*output, c); 3371cb0ef41Sopenharmony_ci continue; 3381cb0ef41Sopenharmony_ci } 3391cb0ef41Sopenharmony_ci if (start == end) 3401cb0ef41Sopenharmony_ci return false; 3411cb0ef41Sopenharmony_ci c = *start++; 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci if (c == 'x') { 3441cb0ef41Sopenharmony_ci // \x is not supported. 3451cb0ef41Sopenharmony_ci return false; 3461cb0ef41Sopenharmony_ci } 3471cb0ef41Sopenharmony_ci 3481cb0ef41Sopenharmony_ci switch (c) { 3491cb0ef41Sopenharmony_ci case '"': 3501cb0ef41Sopenharmony_ci case '/': 3511cb0ef41Sopenharmony_ci case '\\': 3521cb0ef41Sopenharmony_ci break; 3531cb0ef41Sopenharmony_ci case 'b': 3541cb0ef41Sopenharmony_ci c = '\b'; 3551cb0ef41Sopenharmony_ci break; 3561cb0ef41Sopenharmony_ci case 'f': 3571cb0ef41Sopenharmony_ci c = '\f'; 3581cb0ef41Sopenharmony_ci break; 3591cb0ef41Sopenharmony_ci case 'n': 3601cb0ef41Sopenharmony_ci c = '\n'; 3611cb0ef41Sopenharmony_ci break; 3621cb0ef41Sopenharmony_ci case 'r': 3631cb0ef41Sopenharmony_ci c = '\r'; 3641cb0ef41Sopenharmony_ci break; 3651cb0ef41Sopenharmony_ci case 't': 3661cb0ef41Sopenharmony_ci c = '\t'; 3671cb0ef41Sopenharmony_ci break; 3681cb0ef41Sopenharmony_ci case 'v': 3691cb0ef41Sopenharmony_ci c = '\v'; 3701cb0ef41Sopenharmony_ci break; 3711cb0ef41Sopenharmony_ci case 'u': 3721cb0ef41Sopenharmony_ci c = (hexToInt(*start) << 12) + 3731cb0ef41Sopenharmony_ci (hexToInt(*(start + 1)) << 8) + 3741cb0ef41Sopenharmony_ci (hexToInt(*(start + 2)) << 4) + 3751cb0ef41Sopenharmony_ci hexToInt(*(start + 3)); 3761cb0ef41Sopenharmony_ci start += 4; 3771cb0ef41Sopenharmony_ci break; 3781cb0ef41Sopenharmony_ci default: 3791cb0ef41Sopenharmony_ci return false; 3801cb0ef41Sopenharmony_ci } 3811cb0ef41Sopenharmony_ci StringUtil::builderAppend(*output, c); 3821cb0ef41Sopenharmony_ci } 3831cb0ef41Sopenharmony_ci return true; 3841cb0ef41Sopenharmony_ci} 3851cb0ef41Sopenharmony_ci 3861cb0ef41Sopenharmony_citemplate<typename Char> 3871cb0ef41Sopenharmony_cibool decodeString(const Char* start, const Char* end, String* output) 3881cb0ef41Sopenharmony_ci{ 3891cb0ef41Sopenharmony_ci if (start == end) { 3901cb0ef41Sopenharmony_ci *output = ""; 3911cb0ef41Sopenharmony_ci return true; 3921cb0ef41Sopenharmony_ci } 3931cb0ef41Sopenharmony_ci if (start > end) 3941cb0ef41Sopenharmony_ci return false; 3951cb0ef41Sopenharmony_ci StringBuilder buffer; 3961cb0ef41Sopenharmony_ci StringUtil::builderReserve(buffer, end - start); 3971cb0ef41Sopenharmony_ci if (!decodeString(start, end, &buffer)) 3981cb0ef41Sopenharmony_ci return false; 3991cb0ef41Sopenharmony_ci *output = StringUtil::builderToString(buffer); 4001cb0ef41Sopenharmony_ci return true; 4011cb0ef41Sopenharmony_ci} 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_citemplate<typename Char> 4041cb0ef41Sopenharmony_cistd::unique_ptr<Value> buildValue(const Char* start, const Char* end, const Char** valueTokenEnd, int depth) 4051cb0ef41Sopenharmony_ci{ 4061cb0ef41Sopenharmony_ci if (depth > stackLimit) 4071cb0ef41Sopenharmony_ci return nullptr; 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci std::unique_ptr<Value> result; 4101cb0ef41Sopenharmony_ci const Char* tokenStart; 4111cb0ef41Sopenharmony_ci const Char* tokenEnd; 4121cb0ef41Sopenharmony_ci Token token = parseToken(start, end, &tokenStart, &tokenEnd); 4131cb0ef41Sopenharmony_ci switch (token) { 4141cb0ef41Sopenharmony_ci case InvalidToken: 4151cb0ef41Sopenharmony_ci return nullptr; 4161cb0ef41Sopenharmony_ci case NullToken: 4171cb0ef41Sopenharmony_ci result = Value::null(); 4181cb0ef41Sopenharmony_ci break; 4191cb0ef41Sopenharmony_ci case BoolTrue: 4201cb0ef41Sopenharmony_ci result = FundamentalValue::create(true); 4211cb0ef41Sopenharmony_ci break; 4221cb0ef41Sopenharmony_ci case BoolFalse: 4231cb0ef41Sopenharmony_ci result = FundamentalValue::create(false); 4241cb0ef41Sopenharmony_ci break; 4251cb0ef41Sopenharmony_ci case Number: { 4261cb0ef41Sopenharmony_ci bool ok; 4271cb0ef41Sopenharmony_ci double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok); 4281cb0ef41Sopenharmony_ci if (!ok) 4291cb0ef41Sopenharmony_ci return nullptr; 4301cb0ef41Sopenharmony_ci if (value >= INT_MIN && value <= INT_MAX && static_cast<int>(value) == value) 4311cb0ef41Sopenharmony_ci result = FundamentalValue::create(static_cast<int>(value)); 4321cb0ef41Sopenharmony_ci else 4331cb0ef41Sopenharmony_ci result = FundamentalValue::create(value); 4341cb0ef41Sopenharmony_ci break; 4351cb0ef41Sopenharmony_ci } 4361cb0ef41Sopenharmony_ci case StringLiteral: { 4371cb0ef41Sopenharmony_ci String value; 4381cb0ef41Sopenharmony_ci bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value); 4391cb0ef41Sopenharmony_ci if (!ok) 4401cb0ef41Sopenharmony_ci return nullptr; 4411cb0ef41Sopenharmony_ci result = StringValue::create(value); 4421cb0ef41Sopenharmony_ci break; 4431cb0ef41Sopenharmony_ci } 4441cb0ef41Sopenharmony_ci case ArrayBegin: { 4451cb0ef41Sopenharmony_ci std::unique_ptr<ListValue> array = ListValue::create(); 4461cb0ef41Sopenharmony_ci start = tokenEnd; 4471cb0ef41Sopenharmony_ci token = parseToken(start, end, &tokenStart, &tokenEnd); 4481cb0ef41Sopenharmony_ci while (token != ArrayEnd) { 4491cb0ef41Sopenharmony_ci std::unique_ptr<Value> arrayNode = buildValue(start, end, &tokenEnd, depth + 1); 4501cb0ef41Sopenharmony_ci if (!arrayNode) 4511cb0ef41Sopenharmony_ci return nullptr; 4521cb0ef41Sopenharmony_ci array->pushValue(std::move(arrayNode)); 4531cb0ef41Sopenharmony_ci 4541cb0ef41Sopenharmony_ci // After a list value, we expect a comma or the end of the list. 4551cb0ef41Sopenharmony_ci start = tokenEnd; 4561cb0ef41Sopenharmony_ci token = parseToken(start, end, &tokenStart, &tokenEnd); 4571cb0ef41Sopenharmony_ci if (token == ListSeparator) { 4581cb0ef41Sopenharmony_ci start = tokenEnd; 4591cb0ef41Sopenharmony_ci token = parseToken(start, end, &tokenStart, &tokenEnd); 4601cb0ef41Sopenharmony_ci if (token == ArrayEnd) 4611cb0ef41Sopenharmony_ci return nullptr; 4621cb0ef41Sopenharmony_ci } else if (token != ArrayEnd) { 4631cb0ef41Sopenharmony_ci // Unexpected value after list value. Bail out. 4641cb0ef41Sopenharmony_ci return nullptr; 4651cb0ef41Sopenharmony_ci } 4661cb0ef41Sopenharmony_ci } 4671cb0ef41Sopenharmony_ci if (token != ArrayEnd) 4681cb0ef41Sopenharmony_ci return nullptr; 4691cb0ef41Sopenharmony_ci result = std::move(array); 4701cb0ef41Sopenharmony_ci break; 4711cb0ef41Sopenharmony_ci } 4721cb0ef41Sopenharmony_ci case ObjectBegin: { 4731cb0ef41Sopenharmony_ci std::unique_ptr<DictionaryValue> object = DictionaryValue::create(); 4741cb0ef41Sopenharmony_ci start = tokenEnd; 4751cb0ef41Sopenharmony_ci token = parseToken(start, end, &tokenStart, &tokenEnd); 4761cb0ef41Sopenharmony_ci while (token != ObjectEnd) { 4771cb0ef41Sopenharmony_ci if (token != StringLiteral) 4781cb0ef41Sopenharmony_ci return nullptr; 4791cb0ef41Sopenharmony_ci String key; 4801cb0ef41Sopenharmony_ci if (!decodeString(tokenStart + 1, tokenEnd - 1, &key)) 4811cb0ef41Sopenharmony_ci return nullptr; 4821cb0ef41Sopenharmony_ci start = tokenEnd; 4831cb0ef41Sopenharmony_ci 4841cb0ef41Sopenharmony_ci token = parseToken(start, end, &tokenStart, &tokenEnd); 4851cb0ef41Sopenharmony_ci if (token != ObjectPairSeparator) 4861cb0ef41Sopenharmony_ci return nullptr; 4871cb0ef41Sopenharmony_ci start = tokenEnd; 4881cb0ef41Sopenharmony_ci 4891cb0ef41Sopenharmony_ci std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, depth + 1); 4901cb0ef41Sopenharmony_ci if (!value) 4911cb0ef41Sopenharmony_ci return nullptr; 4921cb0ef41Sopenharmony_ci object->setValue(key, std::move(value)); 4931cb0ef41Sopenharmony_ci start = tokenEnd; 4941cb0ef41Sopenharmony_ci 4951cb0ef41Sopenharmony_ci // After a key/value pair, we expect a comma or the end of the 4961cb0ef41Sopenharmony_ci // object. 4971cb0ef41Sopenharmony_ci token = parseToken(start, end, &tokenStart, &tokenEnd); 4981cb0ef41Sopenharmony_ci if (token == ListSeparator) { 4991cb0ef41Sopenharmony_ci start = tokenEnd; 5001cb0ef41Sopenharmony_ci token = parseToken(start, end, &tokenStart, &tokenEnd); 5011cb0ef41Sopenharmony_ci if (token == ObjectEnd) 5021cb0ef41Sopenharmony_ci return nullptr; 5031cb0ef41Sopenharmony_ci } else if (token != ObjectEnd) { 5041cb0ef41Sopenharmony_ci // Unexpected value after last object value. Bail out. 5051cb0ef41Sopenharmony_ci return nullptr; 5061cb0ef41Sopenharmony_ci } 5071cb0ef41Sopenharmony_ci } 5081cb0ef41Sopenharmony_ci if (token != ObjectEnd) 5091cb0ef41Sopenharmony_ci return nullptr; 5101cb0ef41Sopenharmony_ci result = std::move(object); 5111cb0ef41Sopenharmony_ci break; 5121cb0ef41Sopenharmony_ci } 5131cb0ef41Sopenharmony_ci 5141cb0ef41Sopenharmony_ci default: 5151cb0ef41Sopenharmony_ci // We got a token that's not a value. 5161cb0ef41Sopenharmony_ci return nullptr; 5171cb0ef41Sopenharmony_ci } 5181cb0ef41Sopenharmony_ci 5191cb0ef41Sopenharmony_ci skipWhitespaceAndComments(tokenEnd, end, valueTokenEnd); 5201cb0ef41Sopenharmony_ci return result; 5211cb0ef41Sopenharmony_ci} 5221cb0ef41Sopenharmony_ci 5231cb0ef41Sopenharmony_citemplate<typename Char> 5241cb0ef41Sopenharmony_cistd::unique_ptr<Value> parseJSONInternal(const Char* start, unsigned length) 5251cb0ef41Sopenharmony_ci{ 5261cb0ef41Sopenharmony_ci const Char* end = start + length; 5271cb0ef41Sopenharmony_ci const Char *tokenEnd; 5281cb0ef41Sopenharmony_ci std::unique_ptr<Value> value = buildValue(start, end, &tokenEnd, 0); 5291cb0ef41Sopenharmony_ci if (!value || tokenEnd != end) 5301cb0ef41Sopenharmony_ci return nullptr; 5311cb0ef41Sopenharmony_ci return value; 5321cb0ef41Sopenharmony_ci} 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ci} // anonymous namespace 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_cistd::unique_ptr<Value> parseJSONCharacters(const uint16_t* characters, unsigned length) 5371cb0ef41Sopenharmony_ci{ 5381cb0ef41Sopenharmony_ci return parseJSONInternal<uint16_t>(characters, length); 5391cb0ef41Sopenharmony_ci} 5401cb0ef41Sopenharmony_ci 5411cb0ef41Sopenharmony_cistd::unique_ptr<Value> parseJSONCharacters(const uint8_t* characters, unsigned length) 5421cb0ef41Sopenharmony_ci{ 5431cb0ef41Sopenharmony_ci return parseJSONInternal<uint8_t>(characters, length); 5441cb0ef41Sopenharmony_ci} 5451cb0ef41Sopenharmony_ci 5461cb0ef41Sopenharmony_ci{% for namespace in config.protocol.namespace %} 5471cb0ef41Sopenharmony_ci} // namespace {{namespace}} 5481cb0ef41Sopenharmony_ci{% endfor %} 549