node/deps/ngtcp2/nghttp3/lib/sfparse/sfparse.h
James M Snell ebfc28a037 deps: update nghttp3 to 1.11.0
Signed-off-by: James M Snell <jasnell@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/59249
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
2025-08-03 13:48:30 -07:00

442 lines
14 KiB
C

/*
* sfparse
*
* Copyright (c) 2023 sfparse contributors
* Copyright (c) 2019 nghttp3 contributors
* Copyright (c) 2015 nghttp2 contributors
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef SFPARSE_H
#define SFPARSE_H
/* Define WIN32 when build target is Win32 API (borrowed from
libcurl) */
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32
#endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */
#ifdef __cplusplus
extern "C" {
#endif /* defined(__cplusplus) */
#if defined(_MSC_VER) && (_MSC_VER < 1800)
/* MSVC < 2013 does not have inttypes.h because it is not C99
compliant. See compiler macros and version number in
https://sourceforge.net/p/predef/wiki/Compilers/ */
# include <stdint.h>
#else /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
# include <inttypes.h>
#endif /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
#include <sys/types.h>
#include <stddef.h>
/**
* @enum
*
* :type:`sfparse_type` defines value type.
*/
typedef enum sfparse_type {
/**
* :enum:`SFPARSE_TYPE_BOOLEAN` indicates boolean type.
*/
SFPARSE_TYPE_BOOLEAN,
/**
* :enum:`SFPARSE_TYPE_INTEGER` indicates integer type.
*/
SFPARSE_TYPE_INTEGER,
/**
* :enum:`SFPARSE_TYPE_DECIMAL` indicates decimal type.
*/
SFPARSE_TYPE_DECIMAL,
/**
* :enum:`SFPARSE_TYPE_STRING` indicates string type.
*/
SFPARSE_TYPE_STRING,
/**
* :enum:`SFPARSE_TYPE_TOKEN` indicates token type.
*/
SFPARSE_TYPE_TOKEN,
/**
* :enum:`SFPARSE_TYPE_BYTESEQ` indicates byte sequence type.
*/
SFPARSE_TYPE_BYTESEQ,
/**
* :enum:`SFPARSE_TYPE_INNER_LIST` indicates inner list type.
*/
SFPARSE_TYPE_INNER_LIST,
/**
* :enum:`SFPARSE_TYPE_DATE` indicates date type.
*/
SFPARSE_TYPE_DATE,
/**
* :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string type.
*/
SFPARSE_TYPE_DISPSTRING
} sfparse_type;
/**
* @macro
*
* :macro:`SFPARSE_ERR_PARSE` indicates fatal parse error has
* occurred, and it is not possible to continue the processing.
*/
#define SFPARSE_ERR_PARSE -1
/**
* @macro
*
* :macro:`SFPARSE_ERR_EOF` indicates that there is nothing left to
* read. The context of this error varies depending on the function
* that returns this error code.
*/
#define SFPARSE_ERR_EOF -2
/**
* @struct
*
* :type:`sfparse_vec` stores sequence of bytes.
*/
typedef struct sfparse_vec {
/**
* :member:`base` points to the beginning of the sequence of bytes.
*/
uint8_t *base;
/**
* :member:`len` is the number of bytes contained in this sequence.
*/
size_t len;
} sfparse_vec;
/**
* @macro
*
* :macro:`SFPARSE_VALUE_FLAG_NONE` indicates no flag set.
*/
#define SFPARSE_VALUE_FLAG_NONE 0x0u
/**
* @macro
*
* :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` indicates that a string
* contains escaped character(s).
*/
#define SFPARSE_VALUE_FLAG_ESCAPED_STRING 0x1u
/**
* @struct
*
* :type:`sfparse_decimal` contains decimal value.
*/
typedef struct sfparse_decimal {
/**
* :member:`numer` contains numerator of the decimal value.
*/
int64_t numer;
/**
* :member:`denom` contains denominator of the decimal value.
*/
int64_t denom;
} sfparse_decimal;
/**
* @struct
*
* :type:`sfparse_value` stores a Structured Field item. For Inner
* List, only type is set to
* :enum:`sfparse_type.SFPARSE_TYPE_INNER_LIST`. In order to read the
* items contained in an inner list, call `sfparse_parser_inner_list`.
*/
typedef struct sfparse_value {
/**
* :member:`type` is the type of the value contained in this
* particular object.
*/
sfparse_type type;
/**
* :member:`flags` is bitwise OR of one or more of
* :macro:`SFPARSE_VALUE_FLAG_* <SFPARSE_VALUE_FLAG_NONE>`.
*/
uint32_t flags;
/**
* @anonunion_start
*
* @sfparse_value_value
*/
union {
/**
* :member:`boolean` contains boolean value if :member:`type` ==
* :enum:`sfparse_type.SFPARSE_TYPE_BOOLEAN`. 1 indicates true,
* and 0 indicates false.
*/
int boolean;
/**
* :member:`integer` contains integer value if :member:`type` is
* either :enum:`sfparse_type.SFPARSE_TYPE_INTEGER` or
* :enum:`sfparse_type.SFPARSE_TYPE_DATE`.
*/
int64_t integer;
/**
* :member:`decimal` contains decimal value if :member:`type` ==
* :enum:`sfparse_type.SFPARSE_TYPE_DECIMAL`.
*/
sfparse_decimal decimal;
/**
* :member:`vec` contains sequence of bytes if :member:`type` is
* either :enum:`sfparse_type.SFPARSE_TYPE_STRING`,
* :enum:`sfparse_type.SFPARSE_TYPE_TOKEN`,
* :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, or
* :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`.
*
* For :enum:`sfparse_type.SFPARSE_TYPE_STRING`, this field
* contains one or more escaped characters if :member:`flags` has
* :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` set. To unescape
* the string, use `sfparse_unescape`.
*
* For :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, this field
* contains base64 encoded string. To decode this byte string,
* use `sfparse_base64decode`.
*
* For :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`, this field
* may contain percent-encoded UTF-8 byte sequences. To decode
* it, use `sfparse_pctdecode`.
*
* If :member:`vec.len <sfparse_vec.len>` == 0, :member:`vec.base
* <sfparse_vec.base>` is guaranteed to be NULL.
*/
sfparse_vec vec;
/**
* @anonunion_end
*/
};
} sfparse_value;
/**
* @struct
*
* :type:`sfparse_parser` is the Structured Field Values parser. Use
* `sfparse_parser_init` to initialize it.
*/
typedef struct sfparse_parser {
/* all fields are private */
const uint8_t *pos;
const uint8_t *end;
uint32_t state;
} sfparse_parser;
/**
* @function
*
* `sfparse_parser_init` initializes |sfp| with the given data encoded
* in Structured Field Values pointed by |data| of length |datalen|.
*/
void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data,
size_t datalen);
/**
* @function
*
* `sfparse_parser_param` reads a parameter. If this function returns
* 0, it stores parameter key and value in |dest_key| and |dest_value|
* respectively, if they are not NULL.
*
* This function does no effort to find duplicated keys. Same key may
* be reported more than once.
*
* Caller should keep calling this function until it returns negative
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all parameters
* have read, and caller can continue to read rest of the values. If
* it returns :macro:`SFPARSE_ERR_PARSE`, it encountered fatal error
* while parsing field value.
*/
int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key,
sfparse_value *dest_value);
/**
* @function
*
* `sfparse_parser_dict` reads the next dictionary key and value pair.
* If this function returns 0, it stores the key and value in
* |dest_key| and |dest_value| respectively, if they are not NULL.
*
* Caller can optionally read parameters attached to the pair by
* calling `sfparse_parser_param`.
*
* This function does no effort to find duplicated keys. Same key may
* be reported more than once.
*
* Caller should keep calling this function until it returns negative
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all key and
* value pairs have been read, and there is nothing left to read.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :macro:`SFPARSE_ERR_EOF`
* All values in the dictionary have read.
* :macro:`SFPARSE_ERR_PARSE`
* It encountered fatal error while parsing field value.
*/
int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key,
sfparse_value *dest_value);
/**
* @function
*
* `sfparse_parser_list` reads the next list item. If this function
* returns 0, it stores the item in |dest| if it is not NULL.
*
* Caller can optionally read parameters attached to the item by
* calling `sfparse_parser_param`.
*
* Caller should keep calling this function until it returns negative
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in
* the list have been read, and there is nothing left to read.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :macro:`SFPARSE_ERR_EOF`
* All values in the list have read.
* :macro:`SFPARSE_ERR_PARSE`
* It encountered fatal error while parsing field value.
*/
int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest);
/**
* @function
*
* `sfparse_parser_item` reads a single item. If this function
* returns 0, it stores the item in |dest| if it is not NULL.
*
* This function is only used for the field value that consists of a
* single item.
*
* Caller can optionally read parameters attached to the item by
* calling `sfparse_parser_param`.
*
* Caller should call this function again to make sure that there is
* nothing left to read. If this 2nd function call returns
* :macro:`SFPARSE_ERR_EOF`, all data have been processed
* successfully.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :macro:`SFPARSE_ERR_EOF`
* There is nothing left to read.
* :macro:`SFPARSE_ERR_PARSE`
* It encountered fatal error while parsing field value.
*/
int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest);
/**
* @function
*
* `sfparse_parser_inner_list` reads the next inner list item. If
* this function returns 0, it stores the item in |dest| if it is not
* NULL.
*
* Caller can optionally read parameters attached to the item by
* calling `sfparse_parser_param`.
*
* Caller should keep calling this function until it returns negative
* error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in
* this inner list have been read, and caller can optionally read
* parameters attached to this inner list by calling
* `sfparse_parser_param`. Then caller can continue to read rest of
* the values.
*
* This function returns 0 if it succeeds, or one of the following
* negative error codes:
*
* :macro:`SFPARSE_ERR_EOF`
* All values in the inner list have read.
* :macro:`SFPARSE_ERR_PARSE`
* It encountered fatal error while parsing field value.
*/
int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest);
/**
* @function
*
* `sfparse_unescape` copies |src| to |dest| by removing escapes
* (``\``). |src| should be the pointer to
* :member:`sfparse_value.vec` of type
* :enum:`sfparse_type.SFPARSE_TYPE_STRING` produced by either
* `sfparse_parser_dict`, `sfparse_parser_list`,
* `sfparse_parser_inner_list`, `sfparse_parser_item`, or
* `sfparse_parser_param`, otherwise the behavior is undefined.
*
* :member:`dest->base <sfparse_vec.base>` must point to the buffer
* that has sufficient space to store the unescaped string. The
* memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
* :member:`src->base <sfparse_vec.base>` must not overlap.
*
* This function sets the length of unescaped string to
* :member:`dest->len <sfparse_vec.len>`.
*/
void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src);
/**
* @function
*
* `sfparse_base64decode` decodes Base64 encoded string |src| and
* writes the result into |dest|. |src| should be the pointer to
* :member:`sfparse_value.vec` of type
* :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ` produced by either
* `sfparse_parser_dict`, `sfparse_parser_list`,
* `sfparse_parser_inner_list`, `sfparse_parser_item`, or
* `sfparse_parser_param`, otherwise the behavior is undefined.
*
* :member:`dest->base <sfparse_vec.base>` must point to the buffer
* that has sufficient space to store the decoded byte string.
*
* This function sets the length of decoded byte string to
* :member:`dest->len <sfparse_vec.len>`.
*/
void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src);
/**
* @function
*
* `sfparse_pctdecode` decodes percent-encoded string |src| and writes
* the result into |dest|. |src| should be the pointer to
* :member:`sfparse_value.vec` of type
* :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING` produced by either
* `sfparse_parser_dict`, `sfparse_parser_list`,
* `sfparse_parser_inner_list`, `sfparse_parser_item`, or
* `sfparse_parser_param`, otherwise the behavior is undefined.
*
* :member:`dest->base <sfparse_vec.base>` must point to the buffer
* that has sufficient space to store the decoded byte string. The
* memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
* :member:`src->base <sfparse_vec.base>` must not overlap.
*
* This function sets the length of decoded byte string to
* :member:`dest->len <sfparse_vec.len>`.
*/
void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src);
#ifdef __cplusplus
}
#endif /* defined(__cplusplus) */
#endif /* !defined(SFPARSE_H) */