12c593315Sopenharmony_ci/* 22c593315Sopenharmony_ci * sfparse 32c593315Sopenharmony_ci * 42c593315Sopenharmony_ci * Copyright (c) 2023 sfparse contributors 52c593315Sopenharmony_ci * Copyright (c) 2019 nghttp3 contributors 62c593315Sopenharmony_ci * Copyright (c) 2015 nghttp2 contributors 72c593315Sopenharmony_ci * 82c593315Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining 92c593315Sopenharmony_ci * a copy of this software and associated documentation files (the 102c593315Sopenharmony_ci * "Software"), to deal in the Software without restriction, including 112c593315Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish, 122c593315Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to 132c593315Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to 142c593315Sopenharmony_ci * the following conditions: 152c593315Sopenharmony_ci * 162c593315Sopenharmony_ci * The above copyright notice and this permission notice shall be 172c593315Sopenharmony_ci * included in all copies or substantial portions of the Software. 182c593315Sopenharmony_ci * 192c593315Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 202c593315Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 212c593315Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 222c593315Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 232c593315Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 242c593315Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 252c593315Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 262c593315Sopenharmony_ci */ 272c593315Sopenharmony_ci#ifndef SFPARSE_H 282c593315Sopenharmony_ci#define SFPARSE_H 292c593315Sopenharmony_ci 302c593315Sopenharmony_ci/* Define WIN32 when build target is Win32 API (borrowed from 312c593315Sopenharmony_ci libcurl) */ 322c593315Sopenharmony_ci#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) 332c593315Sopenharmony_ci# define WIN32 342c593315Sopenharmony_ci#endif 352c593315Sopenharmony_ci 362c593315Sopenharmony_ci#ifdef __cplusplus 372c593315Sopenharmony_ciextern "C" { 382c593315Sopenharmony_ci#endif 392c593315Sopenharmony_ci 402c593315Sopenharmony_ci#if defined(_MSC_VER) && (_MSC_VER < 1800) 412c593315Sopenharmony_ci/* MSVC < 2013 does not have inttypes.h because it is not C99 422c593315Sopenharmony_ci compliant. See compiler macros and version number in 432c593315Sopenharmony_ci https://sourceforge.net/p/predef/wiki/Compilers/ */ 442c593315Sopenharmony_ci# include <stdint.h> 452c593315Sopenharmony_ci#else /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ 462c593315Sopenharmony_ci# include <inttypes.h> 472c593315Sopenharmony_ci#endif /* !defined(_MSC_VER) || (_MSC_VER >= 1800) */ 482c593315Sopenharmony_ci#include <sys/types.h> 492c593315Sopenharmony_ci#include <stddef.h> 502c593315Sopenharmony_ci 512c593315Sopenharmony_ci/** 522c593315Sopenharmony_ci * @enum 532c593315Sopenharmony_ci * 542c593315Sopenharmony_ci * :type:`sf_type` defines value type. 552c593315Sopenharmony_ci */ 562c593315Sopenharmony_citypedef enum sf_type { 572c593315Sopenharmony_ci /** 582c593315Sopenharmony_ci * :enum:`SF_TYPE_BOOLEAN` indicates boolean type. 592c593315Sopenharmony_ci */ 602c593315Sopenharmony_ci SF_TYPE_BOOLEAN, 612c593315Sopenharmony_ci /** 622c593315Sopenharmony_ci * :enum:`SF_TYPE_INTEGER` indicates integer type. 632c593315Sopenharmony_ci */ 642c593315Sopenharmony_ci SF_TYPE_INTEGER, 652c593315Sopenharmony_ci /** 662c593315Sopenharmony_ci * :enum:`SF_TYPE_DECIMAL` indicates decimal type. 672c593315Sopenharmony_ci */ 682c593315Sopenharmony_ci SF_TYPE_DECIMAL, 692c593315Sopenharmony_ci /** 702c593315Sopenharmony_ci * :enum:`SF_TYPE_STRING` indicates string type. 712c593315Sopenharmony_ci */ 722c593315Sopenharmony_ci SF_TYPE_STRING, 732c593315Sopenharmony_ci /** 742c593315Sopenharmony_ci * :enum:`SF_TYPE_TOKEN` indicates token type. 752c593315Sopenharmony_ci */ 762c593315Sopenharmony_ci SF_TYPE_TOKEN, 772c593315Sopenharmony_ci /** 782c593315Sopenharmony_ci * :enum:`SF_TYPE_BYTESEQ` indicates byte sequence type. 792c593315Sopenharmony_ci */ 802c593315Sopenharmony_ci SF_TYPE_BYTESEQ, 812c593315Sopenharmony_ci /** 822c593315Sopenharmony_ci * :enum:`SF_TYPE_INNER_LIST` indicates inner list type. 832c593315Sopenharmony_ci */ 842c593315Sopenharmony_ci SF_TYPE_INNER_LIST, 852c593315Sopenharmony_ci /** 862c593315Sopenharmony_ci * :enum:`SF_TYPE_DATE` indicates date type. 872c593315Sopenharmony_ci */ 882c593315Sopenharmony_ci SF_TYPE_DATE 892c593315Sopenharmony_ci} sf_type; 902c593315Sopenharmony_ci 912c593315Sopenharmony_ci/** 922c593315Sopenharmony_ci * @macro 932c593315Sopenharmony_ci * 942c593315Sopenharmony_ci * :macro:`SF_ERR_PARSE_ERROR` indicates fatal parse error has 952c593315Sopenharmony_ci * occurred, and it is not possible to continue the processing. 962c593315Sopenharmony_ci */ 972c593315Sopenharmony_ci#define SF_ERR_PARSE_ERROR -1 982c593315Sopenharmony_ci 992c593315Sopenharmony_ci/** 1002c593315Sopenharmony_ci * @macro 1012c593315Sopenharmony_ci * 1022c593315Sopenharmony_ci * :macro:`SF_ERR_EOF` indicates that there is nothing left to read. 1032c593315Sopenharmony_ci * The context of this error varies depending on the function that 1042c593315Sopenharmony_ci * returns this error code. 1052c593315Sopenharmony_ci */ 1062c593315Sopenharmony_ci#define SF_ERR_EOF -2 1072c593315Sopenharmony_ci 1082c593315Sopenharmony_ci/** 1092c593315Sopenharmony_ci * @struct 1102c593315Sopenharmony_ci * 1112c593315Sopenharmony_ci * :type:`sf_vec` stores sequence of bytes. 1122c593315Sopenharmony_ci */ 1132c593315Sopenharmony_citypedef struct sf_vec { 1142c593315Sopenharmony_ci /** 1152c593315Sopenharmony_ci * :member:`base` points to the beginning of the sequence of bytes. 1162c593315Sopenharmony_ci */ 1172c593315Sopenharmony_ci uint8_t *base; 1182c593315Sopenharmony_ci /** 1192c593315Sopenharmony_ci * :member:`len` is the number of bytes contained in this sequence. 1202c593315Sopenharmony_ci */ 1212c593315Sopenharmony_ci size_t len; 1222c593315Sopenharmony_ci} sf_vec; 1232c593315Sopenharmony_ci 1242c593315Sopenharmony_ci/** 1252c593315Sopenharmony_ci * @macro 1262c593315Sopenharmony_ci * 1272c593315Sopenharmony_ci * :macro:`SF_VALUE_FLAG_NONE` indicates no flag set. 1282c593315Sopenharmony_ci */ 1292c593315Sopenharmony_ci#define SF_VALUE_FLAG_NONE 0x0u 1302c593315Sopenharmony_ci 1312c593315Sopenharmony_ci/** 1322c593315Sopenharmony_ci * @macro 1332c593315Sopenharmony_ci * 1342c593315Sopenharmony_ci * :macro:`SF_VALUE_FLAG_ESCAPED_STRING` indicates that a string 1352c593315Sopenharmony_ci * contains escaped character(s). 1362c593315Sopenharmony_ci */ 1372c593315Sopenharmony_ci#define SF_VALUE_FLAG_ESCAPED_STRING 0x1u 1382c593315Sopenharmony_ci 1392c593315Sopenharmony_ci/** 1402c593315Sopenharmony_ci * @struct 1412c593315Sopenharmony_ci * 1422c593315Sopenharmony_ci * :type:`sf_decimal` contains decimal value. 1432c593315Sopenharmony_ci */ 1442c593315Sopenharmony_citypedef struct sf_decimal { 1452c593315Sopenharmony_ci /** 1462c593315Sopenharmony_ci * :member:`numer` contains numerator of the decimal value. 1472c593315Sopenharmony_ci */ 1482c593315Sopenharmony_ci int64_t numer; 1492c593315Sopenharmony_ci /** 1502c593315Sopenharmony_ci * :member:`denom` contains denominator of the decimal value. 1512c593315Sopenharmony_ci */ 1522c593315Sopenharmony_ci int64_t denom; 1532c593315Sopenharmony_ci} sf_decimal; 1542c593315Sopenharmony_ci 1552c593315Sopenharmony_ci/** 1562c593315Sopenharmony_ci * @struct 1572c593315Sopenharmony_ci * 1582c593315Sopenharmony_ci * :type:`sf_value` stores a Structured Field item. For Inner List, 1592c593315Sopenharmony_ci * only type is set to :enum:`sf_type.SF_TYPE_INNER_LIST`. In order 1602c593315Sopenharmony_ci * to read the items contained in an inner list, call 1612c593315Sopenharmony_ci * `sf_parser_inner_list`. 1622c593315Sopenharmony_ci */ 1632c593315Sopenharmony_citypedef struct sf_value { 1642c593315Sopenharmony_ci /** 1652c593315Sopenharmony_ci * :member:`type` is the type of the value contained in this 1662c593315Sopenharmony_ci * particular object. 1672c593315Sopenharmony_ci */ 1682c593315Sopenharmony_ci sf_type type; 1692c593315Sopenharmony_ci /** 1702c593315Sopenharmony_ci * :member:`flags` is bitwise OR of one or more of 1712c593315Sopenharmony_ci * :macro:`SF_VALUE_FLAG_* <SF_VALUE_FLAG_NONE>`. 1722c593315Sopenharmony_ci */ 1732c593315Sopenharmony_ci uint32_t flags; 1742c593315Sopenharmony_ci /** 1752c593315Sopenharmony_ci * @anonunion_start 1762c593315Sopenharmony_ci * 1772c593315Sopenharmony_ci * @sf_value_value 1782c593315Sopenharmony_ci */ 1792c593315Sopenharmony_ci union { 1802c593315Sopenharmony_ci /** 1812c593315Sopenharmony_ci * :member:`boolean` contains boolean value if :member:`type` == 1822c593315Sopenharmony_ci * :enum:`sf_type.SF_TYPE_BOOLEAN`. 1 indicates true, and 0 1832c593315Sopenharmony_ci * indicates false. 1842c593315Sopenharmony_ci */ 1852c593315Sopenharmony_ci int boolean; 1862c593315Sopenharmony_ci /** 1872c593315Sopenharmony_ci * :member:`integer` contains integer value if :member:`type` is 1882c593315Sopenharmony_ci * either :enum:`sf_type.SF_TYPE_INTEGER` or 1892c593315Sopenharmony_ci * :enum:`sf_type.SF_TYPE_DATE`. 1902c593315Sopenharmony_ci */ 1912c593315Sopenharmony_ci int64_t integer; 1922c593315Sopenharmony_ci /** 1932c593315Sopenharmony_ci * :member:`decimal` contains decimal value if :member:`type` == 1942c593315Sopenharmony_ci * :enum:`sf_type.SF_TYPE_DECIMAL`. 1952c593315Sopenharmony_ci */ 1962c593315Sopenharmony_ci sf_decimal decimal; 1972c593315Sopenharmony_ci /** 1982c593315Sopenharmony_ci * :member:`vec` contains sequence of bytes if :member:`type` is 1992c593315Sopenharmony_ci * either :enum:`sf_type.SF_TYPE_STRING`, 2002c593315Sopenharmony_ci * :enum:`sf_type.SF_TYPE_TOKEN`, or 2012c593315Sopenharmony_ci * :enum:`sf_type.SF_TYPE_BYTESEQ`. 2022c593315Sopenharmony_ci * 2032c593315Sopenharmony_ci * For :enum:`sf_type.SF_TYPE_STRING`, this field contains one or 2042c593315Sopenharmony_ci * more escaped characters if :member:`flags` has 2052c593315Sopenharmony_ci * :macro:`SF_VALUE_FLAG_ESCAPED_STRING` set. To unescape the 2062c593315Sopenharmony_ci * string, use `sf_unescape`. 2072c593315Sopenharmony_ci * 2082c593315Sopenharmony_ci * For :enum:`sf_type.SF_TYPE_BYTESEQ`, this field contains base64 2092c593315Sopenharmony_ci * encoded string. To decode this byte string, use 2102c593315Sopenharmony_ci * `sf_base64decode`. 2112c593315Sopenharmony_ci * 2122c593315Sopenharmony_ci * If :member:`vec.len <sf_vec.len>` == 0, :member:`vec.base 2132c593315Sopenharmony_ci * <sf_vec.base>` is guaranteed to be NULL. 2142c593315Sopenharmony_ci */ 2152c593315Sopenharmony_ci sf_vec vec; 2162c593315Sopenharmony_ci /** 2172c593315Sopenharmony_ci * @anonunion_end 2182c593315Sopenharmony_ci */ 2192c593315Sopenharmony_ci }; 2202c593315Sopenharmony_ci} sf_value; 2212c593315Sopenharmony_ci 2222c593315Sopenharmony_ci/** 2232c593315Sopenharmony_ci * @struct 2242c593315Sopenharmony_ci * 2252c593315Sopenharmony_ci * :type:`sf_parser` is the Structured Field Values parser. Use 2262c593315Sopenharmony_ci * `sf_parser_init` to initialize it. 2272c593315Sopenharmony_ci */ 2282c593315Sopenharmony_citypedef struct sf_parser { 2292c593315Sopenharmony_ci /* all fields are private */ 2302c593315Sopenharmony_ci const uint8_t *pos; 2312c593315Sopenharmony_ci const uint8_t *end; 2322c593315Sopenharmony_ci uint32_t state; 2332c593315Sopenharmony_ci} sf_parser; 2342c593315Sopenharmony_ci 2352c593315Sopenharmony_ci/** 2362c593315Sopenharmony_ci * @function 2372c593315Sopenharmony_ci * 2382c593315Sopenharmony_ci * `sf_parser_init` initializes |sfp| with the given buffer pointed by 2392c593315Sopenharmony_ci * |data| of length |datalen|. 2402c593315Sopenharmony_ci */ 2412c593315Sopenharmony_civoid sf_parser_init(sf_parser *sfp, const uint8_t *data, size_t datalen); 2422c593315Sopenharmony_ci 2432c593315Sopenharmony_ci/** 2442c593315Sopenharmony_ci * @function 2452c593315Sopenharmony_ci * 2462c593315Sopenharmony_ci * `sf_parser_param` reads a parameter. If this function returns 0, 2472c593315Sopenharmony_ci * it stores parameter key and value in |dest_key| and |dest_value| 2482c593315Sopenharmony_ci * respectively, if they are not NULL. 2492c593315Sopenharmony_ci * 2502c593315Sopenharmony_ci * This function does no effort to find duplicated keys. Same key may 2512c593315Sopenharmony_ci * be reported more than once. 2522c593315Sopenharmony_ci * 2532c593315Sopenharmony_ci * Caller should keep calling this function until it returns negative 2542c593315Sopenharmony_ci * error code. If it returns :macro:`SF_ERR_EOF`, all parameters have 2552c593315Sopenharmony_ci * read, and caller can continue to read rest of the values. If it 2562c593315Sopenharmony_ci * returns :macro:`SF_ERR_PARSE_ERROR`, it encountered fatal error 2572c593315Sopenharmony_ci * while parsing field value. 2582c593315Sopenharmony_ci */ 2592c593315Sopenharmony_ciint sf_parser_param(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value); 2602c593315Sopenharmony_ci 2612c593315Sopenharmony_ci/** 2622c593315Sopenharmony_ci * @function 2632c593315Sopenharmony_ci * 2642c593315Sopenharmony_ci * `sf_parser_dict` reads the next dictionary key and value pair. If 2652c593315Sopenharmony_ci * this function returns 0, it stores the key and value in |dest_key| 2662c593315Sopenharmony_ci * and |dest_value| respectively, if they are not NULL. 2672c593315Sopenharmony_ci * 2682c593315Sopenharmony_ci * Caller can optionally read parameters attached to the pair by 2692c593315Sopenharmony_ci * calling `sf_parser_param`. 2702c593315Sopenharmony_ci * 2712c593315Sopenharmony_ci * This function does no effort to find duplicated keys. Same key may 2722c593315Sopenharmony_ci * be reported more than once. 2732c593315Sopenharmony_ci * 2742c593315Sopenharmony_ci * Caller should keep calling this function until it returns negative 2752c593315Sopenharmony_ci * error code. If it returns :macro:`SF_ERR_EOF`, all key and value 2762c593315Sopenharmony_ci * pairs have been read, and there is nothing left to read. 2772c593315Sopenharmony_ci * 2782c593315Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 2792c593315Sopenharmony_ci * negative error codes: 2802c593315Sopenharmony_ci * 2812c593315Sopenharmony_ci * :macro:`SF_ERR_EOF` 2822c593315Sopenharmony_ci * All values in the dictionary have read. 2832c593315Sopenharmony_ci * :macro:`SF_ERR_PARSE_ERROR` 2842c593315Sopenharmony_ci * It encountered fatal error while parsing field value. 2852c593315Sopenharmony_ci */ 2862c593315Sopenharmony_ciint sf_parser_dict(sf_parser *sfp, sf_vec *dest_key, sf_value *dest_value); 2872c593315Sopenharmony_ci 2882c593315Sopenharmony_ci/** 2892c593315Sopenharmony_ci * @function 2902c593315Sopenharmony_ci * 2912c593315Sopenharmony_ci * `sf_parser_list` reads the next list item. If this function 2922c593315Sopenharmony_ci * returns 0, it stores the item in |dest| if it is not NULL. 2932c593315Sopenharmony_ci * 2942c593315Sopenharmony_ci * Caller can optionally read parameters attached to the item by 2952c593315Sopenharmony_ci * calling `sf_parser_param`. 2962c593315Sopenharmony_ci * 2972c593315Sopenharmony_ci * Caller should keep calling this function until it returns negative 2982c593315Sopenharmony_ci * error code. If it returns :macro:`SF_ERR_EOF`, all values in the 2992c593315Sopenharmony_ci * list have been read, and there is nothing left to read. 3002c593315Sopenharmony_ci * 3012c593315Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 3022c593315Sopenharmony_ci * negative error codes: 3032c593315Sopenharmony_ci * 3042c593315Sopenharmony_ci * :macro:`SF_ERR_EOF` 3052c593315Sopenharmony_ci * All values in the list have read. 3062c593315Sopenharmony_ci * :macro:`SF_ERR_PARSE_ERROR` 3072c593315Sopenharmony_ci * It encountered fatal error while parsing field value. 3082c593315Sopenharmony_ci */ 3092c593315Sopenharmony_ciint sf_parser_list(sf_parser *sfp, sf_value *dest); 3102c593315Sopenharmony_ci 3112c593315Sopenharmony_ci/** 3122c593315Sopenharmony_ci * @function 3132c593315Sopenharmony_ci * 3142c593315Sopenharmony_ci * `sf_parser_item` reads a single item. If this function returns 0, 3152c593315Sopenharmony_ci * it stores the item in |dest| if it is not NULL. 3162c593315Sopenharmony_ci * 3172c593315Sopenharmony_ci * This function is only used for the field value that consists of a 3182c593315Sopenharmony_ci * single item. 3192c593315Sopenharmony_ci * 3202c593315Sopenharmony_ci * Caller can optionally read parameters attached to the item by 3212c593315Sopenharmony_ci * calling `sf_parser_param`. 3222c593315Sopenharmony_ci * 3232c593315Sopenharmony_ci * Caller should call this function again to make sure that there is 3242c593315Sopenharmony_ci * nothing left to read. If this 2nd function call returns 3252c593315Sopenharmony_ci * :macro:`SF_ERR_EOF`, all data have been processed successfully. 3262c593315Sopenharmony_ci * 3272c593315Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 3282c593315Sopenharmony_ci * negative error codes: 3292c593315Sopenharmony_ci * 3302c593315Sopenharmony_ci * :macro:`SF_ERR_EOF` 3312c593315Sopenharmony_ci * There is nothing left to read. 3322c593315Sopenharmony_ci * :macro:`SF_ERR_PARSE_ERROR` 3332c593315Sopenharmony_ci * It encountered fatal error while parsing field value. 3342c593315Sopenharmony_ci */ 3352c593315Sopenharmony_ciint sf_parser_item(sf_parser *sfp, sf_value *dest); 3362c593315Sopenharmony_ci 3372c593315Sopenharmony_ci/** 3382c593315Sopenharmony_ci * @function 3392c593315Sopenharmony_ci * 3402c593315Sopenharmony_ci * `sf_parser_inner_list` reads the next inner list item. If this 3412c593315Sopenharmony_ci * function returns 0, it stores the item in |dest| if it is not NULL. 3422c593315Sopenharmony_ci * 3432c593315Sopenharmony_ci * Caller can optionally read parameters attached to the item by 3442c593315Sopenharmony_ci * calling `sf_parser_param`. 3452c593315Sopenharmony_ci * 3462c593315Sopenharmony_ci * Caller should keep calling this function until it returns negative 3472c593315Sopenharmony_ci * error code. If it returns :macro:`SF_ERR_EOF`, all values in this 3482c593315Sopenharmony_ci * inner list have been read, and caller can optionally read 3492c593315Sopenharmony_ci * parameters attached to this inner list by calling 3502c593315Sopenharmony_ci * `sf_parser_param`. Then caller can continue to read rest of the 3512c593315Sopenharmony_ci * values. 3522c593315Sopenharmony_ci * 3532c593315Sopenharmony_ci * This function returns 0 if it succeeds, or one of the following 3542c593315Sopenharmony_ci * negative error codes: 3552c593315Sopenharmony_ci * 3562c593315Sopenharmony_ci * :macro:`SF_ERR_EOF` 3572c593315Sopenharmony_ci * All values in the inner list have read. 3582c593315Sopenharmony_ci * :macro:`SF_ERR_PARSE_ERROR` 3592c593315Sopenharmony_ci * It encountered fatal error while parsing field value. 3602c593315Sopenharmony_ci */ 3612c593315Sopenharmony_ciint sf_parser_inner_list(sf_parser *sfp, sf_value *dest); 3622c593315Sopenharmony_ci 3632c593315Sopenharmony_ci/** 3642c593315Sopenharmony_ci * @function 3652c593315Sopenharmony_ci * 3662c593315Sopenharmony_ci * `sf_unescape` copies |src| to |dest| by removing escapes (``\``). 3672c593315Sopenharmony_ci * |src| should be the pointer to :member:`sf_value.vec` of type 3682c593315Sopenharmony_ci * :enum:`sf_type.SF_TYPE_STRING` produced by either `sf_parser_dict`, 3692c593315Sopenharmony_ci * `sf_parser_list`, `sf_parser_inner_list`, `sf_parser_item`, or 3702c593315Sopenharmony_ci * `sf_parser_param`, otherwise the behavior is undefined. 3712c593315Sopenharmony_ci * 3722c593315Sopenharmony_ci * :member:`dest->base <sf_vec.base>` must point to the buffer that 3732c593315Sopenharmony_ci * has sufficient space to store the unescaped string. 3742c593315Sopenharmony_ci * 3752c593315Sopenharmony_ci * If there is no escape character in |src|, |*src| is assigned to 3762c593315Sopenharmony_ci * |*dest|. This includes the case that :member:`src->len 3772c593315Sopenharmony_ci * <sf_vec.len>` == 0. 3782c593315Sopenharmony_ci * 3792c593315Sopenharmony_ci * This function sets the length of unescaped string to 3802c593315Sopenharmony_ci * :member:`dest->len <sf_vec.len>`. 3812c593315Sopenharmony_ci */ 3822c593315Sopenharmony_civoid sf_unescape(sf_vec *dest, const sf_vec *src); 3832c593315Sopenharmony_ci 3842c593315Sopenharmony_ci/** 3852c593315Sopenharmony_ci * @function 3862c593315Sopenharmony_ci * 3872c593315Sopenharmony_ci * `sf_base64decode` decodes Base64 encoded string |src| and writes 3882c593315Sopenharmony_ci * the result into |dest|. |src| should be the pointer to 3892c593315Sopenharmony_ci * :member:`sf_value.vec` of type :enum:`sf_type.SF_TYPE_BYTESEQ` 3902c593315Sopenharmony_ci * produced by either `sf_parser_dict`, `sf_parser_list`, 3912c593315Sopenharmony_ci * `sf_parser_inner_list`, `sf_parser_item`, or `sf_parser_param`, 3922c593315Sopenharmony_ci * otherwise the behavior is undefined. 3932c593315Sopenharmony_ci * 3942c593315Sopenharmony_ci * :member:`dest->base <sf_vec.base>` must point to the buffer that 3952c593315Sopenharmony_ci * has sufficient space to store the decoded byte string. 3962c593315Sopenharmony_ci * 3972c593315Sopenharmony_ci * If :member:`src->len <sf_vec.len>` == 0, |*src| is assigned to 3982c593315Sopenharmony_ci * |*dest|. 3992c593315Sopenharmony_ci * 4002c593315Sopenharmony_ci * This function sets the length of decoded byte string to 4012c593315Sopenharmony_ci * :member:`dest->len <sf_vec.len>`. 4022c593315Sopenharmony_ci */ 4032c593315Sopenharmony_civoid sf_base64decode(sf_vec *dest, const sf_vec *src); 4042c593315Sopenharmony_ci 4052c593315Sopenharmony_ci#ifdef __cplusplus 4062c593315Sopenharmony_ci} 4072c593315Sopenharmony_ci#endif 4082c593315Sopenharmony_ci 4092c593315Sopenharmony_ci#endif /* SFPARSE_H */ 410