11cb0ef41Sopenharmony_ci/* 21cb0ef41Sopenharmony_ci * sfparse 31cb0ef41Sopenharmony_ci * 41cb0ef41Sopenharmony_ci * Copyright (c) 2023 sfparse contributors 51cb0ef41Sopenharmony_ci * Copyright (c) 2019 nghttp3 contributors 61cb0ef41Sopenharmony_ci * Copyright (c) 2015 nghttp2 contributors 71cb0ef41Sopenharmony_ci * 81cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 91cb0ef41Sopenharmony_ci * a copy of this software and associated documentation files (the 101cb0ef41Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 111cb0ef41Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 121cb0ef41Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 131cb0ef41Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 141cb0ef41Sopenharmony_ci * the following conditions: 151cb0ef41Sopenharmony_ci * 161cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be 171cb0ef41Sopenharmony_ci * included in all copies or substantial portions of the Software. 181cb0ef41Sopenharmony_ci * 191cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 201cb0ef41Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 211cb0ef41Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 221cb0ef41Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 231cb0ef41Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 241cb0ef41Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 251cb0ef41Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 261cb0ef41Sopenharmony_ci */ 271cb0ef41Sopenharmony_ci#include "sfparse.h" 281cb0ef41Sopenharmony_ci 291cb0ef41Sopenharmony_ci#include <string.h> 301cb0ef41Sopenharmony_ci#include <assert.h> 311cb0ef41Sopenharmony_ci#include <stdlib.h> 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_ci#define SF_STATE_DICT 0x08u 341cb0ef41Sopenharmony_ci#define SF_STATE_LIST 0x10u 351cb0ef41Sopenharmony_ci#define SF_STATE_ITEM 0x18u 361cb0ef41Sopenharmony_ci 371cb0ef41Sopenharmony_ci#define SF_STATE_INNER_LIST 0x04u 381cb0ef41Sopenharmony_ci 391cb0ef41Sopenharmony_ci#define SF_STATE_BEFORE 0x00u 401cb0ef41Sopenharmony_ci#define SF_STATE_BEFORE_PARAMS 0x01u 411cb0ef41Sopenharmony_ci#define SF_STATE_PARAMS 0x02u 421cb0ef41Sopenharmony_ci#define SF_STATE_AFTER 0x03u 431cb0ef41Sopenharmony_ci 441cb0ef41Sopenharmony_ci#define SF_STATE_OP_MASK 0x03u 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_ci#define SF_SET_STATE_AFTER(NAME) (SF_STATE_##NAME | SF_STATE_AFTER) 471cb0ef41Sopenharmony_ci#define SF_SET_STATE_BEFORE_PARAMS(NAME) \ 481cb0ef41Sopenharmony_ci (SF_STATE_##NAME | SF_STATE_BEFORE_PARAMS) 491cb0ef41Sopenharmony_ci#define SF_SET_STATE_INNER_LIST_BEFORE(NAME) \ 501cb0ef41Sopenharmony_ci (SF_STATE_##NAME | SF_STATE_INNER_LIST | SF_STATE_BEFORE) 511cb0ef41Sopenharmony_ci 521cb0ef41Sopenharmony_ci#define SF_STATE_DICT_AFTER SF_SET_STATE_AFTER(DICT) 531cb0ef41Sopenharmony_ci#define SF_STATE_DICT_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(DICT) 541cb0ef41Sopenharmony_ci#define SF_STATE_DICT_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(DICT) 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_ci#define SF_STATE_LIST_AFTER SF_SET_STATE_AFTER(LIST) 571cb0ef41Sopenharmony_ci#define SF_STATE_LIST_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(LIST) 581cb0ef41Sopenharmony_ci#define SF_STATE_LIST_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(LIST) 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci#define SF_STATE_ITEM_AFTER SF_SET_STATE_AFTER(ITEM) 611cb0ef41Sopenharmony_ci#define SF_STATE_ITEM_BEFORE_PARAMS SF_SET_STATE_BEFORE_PARAMS(ITEM) 621cb0ef41Sopenharmony_ci#define SF_STATE_ITEM_INNER_LIST_BEFORE SF_SET_STATE_INNER_LIST_BEFORE(ITEM) 631cb0ef41Sopenharmony_ci 641cb0ef41Sopenharmony_ci#define SF_STATE_INITIAL 0x00u 651cb0ef41Sopenharmony_ci 661cb0ef41Sopenharmony_ci#define DIGIT_CASES \ 671cb0ef41Sopenharmony_ci case '0': \ 681cb0ef41Sopenharmony_ci case '1': \ 691cb0ef41Sopenharmony_ci case '2': \ 701cb0ef41Sopenharmony_ci case '3': \ 711cb0ef41Sopenharmony_ci case '4': \ 721cb0ef41Sopenharmony_ci case '5': \ 731cb0ef41Sopenharmony_ci case '6': \ 741cb0ef41Sopenharmony_ci case '7': \ 751cb0ef41Sopenharmony_ci case '8': \ 761cb0ef41Sopenharmony_ci case '9' 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_ci#define LCALPHA_CASES \ 791cb0ef41Sopenharmony_ci case 'a': \ 801cb0ef41Sopenharmony_ci case 'b': \ 811cb0ef41Sopenharmony_ci case 'c': \ 821cb0ef41Sopenharmony_ci case 'd': \ 831cb0ef41Sopenharmony_ci case 'e': \ 841cb0ef41Sopenharmony_ci case 'f': \ 851cb0ef41Sopenharmony_ci case 'g': \ 861cb0ef41Sopenharmony_ci case 'h': \ 871cb0ef41Sopenharmony_ci case 'i': \ 881cb0ef41Sopenharmony_ci case 'j': \ 891cb0ef41Sopenharmony_ci case 'k': \ 901cb0ef41Sopenharmony_ci case 'l': \ 911cb0ef41Sopenharmony_ci case 'm': \ 921cb0ef41Sopenharmony_ci case 'n': \ 931cb0ef41Sopenharmony_ci case 'o': \ 941cb0ef41Sopenharmony_ci case 'p': \ 951cb0ef41Sopenharmony_ci case 'q': \ 961cb0ef41Sopenharmony_ci case 'r': \ 971cb0ef41Sopenharmony_ci case 's': \ 981cb0ef41Sopenharmony_ci case 't': \ 991cb0ef41Sopenharmony_ci case 'u': \ 1001cb0ef41Sopenharmony_ci case 'v': \ 1011cb0ef41Sopenharmony_ci case 'w': \ 1021cb0ef41Sopenharmony_ci case 'x': \ 1031cb0ef41Sopenharmony_ci case 'y': \ 1041cb0ef41Sopenharmony_ci case 'z' 1051cb0ef41Sopenharmony_ci 1061cb0ef41Sopenharmony_ci#define UCALPHA_CASES \ 1071cb0ef41Sopenharmony_ci case 'A': \ 1081cb0ef41Sopenharmony_ci case 'B': \ 1091cb0ef41Sopenharmony_ci case 'C': \ 1101cb0ef41Sopenharmony_ci case 'D': \ 1111cb0ef41Sopenharmony_ci case 'E': \ 1121cb0ef41Sopenharmony_ci case 'F': \ 1131cb0ef41Sopenharmony_ci case 'G': \ 1141cb0ef41Sopenharmony_ci case 'H': \ 1151cb0ef41Sopenharmony_ci case 'I': \ 1161cb0ef41Sopenharmony_ci case 'J': \ 1171cb0ef41Sopenharmony_ci case 'K': \ 1181cb0ef41Sopenharmony_ci case 'L': \ 1191cb0ef41Sopenharmony_ci case 'M': \ 1201cb0ef41Sopenharmony_ci case 'N': \ 1211cb0ef41Sopenharmony_ci case 'O': \ 1221cb0ef41Sopenharmony_ci case 'P': \ 1231cb0ef41Sopenharmony_ci case 'Q': \ 1241cb0ef41Sopenharmony_ci case 'R': \ 1251cb0ef41Sopenharmony_ci case 'S': \ 1261cb0ef41Sopenharmony_ci case 'T': \ 1271cb0ef41Sopenharmony_ci case 'U': \ 1281cb0ef41Sopenharmony_ci case 'V': \ 1291cb0ef41Sopenharmony_ci case 'W': \ 1301cb0ef41Sopenharmony_ci case 'X': \ 1311cb0ef41Sopenharmony_ci case 'Y': \ 1321cb0ef41Sopenharmony_ci case 'Z' 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci#define ALPHA_CASES \ 1351cb0ef41Sopenharmony_ci UCALPHA_CASES: \ 1361cb0ef41Sopenharmony_ci LCALPHA_CASES 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci#define X20_21_CASES \ 1391cb0ef41Sopenharmony_ci case ' ': \ 1401cb0ef41Sopenharmony_ci case '!' 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ci#define X23_5B_CASES \ 1431cb0ef41Sopenharmony_ci case '#': \ 1441cb0ef41Sopenharmony_ci case '$': \ 1451cb0ef41Sopenharmony_ci case '%': \ 1461cb0ef41Sopenharmony_ci case '&': \ 1471cb0ef41Sopenharmony_ci case '\'': \ 1481cb0ef41Sopenharmony_ci case '(': \ 1491cb0ef41Sopenharmony_ci case ')': \ 1501cb0ef41Sopenharmony_ci case '*': \ 1511cb0ef41Sopenharmony_ci case '+': \ 1521cb0ef41Sopenharmony_ci case ',': \ 1531cb0ef41Sopenharmony_ci case '-': \ 1541cb0ef41Sopenharmony_ci case '.': \ 1551cb0ef41Sopenharmony_ci case '/': \ 1561cb0ef41Sopenharmony_ci DIGIT_CASES: \ 1571cb0ef41Sopenharmony_ci case ':': \ 1581cb0ef41Sopenharmony_ci case ';': \ 1591cb0ef41Sopenharmony_ci case '<': \ 1601cb0ef41Sopenharmony_ci case '=': \ 1611cb0ef41Sopenharmony_ci case '>': \ 1621cb0ef41Sopenharmony_ci case '?': \ 1631cb0ef41Sopenharmony_ci case '@': \ 1641cb0ef41Sopenharmony_ci UCALPHA_CASES: \ 1651cb0ef41Sopenharmony_ci case '[' 1661cb0ef41Sopenharmony_ci 1671cb0ef41Sopenharmony_ci#define X5D_7E_CASES \ 1681cb0ef41Sopenharmony_ci case ']': \ 1691cb0ef41Sopenharmony_ci case '^': \ 1701cb0ef41Sopenharmony_ci case '_': \ 1711cb0ef41Sopenharmony_ci case '`': \ 1721cb0ef41Sopenharmony_ci LCALPHA_CASES: \ 1731cb0ef41Sopenharmony_ci case '{': \ 1741cb0ef41Sopenharmony_ci case '|': \ 1751cb0ef41Sopenharmony_ci case '}': \ 1761cb0ef41Sopenharmony_ci case '~' 1771cb0ef41Sopenharmony_ci 1781cb0ef41Sopenharmony_cistatic int is_ws(uint8_t c) { 1791cb0ef41Sopenharmony_ci switch (c) { 1801cb0ef41Sopenharmony_ci case ' ': 1811cb0ef41Sopenharmony_ci case '\t': 1821cb0ef41Sopenharmony_ci return 1; 1831cb0ef41Sopenharmony_ci default: 1841cb0ef41Sopenharmony_ci return 0; 1851cb0ef41Sopenharmony_ci } 1861cb0ef41Sopenharmony_ci} 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_cistatic int parser_eof(sf_parser *sfp) { return sfp->pos == sfp->end; } 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_cistatic void parser_discard_ows(sf_parser *sfp) { 1911cb0ef41Sopenharmony_ci for (; !parser_eof(sfp) && is_ws(*sfp->pos); ++sfp->pos) 1921cb0ef41Sopenharmony_ci ; 1931cb0ef41Sopenharmony_ci} 1941cb0ef41Sopenharmony_ci 1951cb0ef41Sopenharmony_cistatic void parser_discard_sp(sf_parser *sfp) { 1961cb0ef41Sopenharmony_ci for (; !parser_eof(sfp) && *sfp->pos == ' '; ++sfp->pos) 1971cb0ef41Sopenharmony_ci ; 1981cb0ef41Sopenharmony_ci} 1991cb0ef41Sopenharmony_ci 2001cb0ef41Sopenharmony_cistatic void parser_set_op_state(sf_parser *sfp, uint32_t op) { 2011cb0ef41Sopenharmony_ci sfp->state &= ~SF_STATE_OP_MASK; 2021cb0ef41Sopenharmony_ci sfp->state |= op; 2031cb0ef41Sopenharmony_ci} 2041cb0ef41Sopenharmony_ci 2051cb0ef41Sopenharmony_cistatic void parser_unset_inner_list_state(sf_parser *sfp) { 2061cb0ef41Sopenharmony_ci sfp->state &= ~SF_STATE_INNER_LIST; 2071cb0ef41Sopenharmony_ci} 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_cistatic int parser_key(sf_parser *sfp, sf_vec *dest) { 2101cb0ef41Sopenharmony_ci const uint8_t *base; 2111cb0ef41Sopenharmony_ci 2121cb0ef41Sopenharmony_ci switch (*sfp->pos) { 2131cb0ef41Sopenharmony_ci case '*': 2141cb0ef41Sopenharmony_ci LCALPHA_CASES: 2151cb0ef41Sopenharmony_ci break; 2161cb0ef41Sopenharmony_ci default: 2171cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 2181cb0ef41Sopenharmony_ci } 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ci base = sfp->pos++; 2211cb0ef41Sopenharmony_ci 2221cb0ef41Sopenharmony_ci for (; !parser_eof(sfp); ++sfp->pos) { 2231cb0ef41Sopenharmony_ci switch (*sfp->pos) { 2241cb0ef41Sopenharmony_ci case '_': 2251cb0ef41Sopenharmony_ci case '-': 2261cb0ef41Sopenharmony_ci case '.': 2271cb0ef41Sopenharmony_ci case '*': 2281cb0ef41Sopenharmony_ci DIGIT_CASES: 2291cb0ef41Sopenharmony_ci LCALPHA_CASES: 2301cb0ef41Sopenharmony_ci continue; 2311cb0ef41Sopenharmony_ci } 2321cb0ef41Sopenharmony_ci 2331cb0ef41Sopenharmony_ci break; 2341cb0ef41Sopenharmony_ci } 2351cb0ef41Sopenharmony_ci 2361cb0ef41Sopenharmony_ci if (dest) { 2371cb0ef41Sopenharmony_ci dest->base = (uint8_t *)base; 2381cb0ef41Sopenharmony_ci dest->len = (size_t)(sfp->pos - dest->base); 2391cb0ef41Sopenharmony_ci } 2401cb0ef41Sopenharmony_ci 2411cb0ef41Sopenharmony_ci return 0; 2421cb0ef41Sopenharmony_ci} 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_cistatic int parser_number(sf_parser *sfp, sf_value *dest) { 2451cb0ef41Sopenharmony_ci int sign = 1; 2461cb0ef41Sopenharmony_ci int64_t value = 0; 2471cb0ef41Sopenharmony_ci size_t len = 0; 2481cb0ef41Sopenharmony_ci size_t fpos = 0; 2491cb0ef41Sopenharmony_ci 2501cb0ef41Sopenharmony_ci if (*sfp->pos == '-') { 2511cb0ef41Sopenharmony_ci ++sfp->pos; 2521cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 2531cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 2541cb0ef41Sopenharmony_ci } 2551cb0ef41Sopenharmony_ci 2561cb0ef41Sopenharmony_ci sign = -1; 2571cb0ef41Sopenharmony_ci } 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci assert(!parser_eof(sfp)); 2601cb0ef41Sopenharmony_ci 2611cb0ef41Sopenharmony_ci for (; !parser_eof(sfp); ++sfp->pos) { 2621cb0ef41Sopenharmony_ci switch (*sfp->pos) { 2631cb0ef41Sopenharmony_ci DIGIT_CASES: 2641cb0ef41Sopenharmony_ci if (++len > 15) { 2651cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 2661cb0ef41Sopenharmony_ci } 2671cb0ef41Sopenharmony_ci 2681cb0ef41Sopenharmony_ci value *= 10; 2691cb0ef41Sopenharmony_ci value += *sfp->pos - '0'; 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci continue; 2721cb0ef41Sopenharmony_ci } 2731cb0ef41Sopenharmony_ci 2741cb0ef41Sopenharmony_ci break; 2751cb0ef41Sopenharmony_ci } 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci if (len == 0) { 2781cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 2791cb0ef41Sopenharmony_ci } 2801cb0ef41Sopenharmony_ci 2811cb0ef41Sopenharmony_ci if (parser_eof(sfp) || *sfp->pos != '.') { 2821cb0ef41Sopenharmony_ci if (dest) { 2831cb0ef41Sopenharmony_ci dest->type = SF_TYPE_INTEGER; 2841cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 2851cb0ef41Sopenharmony_ci dest->integer = value * sign; 2861cb0ef41Sopenharmony_ci } 2871cb0ef41Sopenharmony_ci 2881cb0ef41Sopenharmony_ci return 0; 2891cb0ef41Sopenharmony_ci } 2901cb0ef41Sopenharmony_ci 2911cb0ef41Sopenharmony_ci /* decimal */ 2921cb0ef41Sopenharmony_ci 2931cb0ef41Sopenharmony_ci if (len > 12) { 2941cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 2951cb0ef41Sopenharmony_ci } 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci fpos = len; 2981cb0ef41Sopenharmony_ci 2991cb0ef41Sopenharmony_ci ++sfp->pos; 3001cb0ef41Sopenharmony_ci 3011cb0ef41Sopenharmony_ci for (; !parser_eof(sfp); ++sfp->pos) { 3021cb0ef41Sopenharmony_ci switch (*sfp->pos) { 3031cb0ef41Sopenharmony_ci DIGIT_CASES: 3041cb0ef41Sopenharmony_ci if (++len > 15) { 3051cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 3061cb0ef41Sopenharmony_ci } 3071cb0ef41Sopenharmony_ci 3081cb0ef41Sopenharmony_ci value *= 10; 3091cb0ef41Sopenharmony_ci value += *sfp->pos - '0'; 3101cb0ef41Sopenharmony_ci 3111cb0ef41Sopenharmony_ci continue; 3121cb0ef41Sopenharmony_ci } 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ci break; 3151cb0ef41Sopenharmony_ci } 3161cb0ef41Sopenharmony_ci 3171cb0ef41Sopenharmony_ci if (fpos == len || len - fpos > 3) { 3181cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 3191cb0ef41Sopenharmony_ci } 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci if (dest) { 3221cb0ef41Sopenharmony_ci dest->type = SF_TYPE_DECIMAL; 3231cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 3241cb0ef41Sopenharmony_ci dest->decimal.numer = value * sign; 3251cb0ef41Sopenharmony_ci 3261cb0ef41Sopenharmony_ci switch (len - fpos) { 3271cb0ef41Sopenharmony_ci case 1: 3281cb0ef41Sopenharmony_ci dest->decimal.denom = 10; 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_ci break; 3311cb0ef41Sopenharmony_ci case 2: 3321cb0ef41Sopenharmony_ci dest->decimal.denom = 100; 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_ci break; 3351cb0ef41Sopenharmony_ci case 3: 3361cb0ef41Sopenharmony_ci dest->decimal.denom = 1000; 3371cb0ef41Sopenharmony_ci 3381cb0ef41Sopenharmony_ci break; 3391cb0ef41Sopenharmony_ci } 3401cb0ef41Sopenharmony_ci } 3411cb0ef41Sopenharmony_ci 3421cb0ef41Sopenharmony_ci return 0; 3431cb0ef41Sopenharmony_ci} 3441cb0ef41Sopenharmony_ci 3451cb0ef41Sopenharmony_cistatic int parser_date(sf_parser *sfp, sf_value *dest) { 3461cb0ef41Sopenharmony_ci int rv; 3471cb0ef41Sopenharmony_ci sf_value val; 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ci /* The first byte has already been validated by the caller. */ 3501cb0ef41Sopenharmony_ci assert('@' == *sfp->pos); 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci ++sfp->pos; 3531cb0ef41Sopenharmony_ci 3541cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 3551cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 3561cb0ef41Sopenharmony_ci } 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci rv = parser_number(sfp, &val); 3591cb0ef41Sopenharmony_ci if (rv != 0) { 3601cb0ef41Sopenharmony_ci return rv; 3611cb0ef41Sopenharmony_ci } 3621cb0ef41Sopenharmony_ci 3631cb0ef41Sopenharmony_ci if (val.type != SF_TYPE_INTEGER) { 3641cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 3651cb0ef41Sopenharmony_ci } 3661cb0ef41Sopenharmony_ci 3671cb0ef41Sopenharmony_ci if (dest) { 3681cb0ef41Sopenharmony_ci *dest = val; 3691cb0ef41Sopenharmony_ci dest->type = SF_TYPE_DATE; 3701cb0ef41Sopenharmony_ci } 3711cb0ef41Sopenharmony_ci 3721cb0ef41Sopenharmony_ci return 0; 3731cb0ef41Sopenharmony_ci} 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_cistatic int parser_string(sf_parser *sfp, sf_value *dest) { 3761cb0ef41Sopenharmony_ci const uint8_t *base; 3771cb0ef41Sopenharmony_ci uint32_t flags = SF_VALUE_FLAG_NONE; 3781cb0ef41Sopenharmony_ci 3791cb0ef41Sopenharmony_ci /* The first byte has already been validated by the caller. */ 3801cb0ef41Sopenharmony_ci assert('"' == *sfp->pos); 3811cb0ef41Sopenharmony_ci 3821cb0ef41Sopenharmony_ci base = ++sfp->pos; 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci for (; !parser_eof(sfp); ++sfp->pos) { 3851cb0ef41Sopenharmony_ci switch (*sfp->pos) { 3861cb0ef41Sopenharmony_ci X20_21_CASES: 3871cb0ef41Sopenharmony_ci X23_5B_CASES: 3881cb0ef41Sopenharmony_ci X5D_7E_CASES: 3891cb0ef41Sopenharmony_ci break; 3901cb0ef41Sopenharmony_ci case '\\': 3911cb0ef41Sopenharmony_ci ++sfp->pos; 3921cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 3931cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 3941cb0ef41Sopenharmony_ci } 3951cb0ef41Sopenharmony_ci 3961cb0ef41Sopenharmony_ci switch (*sfp->pos) { 3971cb0ef41Sopenharmony_ci case '"': 3981cb0ef41Sopenharmony_ci case '\\': 3991cb0ef41Sopenharmony_ci flags = SF_VALUE_FLAG_ESCAPED_STRING; 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci break; 4021cb0ef41Sopenharmony_ci default: 4031cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 4041cb0ef41Sopenharmony_ci } 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_ci break; 4071cb0ef41Sopenharmony_ci case '"': 4081cb0ef41Sopenharmony_ci if (dest) { 4091cb0ef41Sopenharmony_ci dest->type = SF_TYPE_STRING; 4101cb0ef41Sopenharmony_ci dest->flags = flags; 4111cb0ef41Sopenharmony_ci dest->vec.len = (size_t)(sfp->pos - base); 4121cb0ef41Sopenharmony_ci dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; 4131cb0ef41Sopenharmony_ci } 4141cb0ef41Sopenharmony_ci 4151cb0ef41Sopenharmony_ci ++sfp->pos; 4161cb0ef41Sopenharmony_ci 4171cb0ef41Sopenharmony_ci return 0; 4181cb0ef41Sopenharmony_ci default: 4191cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 4201cb0ef41Sopenharmony_ci } 4211cb0ef41Sopenharmony_ci } 4221cb0ef41Sopenharmony_ci 4231cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 4241cb0ef41Sopenharmony_ci} 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_cistatic int parser_token(sf_parser *sfp, sf_value *dest) { 4271cb0ef41Sopenharmony_ci const uint8_t *base; 4281cb0ef41Sopenharmony_ci 4291cb0ef41Sopenharmony_ci /* The first byte has already been validated by the caller. */ 4301cb0ef41Sopenharmony_ci base = sfp->pos++; 4311cb0ef41Sopenharmony_ci 4321cb0ef41Sopenharmony_ci for (; !parser_eof(sfp); ++sfp->pos) { 4331cb0ef41Sopenharmony_ci switch (*sfp->pos) { 4341cb0ef41Sopenharmony_ci case '!': 4351cb0ef41Sopenharmony_ci case '#': 4361cb0ef41Sopenharmony_ci case '$': 4371cb0ef41Sopenharmony_ci case '%': 4381cb0ef41Sopenharmony_ci case '&': 4391cb0ef41Sopenharmony_ci case '\'': 4401cb0ef41Sopenharmony_ci case '*': 4411cb0ef41Sopenharmony_ci case '+': 4421cb0ef41Sopenharmony_ci case '-': 4431cb0ef41Sopenharmony_ci case '.': 4441cb0ef41Sopenharmony_ci case '^': 4451cb0ef41Sopenharmony_ci case '_': 4461cb0ef41Sopenharmony_ci case '`': 4471cb0ef41Sopenharmony_ci case '|': 4481cb0ef41Sopenharmony_ci case '~': 4491cb0ef41Sopenharmony_ci case ':': 4501cb0ef41Sopenharmony_ci case '/': 4511cb0ef41Sopenharmony_ci DIGIT_CASES: 4521cb0ef41Sopenharmony_ci ALPHA_CASES: 4531cb0ef41Sopenharmony_ci continue; 4541cb0ef41Sopenharmony_ci } 4551cb0ef41Sopenharmony_ci 4561cb0ef41Sopenharmony_ci break; 4571cb0ef41Sopenharmony_ci } 4581cb0ef41Sopenharmony_ci 4591cb0ef41Sopenharmony_ci if (dest) { 4601cb0ef41Sopenharmony_ci dest->type = SF_TYPE_TOKEN; 4611cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 4621cb0ef41Sopenharmony_ci dest->vec.base = (uint8_t *)base; 4631cb0ef41Sopenharmony_ci dest->vec.len = (size_t)(sfp->pos - base); 4641cb0ef41Sopenharmony_ci } 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci return 0; 4671cb0ef41Sopenharmony_ci} 4681cb0ef41Sopenharmony_ci 4691cb0ef41Sopenharmony_cistatic int parser_byteseq(sf_parser *sfp, sf_value *dest) { 4701cb0ef41Sopenharmony_ci const uint8_t *base; 4711cb0ef41Sopenharmony_ci 4721cb0ef41Sopenharmony_ci /* The first byte has already been validated by the caller. */ 4731cb0ef41Sopenharmony_ci assert(':' == *sfp->pos); 4741cb0ef41Sopenharmony_ci 4751cb0ef41Sopenharmony_ci base = ++sfp->pos; 4761cb0ef41Sopenharmony_ci 4771cb0ef41Sopenharmony_ci for (; !parser_eof(sfp); ++sfp->pos) { 4781cb0ef41Sopenharmony_ci switch (*sfp->pos) { 4791cb0ef41Sopenharmony_ci case '+': 4801cb0ef41Sopenharmony_ci case '/': 4811cb0ef41Sopenharmony_ci DIGIT_CASES: 4821cb0ef41Sopenharmony_ci ALPHA_CASES: 4831cb0ef41Sopenharmony_ci continue; 4841cb0ef41Sopenharmony_ci case '=': 4851cb0ef41Sopenharmony_ci switch ((sfp->pos - base) & 0x3) { 4861cb0ef41Sopenharmony_ci case 0: 4871cb0ef41Sopenharmony_ci case 1: 4881cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 4891cb0ef41Sopenharmony_ci case 2: 4901cb0ef41Sopenharmony_ci switch (*(sfp->pos - 1)) { 4911cb0ef41Sopenharmony_ci case 'A': 4921cb0ef41Sopenharmony_ci case 'Q': 4931cb0ef41Sopenharmony_ci case 'g': 4941cb0ef41Sopenharmony_ci case 'w': 4951cb0ef41Sopenharmony_ci break; 4961cb0ef41Sopenharmony_ci default: 4971cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 4981cb0ef41Sopenharmony_ci } 4991cb0ef41Sopenharmony_ci 5001cb0ef41Sopenharmony_ci ++sfp->pos; 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ci if (parser_eof(sfp) || *sfp->pos != '=') { 5031cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5041cb0ef41Sopenharmony_ci } 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci break; 5071cb0ef41Sopenharmony_ci case 3: 5081cb0ef41Sopenharmony_ci switch (*(sfp->pos - 1)) { 5091cb0ef41Sopenharmony_ci case 'A': 5101cb0ef41Sopenharmony_ci case 'E': 5111cb0ef41Sopenharmony_ci case 'I': 5121cb0ef41Sopenharmony_ci case 'M': 5131cb0ef41Sopenharmony_ci case 'Q': 5141cb0ef41Sopenharmony_ci case 'U': 5151cb0ef41Sopenharmony_ci case 'Y': 5161cb0ef41Sopenharmony_ci case 'c': 5171cb0ef41Sopenharmony_ci case 'g': 5181cb0ef41Sopenharmony_ci case 'k': 5191cb0ef41Sopenharmony_ci case 'o': 5201cb0ef41Sopenharmony_ci case 's': 5211cb0ef41Sopenharmony_ci case 'w': 5221cb0ef41Sopenharmony_ci case '0': 5231cb0ef41Sopenharmony_ci case '4': 5241cb0ef41Sopenharmony_ci case '8': 5251cb0ef41Sopenharmony_ci break; 5261cb0ef41Sopenharmony_ci default: 5271cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5281cb0ef41Sopenharmony_ci } 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_ci break; 5311cb0ef41Sopenharmony_ci } 5321cb0ef41Sopenharmony_ci 5331cb0ef41Sopenharmony_ci ++sfp->pos; 5341cb0ef41Sopenharmony_ci 5351cb0ef41Sopenharmony_ci if (parser_eof(sfp) || *sfp->pos != ':') { 5361cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5371cb0ef41Sopenharmony_ci } 5381cb0ef41Sopenharmony_ci 5391cb0ef41Sopenharmony_ci goto fin; 5401cb0ef41Sopenharmony_ci case ':': 5411cb0ef41Sopenharmony_ci if ((sfp->pos - base) & 0x3) { 5421cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5431cb0ef41Sopenharmony_ci } 5441cb0ef41Sopenharmony_ci 5451cb0ef41Sopenharmony_ci goto fin; 5461cb0ef41Sopenharmony_ci default: 5471cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5481cb0ef41Sopenharmony_ci } 5491cb0ef41Sopenharmony_ci } 5501cb0ef41Sopenharmony_ci 5511cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5521cb0ef41Sopenharmony_ci 5531cb0ef41Sopenharmony_cifin: 5541cb0ef41Sopenharmony_ci if (dest) { 5551cb0ef41Sopenharmony_ci dest->type = SF_TYPE_BYTESEQ; 5561cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 5571cb0ef41Sopenharmony_ci dest->vec.len = (size_t)(sfp->pos - base); 5581cb0ef41Sopenharmony_ci dest->vec.base = dest->vec.len == 0 ? NULL : (uint8_t *)base; 5591cb0ef41Sopenharmony_ci } 5601cb0ef41Sopenharmony_ci 5611cb0ef41Sopenharmony_ci ++sfp->pos; 5621cb0ef41Sopenharmony_ci 5631cb0ef41Sopenharmony_ci return 0; 5641cb0ef41Sopenharmony_ci} 5651cb0ef41Sopenharmony_ci 5661cb0ef41Sopenharmony_cistatic int parser_boolean(sf_parser *sfp, sf_value *dest) { 5671cb0ef41Sopenharmony_ci int b; 5681cb0ef41Sopenharmony_ci 5691cb0ef41Sopenharmony_ci /* The first byte has already been validated by the caller. */ 5701cb0ef41Sopenharmony_ci assert('?' == *sfp->pos); 5711cb0ef41Sopenharmony_ci 5721cb0ef41Sopenharmony_ci ++sfp->pos; 5731cb0ef41Sopenharmony_ci 5741cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 5751cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5761cb0ef41Sopenharmony_ci } 5771cb0ef41Sopenharmony_ci 5781cb0ef41Sopenharmony_ci switch (*sfp->pos) { 5791cb0ef41Sopenharmony_ci case '0': 5801cb0ef41Sopenharmony_ci b = 0; 5811cb0ef41Sopenharmony_ci 5821cb0ef41Sopenharmony_ci break; 5831cb0ef41Sopenharmony_ci case '1': 5841cb0ef41Sopenharmony_ci b = 1; 5851cb0ef41Sopenharmony_ci 5861cb0ef41Sopenharmony_ci break; 5871cb0ef41Sopenharmony_ci default: 5881cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 5891cb0ef41Sopenharmony_ci } 5901cb0ef41Sopenharmony_ci 5911cb0ef41Sopenharmony_ci ++sfp->pos; 5921cb0ef41Sopenharmony_ci 5931cb0ef41Sopenharmony_ci if (dest) { 5941cb0ef41Sopenharmony_ci dest->type = SF_TYPE_BOOLEAN; 5951cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 5961cb0ef41Sopenharmony_ci dest->boolean = b; 5971cb0ef41Sopenharmony_ci } 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci return 0; 6001cb0ef41Sopenharmony_ci} 6011cb0ef41Sopenharmony_ci 6021cb0ef41Sopenharmony_cistatic int parser_bare_item(sf_parser *sfp, sf_value *dest) { 6031cb0ef41Sopenharmony_ci switch (*sfp->pos) { 6041cb0ef41Sopenharmony_ci case '"': 6051cb0ef41Sopenharmony_ci return parser_string(sfp, dest); 6061cb0ef41Sopenharmony_ci case '-': 6071cb0ef41Sopenharmony_ci DIGIT_CASES: 6081cb0ef41Sopenharmony_ci return parser_number(sfp, dest); 6091cb0ef41Sopenharmony_ci case '@': 6101cb0ef41Sopenharmony_ci return parser_date(sfp, dest); 6111cb0ef41Sopenharmony_ci case ':': 6121cb0ef41Sopenharmony_ci return parser_byteseq(sfp, dest); 6131cb0ef41Sopenharmony_ci case '?': 6141cb0ef41Sopenharmony_ci return parser_boolean(sfp, dest); 6151cb0ef41Sopenharmony_ci case '*': 6161cb0ef41Sopenharmony_ci ALPHA_CASES: 6171cb0ef41Sopenharmony_ci return parser_token(sfp, dest); 6181cb0ef41Sopenharmony_ci default: 6191cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 6201cb0ef41Sopenharmony_ci } 6211cb0ef41Sopenharmony_ci} 6221cb0ef41Sopenharmony_ci 6231cb0ef41Sopenharmony_cistatic int parser_skip_inner_list(sf_parser *sfp); 6241cb0ef41Sopenharmony_ci 6251cb0ef41Sopenharmony_ciint sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { 6261cb0ef41Sopenharmony_ci int rv; 6271cb0ef41Sopenharmony_ci 6281cb0ef41Sopenharmony_ci switch (sfp->state & SF_STATE_OP_MASK) { 6291cb0ef41Sopenharmony_ci case SF_STATE_BEFORE: 6301cb0ef41Sopenharmony_ci rv = parser_skip_inner_list(sfp); 6311cb0ef41Sopenharmony_ci if (rv != 0) { 6321cb0ef41Sopenharmony_ci return rv; 6331cb0ef41Sopenharmony_ci } 6341cb0ef41Sopenharmony_ci 6351cb0ef41Sopenharmony_ci /* fall through */ 6361cb0ef41Sopenharmony_ci case SF_STATE_BEFORE_PARAMS: 6371cb0ef41Sopenharmony_ci parser_set_op_state(sfp, SF_STATE_PARAMS); 6381cb0ef41Sopenharmony_ci 6391cb0ef41Sopenharmony_ci break; 6401cb0ef41Sopenharmony_ci case SF_STATE_PARAMS: 6411cb0ef41Sopenharmony_ci break; 6421cb0ef41Sopenharmony_ci default: 6431cb0ef41Sopenharmony_ci assert(0); 6441cb0ef41Sopenharmony_ci abort(); 6451cb0ef41Sopenharmony_ci } 6461cb0ef41Sopenharmony_ci 6471cb0ef41Sopenharmony_ci if (parser_eof(sfp) || *sfp->pos != ';') { 6481cb0ef41Sopenharmony_ci parser_set_op_state(sfp, SF_STATE_AFTER); 6491cb0ef41Sopenharmony_ci 6501cb0ef41Sopenharmony_ci return SF_ERR_EOF; 6511cb0ef41Sopenharmony_ci } 6521cb0ef41Sopenharmony_ci 6531cb0ef41Sopenharmony_ci ++sfp->pos; 6541cb0ef41Sopenharmony_ci 6551cb0ef41Sopenharmony_ci parser_discard_sp(sfp); 6561cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 6571cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 6581cb0ef41Sopenharmony_ci } 6591cb0ef41Sopenharmony_ci 6601cb0ef41Sopenharmony_ci rv = parser_key(sfp, dest_key); 6611cb0ef41Sopenharmony_ci if (rv != 0) { 6621cb0ef41Sopenharmony_ci return rv; 6631cb0ef41Sopenharmony_ci } 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci if (parser_eof(sfp) || *sfp->pos != '=') { 6661cb0ef41Sopenharmony_ci if (dest_value) { 6671cb0ef41Sopenharmony_ci dest_value->type = SF_TYPE_BOOLEAN; 6681cb0ef41Sopenharmony_ci dest_value->flags = SF_VALUE_FLAG_NONE; 6691cb0ef41Sopenharmony_ci dest_value->boolean = 1; 6701cb0ef41Sopenharmony_ci } 6711cb0ef41Sopenharmony_ci 6721cb0ef41Sopenharmony_ci return 0; 6731cb0ef41Sopenharmony_ci } 6741cb0ef41Sopenharmony_ci 6751cb0ef41Sopenharmony_ci ++sfp->pos; 6761cb0ef41Sopenharmony_ci 6771cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 6781cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 6791cb0ef41Sopenharmony_ci } 6801cb0ef41Sopenharmony_ci 6811cb0ef41Sopenharmony_ci return parser_bare_item(sfp, dest_value); 6821cb0ef41Sopenharmony_ci} 6831cb0ef41Sopenharmony_ci 6841cb0ef41Sopenharmony_cistatic int parser_skip_params(sf_parser *sfp) { 6851cb0ef41Sopenharmony_ci int rv; 6861cb0ef41Sopenharmony_ci 6871cb0ef41Sopenharmony_ci for (;;) { 6881cb0ef41Sopenharmony_ci rv = sf_parser_param(sfp, NULL, NULL); 6891cb0ef41Sopenharmony_ci switch (rv) { 6901cb0ef41Sopenharmony_ci case 0: 6911cb0ef41Sopenharmony_ci break; 6921cb0ef41Sopenharmony_ci case SF_ERR_EOF: 6931cb0ef41Sopenharmony_ci return 0; 6941cb0ef41Sopenharmony_ci case SF_ERR_PARSE_ERROR: 6951cb0ef41Sopenharmony_ci return rv; 6961cb0ef41Sopenharmony_ci default: 6971cb0ef41Sopenharmony_ci assert(0); 6981cb0ef41Sopenharmony_ci abort(); 6991cb0ef41Sopenharmony_ci } 7001cb0ef41Sopenharmony_ci } 7011cb0ef41Sopenharmony_ci} 7021cb0ef41Sopenharmony_ci 7031cb0ef41Sopenharmony_ciint sf_parser_inner_list(sf_parser *sfp, sf_value *dest) { 7041cb0ef41Sopenharmony_ci int rv; 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_ci switch (sfp->state & SF_STATE_OP_MASK) { 7071cb0ef41Sopenharmony_ci case SF_STATE_BEFORE: 7081cb0ef41Sopenharmony_ci parser_discard_sp(sfp); 7091cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 7101cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 7111cb0ef41Sopenharmony_ci } 7121cb0ef41Sopenharmony_ci 7131cb0ef41Sopenharmony_ci break; 7141cb0ef41Sopenharmony_ci case SF_STATE_BEFORE_PARAMS: 7151cb0ef41Sopenharmony_ci rv = parser_skip_params(sfp); 7161cb0ef41Sopenharmony_ci if (rv != 0) { 7171cb0ef41Sopenharmony_ci return rv; 7181cb0ef41Sopenharmony_ci } 7191cb0ef41Sopenharmony_ci 7201cb0ef41Sopenharmony_ci /* Technically, we are entering SF_STATE_AFTER, but we will set 7211cb0ef41Sopenharmony_ci another state without reading the state. */ 7221cb0ef41Sopenharmony_ci /* parser_set_op_state(sfp, SF_STATE_AFTER); */ 7231cb0ef41Sopenharmony_ci 7241cb0ef41Sopenharmony_ci /* fall through */ 7251cb0ef41Sopenharmony_ci case SF_STATE_AFTER: 7261cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 7271cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 7281cb0ef41Sopenharmony_ci } 7291cb0ef41Sopenharmony_ci 7301cb0ef41Sopenharmony_ci switch (*sfp->pos) { 7311cb0ef41Sopenharmony_ci case ' ': 7321cb0ef41Sopenharmony_ci parser_discard_sp(sfp); 7331cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 7341cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 7351cb0ef41Sopenharmony_ci } 7361cb0ef41Sopenharmony_ci 7371cb0ef41Sopenharmony_ci break; 7381cb0ef41Sopenharmony_ci case ')': 7391cb0ef41Sopenharmony_ci break; 7401cb0ef41Sopenharmony_ci default: 7411cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 7421cb0ef41Sopenharmony_ci } 7431cb0ef41Sopenharmony_ci 7441cb0ef41Sopenharmony_ci break; 7451cb0ef41Sopenharmony_ci default: 7461cb0ef41Sopenharmony_ci assert(0); 7471cb0ef41Sopenharmony_ci abort(); 7481cb0ef41Sopenharmony_ci } 7491cb0ef41Sopenharmony_ci 7501cb0ef41Sopenharmony_ci if (*sfp->pos == ')') { 7511cb0ef41Sopenharmony_ci ++sfp->pos; 7521cb0ef41Sopenharmony_ci 7531cb0ef41Sopenharmony_ci parser_unset_inner_list_state(sfp); 7541cb0ef41Sopenharmony_ci parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS); 7551cb0ef41Sopenharmony_ci 7561cb0ef41Sopenharmony_ci return SF_ERR_EOF; 7571cb0ef41Sopenharmony_ci } 7581cb0ef41Sopenharmony_ci 7591cb0ef41Sopenharmony_ci rv = parser_bare_item(sfp, dest); 7601cb0ef41Sopenharmony_ci if (rv != 0) { 7611cb0ef41Sopenharmony_ci return rv; 7621cb0ef41Sopenharmony_ci } 7631cb0ef41Sopenharmony_ci 7641cb0ef41Sopenharmony_ci parser_set_op_state(sfp, SF_STATE_BEFORE_PARAMS); 7651cb0ef41Sopenharmony_ci 7661cb0ef41Sopenharmony_ci return 0; 7671cb0ef41Sopenharmony_ci} 7681cb0ef41Sopenharmony_ci 7691cb0ef41Sopenharmony_cistatic int parser_skip_inner_list(sf_parser *sfp) { 7701cb0ef41Sopenharmony_ci int rv; 7711cb0ef41Sopenharmony_ci 7721cb0ef41Sopenharmony_ci for (;;) { 7731cb0ef41Sopenharmony_ci rv = sf_parser_inner_list(sfp, NULL); 7741cb0ef41Sopenharmony_ci switch (rv) { 7751cb0ef41Sopenharmony_ci case 0: 7761cb0ef41Sopenharmony_ci break; 7771cb0ef41Sopenharmony_ci case SF_ERR_EOF: 7781cb0ef41Sopenharmony_ci return 0; 7791cb0ef41Sopenharmony_ci case SF_ERR_PARSE_ERROR: 7801cb0ef41Sopenharmony_ci return rv; 7811cb0ef41Sopenharmony_ci default: 7821cb0ef41Sopenharmony_ci assert(0); 7831cb0ef41Sopenharmony_ci abort(); 7841cb0ef41Sopenharmony_ci } 7851cb0ef41Sopenharmony_ci } 7861cb0ef41Sopenharmony_ci} 7871cb0ef41Sopenharmony_ci 7881cb0ef41Sopenharmony_cistatic int parser_next_key_or_item(sf_parser *sfp) { 7891cb0ef41Sopenharmony_ci parser_discard_ows(sfp); 7901cb0ef41Sopenharmony_ci 7911cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 7921cb0ef41Sopenharmony_ci return SF_ERR_EOF; 7931cb0ef41Sopenharmony_ci } 7941cb0ef41Sopenharmony_ci 7951cb0ef41Sopenharmony_ci if (*sfp->pos != ',') { 7961cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 7971cb0ef41Sopenharmony_ci } 7981cb0ef41Sopenharmony_ci 7991cb0ef41Sopenharmony_ci ++sfp->pos; 8001cb0ef41Sopenharmony_ci 8011cb0ef41Sopenharmony_ci parser_discard_ows(sfp); 8021cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 8031cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 8041cb0ef41Sopenharmony_ci } 8051cb0ef41Sopenharmony_ci 8061cb0ef41Sopenharmony_ci return 0; 8071cb0ef41Sopenharmony_ci} 8081cb0ef41Sopenharmony_ci 8091cb0ef41Sopenharmony_cistatic int parser_dict_value(sf_parser *sfp, sf_value *dest) { 8101cb0ef41Sopenharmony_ci int rv; 8111cb0ef41Sopenharmony_ci 8121cb0ef41Sopenharmony_ci if (parser_eof(sfp) || *(sfp->pos) != '=') { 8131cb0ef41Sopenharmony_ci /* Boolean true */ 8141cb0ef41Sopenharmony_ci if (dest) { 8151cb0ef41Sopenharmony_ci dest->type = SF_TYPE_BOOLEAN; 8161cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 8171cb0ef41Sopenharmony_ci dest->boolean = 1; 8181cb0ef41Sopenharmony_ci } 8191cb0ef41Sopenharmony_ci 8201cb0ef41Sopenharmony_ci sfp->state = SF_STATE_DICT_BEFORE_PARAMS; 8211cb0ef41Sopenharmony_ci 8221cb0ef41Sopenharmony_ci return 0; 8231cb0ef41Sopenharmony_ci } 8241cb0ef41Sopenharmony_ci 8251cb0ef41Sopenharmony_ci ++sfp->pos; 8261cb0ef41Sopenharmony_ci 8271cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 8281cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 8291cb0ef41Sopenharmony_ci } 8301cb0ef41Sopenharmony_ci 8311cb0ef41Sopenharmony_ci if (*sfp->pos == '(') { 8321cb0ef41Sopenharmony_ci if (dest) { 8331cb0ef41Sopenharmony_ci dest->type = SF_TYPE_INNER_LIST; 8341cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 8351cb0ef41Sopenharmony_ci } 8361cb0ef41Sopenharmony_ci 8371cb0ef41Sopenharmony_ci ++sfp->pos; 8381cb0ef41Sopenharmony_ci 8391cb0ef41Sopenharmony_ci sfp->state = SF_STATE_DICT_INNER_LIST_BEFORE; 8401cb0ef41Sopenharmony_ci 8411cb0ef41Sopenharmony_ci return 0; 8421cb0ef41Sopenharmony_ci } 8431cb0ef41Sopenharmony_ci 8441cb0ef41Sopenharmony_ci rv = parser_bare_item(sfp, dest); 8451cb0ef41Sopenharmony_ci if (rv != 0) { 8461cb0ef41Sopenharmony_ci return rv; 8471cb0ef41Sopenharmony_ci } 8481cb0ef41Sopenharmony_ci 8491cb0ef41Sopenharmony_ci sfp->state = SF_STATE_DICT_BEFORE_PARAMS; 8501cb0ef41Sopenharmony_ci 8511cb0ef41Sopenharmony_ci return 0; 8521cb0ef41Sopenharmony_ci} 8531cb0ef41Sopenharmony_ci 8541cb0ef41Sopenharmony_ciint sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value) { 8551cb0ef41Sopenharmony_ci int rv; 8561cb0ef41Sopenharmony_ci 8571cb0ef41Sopenharmony_ci switch (sfp->state) { 8581cb0ef41Sopenharmony_ci case SF_STATE_DICT_INNER_LIST_BEFORE: 8591cb0ef41Sopenharmony_ci rv = parser_skip_inner_list(sfp); 8601cb0ef41Sopenharmony_ci if (rv != 0) { 8611cb0ef41Sopenharmony_ci return rv; 8621cb0ef41Sopenharmony_ci } 8631cb0ef41Sopenharmony_ci 8641cb0ef41Sopenharmony_ci /* fall through */ 8651cb0ef41Sopenharmony_ci case SF_STATE_DICT_BEFORE_PARAMS: 8661cb0ef41Sopenharmony_ci rv = parser_skip_params(sfp); 8671cb0ef41Sopenharmony_ci if (rv != 0) { 8681cb0ef41Sopenharmony_ci return rv; 8691cb0ef41Sopenharmony_ci } 8701cb0ef41Sopenharmony_ci 8711cb0ef41Sopenharmony_ci /* fall through */ 8721cb0ef41Sopenharmony_ci case SF_STATE_DICT_AFTER: 8731cb0ef41Sopenharmony_ci rv = parser_next_key_or_item(sfp); 8741cb0ef41Sopenharmony_ci if (rv != 0) { 8751cb0ef41Sopenharmony_ci return rv; 8761cb0ef41Sopenharmony_ci } 8771cb0ef41Sopenharmony_ci 8781cb0ef41Sopenharmony_ci break; 8791cb0ef41Sopenharmony_ci case SF_STATE_INITIAL: 8801cb0ef41Sopenharmony_ci parser_discard_sp(sfp); 8811cb0ef41Sopenharmony_ci 8821cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 8831cb0ef41Sopenharmony_ci return SF_ERR_EOF; 8841cb0ef41Sopenharmony_ci } 8851cb0ef41Sopenharmony_ci 8861cb0ef41Sopenharmony_ci break; 8871cb0ef41Sopenharmony_ci default: 8881cb0ef41Sopenharmony_ci assert(0); 8891cb0ef41Sopenharmony_ci abort(); 8901cb0ef41Sopenharmony_ci } 8911cb0ef41Sopenharmony_ci 8921cb0ef41Sopenharmony_ci rv = parser_key(sfp, dest_key); 8931cb0ef41Sopenharmony_ci if (rv != 0) { 8941cb0ef41Sopenharmony_ci return rv; 8951cb0ef41Sopenharmony_ci } 8961cb0ef41Sopenharmony_ci 8971cb0ef41Sopenharmony_ci return parser_dict_value(sfp, dest_value); 8981cb0ef41Sopenharmony_ci} 8991cb0ef41Sopenharmony_ci 9001cb0ef41Sopenharmony_ciint sf_parser_list(sf_parser *sfp, sf_value *dest) { 9011cb0ef41Sopenharmony_ci int rv; 9021cb0ef41Sopenharmony_ci 9031cb0ef41Sopenharmony_ci switch (sfp->state) { 9041cb0ef41Sopenharmony_ci case SF_STATE_LIST_INNER_LIST_BEFORE: 9051cb0ef41Sopenharmony_ci rv = parser_skip_inner_list(sfp); 9061cb0ef41Sopenharmony_ci if (rv != 0) { 9071cb0ef41Sopenharmony_ci return rv; 9081cb0ef41Sopenharmony_ci } 9091cb0ef41Sopenharmony_ci 9101cb0ef41Sopenharmony_ci /* fall through */ 9111cb0ef41Sopenharmony_ci case SF_STATE_LIST_BEFORE_PARAMS: 9121cb0ef41Sopenharmony_ci rv = parser_skip_params(sfp); 9131cb0ef41Sopenharmony_ci if (rv != 0) { 9141cb0ef41Sopenharmony_ci return rv; 9151cb0ef41Sopenharmony_ci } 9161cb0ef41Sopenharmony_ci 9171cb0ef41Sopenharmony_ci /* fall through */ 9181cb0ef41Sopenharmony_ci case SF_STATE_LIST_AFTER: 9191cb0ef41Sopenharmony_ci rv = parser_next_key_or_item(sfp); 9201cb0ef41Sopenharmony_ci if (rv != 0) { 9211cb0ef41Sopenharmony_ci return rv; 9221cb0ef41Sopenharmony_ci } 9231cb0ef41Sopenharmony_ci 9241cb0ef41Sopenharmony_ci break; 9251cb0ef41Sopenharmony_ci case SF_STATE_INITIAL: 9261cb0ef41Sopenharmony_ci parser_discard_sp(sfp); 9271cb0ef41Sopenharmony_ci 9281cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 9291cb0ef41Sopenharmony_ci return SF_ERR_EOF; 9301cb0ef41Sopenharmony_ci } 9311cb0ef41Sopenharmony_ci 9321cb0ef41Sopenharmony_ci break; 9331cb0ef41Sopenharmony_ci default: 9341cb0ef41Sopenharmony_ci assert(0); 9351cb0ef41Sopenharmony_ci abort(); 9361cb0ef41Sopenharmony_ci } 9371cb0ef41Sopenharmony_ci 9381cb0ef41Sopenharmony_ci if (*sfp->pos == '(') { 9391cb0ef41Sopenharmony_ci if (dest) { 9401cb0ef41Sopenharmony_ci dest->type = SF_TYPE_INNER_LIST; 9411cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 9421cb0ef41Sopenharmony_ci } 9431cb0ef41Sopenharmony_ci 9441cb0ef41Sopenharmony_ci ++sfp->pos; 9451cb0ef41Sopenharmony_ci 9461cb0ef41Sopenharmony_ci sfp->state = SF_STATE_LIST_INNER_LIST_BEFORE; 9471cb0ef41Sopenharmony_ci 9481cb0ef41Sopenharmony_ci return 0; 9491cb0ef41Sopenharmony_ci } 9501cb0ef41Sopenharmony_ci 9511cb0ef41Sopenharmony_ci rv = parser_bare_item(sfp, dest); 9521cb0ef41Sopenharmony_ci if (rv != 0) { 9531cb0ef41Sopenharmony_ci return rv; 9541cb0ef41Sopenharmony_ci } 9551cb0ef41Sopenharmony_ci 9561cb0ef41Sopenharmony_ci sfp->state = SF_STATE_LIST_BEFORE_PARAMS; 9571cb0ef41Sopenharmony_ci 9581cb0ef41Sopenharmony_ci return 0; 9591cb0ef41Sopenharmony_ci} 9601cb0ef41Sopenharmony_ci 9611cb0ef41Sopenharmony_ciint sf_parser_item(sf_parser *sfp, sf_value *dest) { 9621cb0ef41Sopenharmony_ci int rv; 9631cb0ef41Sopenharmony_ci 9641cb0ef41Sopenharmony_ci switch (sfp->state) { 9651cb0ef41Sopenharmony_ci case SF_STATE_INITIAL: 9661cb0ef41Sopenharmony_ci parser_discard_sp(sfp); 9671cb0ef41Sopenharmony_ci 9681cb0ef41Sopenharmony_ci if (parser_eof(sfp)) { 9691cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 9701cb0ef41Sopenharmony_ci } 9711cb0ef41Sopenharmony_ci 9721cb0ef41Sopenharmony_ci break; 9731cb0ef41Sopenharmony_ci case SF_STATE_ITEM_INNER_LIST_BEFORE: 9741cb0ef41Sopenharmony_ci rv = parser_skip_inner_list(sfp); 9751cb0ef41Sopenharmony_ci if (rv != 0) { 9761cb0ef41Sopenharmony_ci return rv; 9771cb0ef41Sopenharmony_ci } 9781cb0ef41Sopenharmony_ci 9791cb0ef41Sopenharmony_ci /* fall through */ 9801cb0ef41Sopenharmony_ci case SF_STATE_ITEM_BEFORE_PARAMS: 9811cb0ef41Sopenharmony_ci rv = parser_skip_params(sfp); 9821cb0ef41Sopenharmony_ci if (rv != 0) { 9831cb0ef41Sopenharmony_ci return rv; 9841cb0ef41Sopenharmony_ci } 9851cb0ef41Sopenharmony_ci 9861cb0ef41Sopenharmony_ci /* fall through */ 9871cb0ef41Sopenharmony_ci case SF_STATE_ITEM_AFTER: 9881cb0ef41Sopenharmony_ci parser_discard_sp(sfp); 9891cb0ef41Sopenharmony_ci 9901cb0ef41Sopenharmony_ci if (!parser_eof(sfp)) { 9911cb0ef41Sopenharmony_ci return SF_ERR_PARSE_ERROR; 9921cb0ef41Sopenharmony_ci } 9931cb0ef41Sopenharmony_ci 9941cb0ef41Sopenharmony_ci return SF_ERR_EOF; 9951cb0ef41Sopenharmony_ci default: 9961cb0ef41Sopenharmony_ci assert(0); 9971cb0ef41Sopenharmony_ci abort(); 9981cb0ef41Sopenharmony_ci } 9991cb0ef41Sopenharmony_ci 10001cb0ef41Sopenharmony_ci if (*sfp->pos == '(') { 10011cb0ef41Sopenharmony_ci if (dest) { 10021cb0ef41Sopenharmony_ci dest->type = SF_TYPE_INNER_LIST; 10031cb0ef41Sopenharmony_ci dest->flags = SF_VALUE_FLAG_NONE; 10041cb0ef41Sopenharmony_ci } 10051cb0ef41Sopenharmony_ci 10061cb0ef41Sopenharmony_ci ++sfp->pos; 10071cb0ef41Sopenharmony_ci 10081cb0ef41Sopenharmony_ci sfp->state = SF_STATE_ITEM_INNER_LIST_BEFORE; 10091cb0ef41Sopenharmony_ci 10101cb0ef41Sopenharmony_ci return 0; 10111cb0ef41Sopenharmony_ci } 10121cb0ef41Sopenharmony_ci 10131cb0ef41Sopenharmony_ci rv = parser_bare_item(sfp, dest); 10141cb0ef41Sopenharmony_ci if (rv != 0) { 10151cb0ef41Sopenharmony_ci return rv; 10161cb0ef41Sopenharmony_ci } 10171cb0ef41Sopenharmony_ci 10181cb0ef41Sopenharmony_ci sfp->state = SF_STATE_ITEM_BEFORE_PARAMS; 10191cb0ef41Sopenharmony_ci 10201cb0ef41Sopenharmony_ci return 0; 10211cb0ef41Sopenharmony_ci} 10221cb0ef41Sopenharmony_ci 10231cb0ef41Sopenharmony_civoid sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen) { 10241cb0ef41Sopenharmony_ci if (datalen == 0) { 10251cb0ef41Sopenharmony_ci sfp->pos = sfp->end = NULL; 10261cb0ef41Sopenharmony_ci } else { 10271cb0ef41Sopenharmony_ci sfp->pos = data; 10281cb0ef41Sopenharmony_ci sfp->end = data + datalen; 10291cb0ef41Sopenharmony_ci } 10301cb0ef41Sopenharmony_ci 10311cb0ef41Sopenharmony_ci sfp->state = SF_STATE_INITIAL; 10321cb0ef41Sopenharmony_ci} 10331cb0ef41Sopenharmony_ci 10341cb0ef41Sopenharmony_civoid sf_unescape(sf_vec *dest, const sf_vec *src) { 10351cb0ef41Sopenharmony_ci const uint8_t *p, *q; 10361cb0ef41Sopenharmony_ci uint8_t *o; 10371cb0ef41Sopenharmony_ci size_t len, slen; 10381cb0ef41Sopenharmony_ci 10391cb0ef41Sopenharmony_ci if (src->len == 0) { 10401cb0ef41Sopenharmony_ci *dest = *src; 10411cb0ef41Sopenharmony_ci 10421cb0ef41Sopenharmony_ci return; 10431cb0ef41Sopenharmony_ci } 10441cb0ef41Sopenharmony_ci 10451cb0ef41Sopenharmony_ci o = dest->base; 10461cb0ef41Sopenharmony_ci p = src->base; 10471cb0ef41Sopenharmony_ci len = src->len; 10481cb0ef41Sopenharmony_ci 10491cb0ef41Sopenharmony_ci for (;;) { 10501cb0ef41Sopenharmony_ci q = memchr(p, '\\', len); 10511cb0ef41Sopenharmony_ci if (q == NULL) { 10521cb0ef41Sopenharmony_ci if (len == src->len) { 10531cb0ef41Sopenharmony_ci *dest = *src; 10541cb0ef41Sopenharmony_ci 10551cb0ef41Sopenharmony_ci return; 10561cb0ef41Sopenharmony_ci } 10571cb0ef41Sopenharmony_ci 10581cb0ef41Sopenharmony_ci memcpy(o, p, len); 10591cb0ef41Sopenharmony_ci o += len; 10601cb0ef41Sopenharmony_ci 10611cb0ef41Sopenharmony_ci break; 10621cb0ef41Sopenharmony_ci } 10631cb0ef41Sopenharmony_ci 10641cb0ef41Sopenharmony_ci slen = (size_t)(q - p); 10651cb0ef41Sopenharmony_ci memcpy(o, p, slen); 10661cb0ef41Sopenharmony_ci o += slen; 10671cb0ef41Sopenharmony_ci 10681cb0ef41Sopenharmony_ci p = q + 1; 10691cb0ef41Sopenharmony_ci *o++ = *p++; 10701cb0ef41Sopenharmony_ci len -= slen + 2; 10711cb0ef41Sopenharmony_ci } 10721cb0ef41Sopenharmony_ci 10731cb0ef41Sopenharmony_ci dest->len = (size_t)(o - dest->base); 10741cb0ef41Sopenharmony_ci} 10751cb0ef41Sopenharmony_ci 10761cb0ef41Sopenharmony_civoid sf_base64decode(sf_vec *dest, const sf_vec *src) { 10771cb0ef41Sopenharmony_ci static const int index_tbl[] = { 10781cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10791cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10801cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 10811cb0ef41Sopenharmony_ci 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 10821cb0ef41Sopenharmony_ci 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 10831cb0ef41Sopenharmony_ci 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 10841cb0ef41Sopenharmony_ci 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, 10851cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10861cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10871cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10881cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10891cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10901cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10911cb0ef41Sopenharmony_ci -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10921cb0ef41Sopenharmony_ci -1, -1, -1, -1}; 10931cb0ef41Sopenharmony_ci uint8_t *o; 10941cb0ef41Sopenharmony_ci const uint8_t *p, *end; 10951cb0ef41Sopenharmony_ci uint32_t n; 10961cb0ef41Sopenharmony_ci size_t i; 10971cb0ef41Sopenharmony_ci int idx; 10981cb0ef41Sopenharmony_ci 10991cb0ef41Sopenharmony_ci assert((src->len & 0x3) == 0); 11001cb0ef41Sopenharmony_ci 11011cb0ef41Sopenharmony_ci if (src->len == 0) { 11021cb0ef41Sopenharmony_ci *dest = *src; 11031cb0ef41Sopenharmony_ci 11041cb0ef41Sopenharmony_ci return; 11051cb0ef41Sopenharmony_ci } 11061cb0ef41Sopenharmony_ci 11071cb0ef41Sopenharmony_ci o = dest->base; 11081cb0ef41Sopenharmony_ci p = src->base; 11091cb0ef41Sopenharmony_ci end = src->base + src->len; 11101cb0ef41Sopenharmony_ci 11111cb0ef41Sopenharmony_ci for (; p != end;) { 11121cb0ef41Sopenharmony_ci n = 0; 11131cb0ef41Sopenharmony_ci 11141cb0ef41Sopenharmony_ci for (i = 1; i <= 4; ++i, ++p) { 11151cb0ef41Sopenharmony_ci idx = index_tbl[*p]; 11161cb0ef41Sopenharmony_ci 11171cb0ef41Sopenharmony_ci if (idx == -1) { 11181cb0ef41Sopenharmony_ci assert(i > 2); 11191cb0ef41Sopenharmony_ci 11201cb0ef41Sopenharmony_ci if (i == 3) { 11211cb0ef41Sopenharmony_ci assert(*p == '=' && *(p + 1) == '=' && p + 2 == end); 11221cb0ef41Sopenharmony_ci 11231cb0ef41Sopenharmony_ci *o++ = (uint8_t)(n >> 16); 11241cb0ef41Sopenharmony_ci 11251cb0ef41Sopenharmony_ci goto fin; 11261cb0ef41Sopenharmony_ci } 11271cb0ef41Sopenharmony_ci 11281cb0ef41Sopenharmony_ci assert(*p == '=' && p + 1 == end); 11291cb0ef41Sopenharmony_ci 11301cb0ef41Sopenharmony_ci *o++ = (uint8_t)(n >> 16); 11311cb0ef41Sopenharmony_ci *o++ = (n >> 8) & 0xffu; 11321cb0ef41Sopenharmony_ci 11331cb0ef41Sopenharmony_ci goto fin; 11341cb0ef41Sopenharmony_ci } 11351cb0ef41Sopenharmony_ci 11361cb0ef41Sopenharmony_ci n += (uint32_t)(idx << (24 - i * 6)); 11371cb0ef41Sopenharmony_ci } 11381cb0ef41Sopenharmony_ci 11391cb0ef41Sopenharmony_ci *o++ = (uint8_t)(n >> 16); 11401cb0ef41Sopenharmony_ci *o++ = (n >> 8) & 0xffu; 11411cb0ef41Sopenharmony_ci *o++ = n & 0xffu; 11421cb0ef41Sopenharmony_ci } 11431cb0ef41Sopenharmony_ci 11441cb0ef41Sopenharmony_cifin: 11451cb0ef41Sopenharmony_ci dest->len = (size_t)(o - dest->base); 11461cb0ef41Sopenharmony_ci} 1147