sfparse.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. /*
  2. * sfparse
  3. *
  4. * Copyright (c) 2023 sfparse contributors
  5. * Copyright (c) 2019 nghttp3 contributors
  6. * Copyright (c) 2015 nghttp2 contributors
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining
  9. * a copy of this software and associated documentation files (the
  10. * "Software"), to deal in the Software without restriction, including
  11. * without limitation the rights to use, copy, modify, merge, publish,
  12. * distribute, sublicense, and/or sell copies of the Software, and to
  13. * permit persons to whom the Software is furnished to do so, subject to
  14. * the following conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be
  17. * included in all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  21. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  23. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  24. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  25. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  26. */
  27. #ifndef SFPARSE_H
  28. #define SFPARSE_H
  29. /* Define WIN32 when build target is Win32 API (borrowed from
  30. libcurl) */
  31. #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
  32. # define WIN32
  33. #endif /* (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32) */
  34. #ifdef __cplusplus
  35. extern "C" {
  36. #endif /* defined(__cplusplus) */
  37. #if defined(_MSC_VER) && (_MSC_VER < 1800)
  38. /* MSVC < 2013 does not have inttypes.h because it is not C99
  39. compliant. See compiler macros and version number in
  40. https://sourceforge.net/p/predef/wiki/Compilers/ */
  41. # include <stdint.h>
  42. #else /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
  43. # include <inttypes.h>
  44. #endif /* !(defined(_MSC_VER) && (_MSC_VER < 1800)) */
  45. #include <sys/types.h>
  46. #include <stddef.h>
  47. /**
  48. * @enum
  49. *
  50. * :type:`sfparse_type` defines value type.
  51. */
  52. typedef enum sfparse_type {
  53. /**
  54. * :enum:`SFPARSE_TYPE_BOOLEAN` indicates boolean type.
  55. */
  56. SFPARSE_TYPE_BOOLEAN,
  57. /**
  58. * :enum:`SFPARSE_TYPE_INTEGER` indicates integer type.
  59. */
  60. SFPARSE_TYPE_INTEGER,
  61. /**
  62. * :enum:`SFPARSE_TYPE_DECIMAL` indicates decimal type.
  63. */
  64. SFPARSE_TYPE_DECIMAL,
  65. /**
  66. * :enum:`SFPARSE_TYPE_STRING` indicates string type.
  67. */
  68. SFPARSE_TYPE_STRING,
  69. /**
  70. * :enum:`SFPARSE_TYPE_TOKEN` indicates token type.
  71. */
  72. SFPARSE_TYPE_TOKEN,
  73. /**
  74. * :enum:`SFPARSE_TYPE_BYTESEQ` indicates byte sequence type.
  75. */
  76. SFPARSE_TYPE_BYTESEQ,
  77. /**
  78. * :enum:`SFPARSE_TYPE_INNER_LIST` indicates inner list type.
  79. */
  80. SFPARSE_TYPE_INNER_LIST,
  81. /**
  82. * :enum:`SFPARSE_TYPE_DATE` indicates date type.
  83. */
  84. SFPARSE_TYPE_DATE,
  85. /**
  86. * :enum:`SFPARSE_TYPE_DISPSTRING` indicates display string type.
  87. */
  88. SFPARSE_TYPE_DISPSTRING
  89. } sfparse_type;
  90. /**
  91. * @macro
  92. *
  93. * :macro:`SFPARSE_ERR_PARSE` indicates fatal parse error has
  94. * occurred, and it is not possible to continue the processing.
  95. */
  96. #define SFPARSE_ERR_PARSE -1
  97. /**
  98. * @macro
  99. *
  100. * :macro:`SFPARSE_ERR_EOF` indicates that there is nothing left to
  101. * read. The context of this error varies depending on the function
  102. * that returns this error code.
  103. */
  104. #define SFPARSE_ERR_EOF -2
  105. /**
  106. * @struct
  107. *
  108. * :type:`sfparse_vec` stores sequence of bytes.
  109. */
  110. typedef struct sfparse_vec {
  111. /**
  112. * :member:`base` points to the beginning of the sequence of bytes.
  113. */
  114. uint8_t *base;
  115. /**
  116. * :member:`len` is the number of bytes contained in this sequence.
  117. */
  118. size_t len;
  119. } sfparse_vec;
  120. /**
  121. * @macro
  122. *
  123. * :macro:`SFPARSE_VALUE_FLAG_NONE` indicates no flag set.
  124. */
  125. #define SFPARSE_VALUE_FLAG_NONE 0x0u
  126. /**
  127. * @macro
  128. *
  129. * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` indicates that a string
  130. * contains escaped character(s).
  131. */
  132. #define SFPARSE_VALUE_FLAG_ESCAPED_STRING 0x1u
  133. /**
  134. * @struct
  135. *
  136. * :type:`sfparse_decimal` contains decimal value.
  137. */
  138. typedef struct sfparse_decimal {
  139. /**
  140. * :member:`numer` contains numerator of the decimal value.
  141. */
  142. int64_t numer;
  143. /**
  144. * :member:`denom` contains denominator of the decimal value.
  145. */
  146. int64_t denom;
  147. } sfparse_decimal;
  148. /**
  149. * @struct
  150. *
  151. * :type:`sfparse_value` stores a Structured Field item. For Inner
  152. * List, only type is set to
  153. * :enum:`sfparse_type.SFPARSE_TYPE_INNER_LIST`. In order to read the
  154. * items contained in an inner list, call `sfparse_parser_inner_list`.
  155. */
  156. typedef struct sfparse_value {
  157. /**
  158. * :member:`type` is the type of the value contained in this
  159. * particular object.
  160. */
  161. sfparse_type type;
  162. /**
  163. * :member:`flags` is bitwise OR of one or more of
  164. * :macro:`SFPARSE_VALUE_FLAG_* <SFPARSE_VALUE_FLAG_NONE>`.
  165. */
  166. uint32_t flags;
  167. /**
  168. * @anonunion_start
  169. *
  170. * @sfparse_value_value
  171. */
  172. union {
  173. /**
  174. * :member:`boolean` contains boolean value if :member:`type` ==
  175. * :enum:`sfparse_type.SFPARSE_TYPE_BOOLEAN`. 1 indicates true,
  176. * and 0 indicates false.
  177. */
  178. int boolean;
  179. /**
  180. * :member:`integer` contains integer value if :member:`type` is
  181. * either :enum:`sfparse_type.SFPARSE_TYPE_INTEGER` or
  182. * :enum:`sfparse_type.SFPARSE_TYPE_DATE`.
  183. */
  184. int64_t integer;
  185. /**
  186. * :member:`decimal` contains decimal value if :member:`type` ==
  187. * :enum:`sfparse_type.SFPARSE_TYPE_DECIMAL`.
  188. */
  189. sfparse_decimal decimal;
  190. /**
  191. * :member:`vec` contains sequence of bytes if :member:`type` is
  192. * either :enum:`sfparse_type.SFPARSE_TYPE_STRING`,
  193. * :enum:`sfparse_type.SFPARSE_TYPE_TOKEN`,
  194. * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, or
  195. * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`.
  196. *
  197. * For :enum:`sfparse_type.SFPARSE_TYPE_STRING`, this field
  198. * contains one or more escaped characters if :member:`flags` has
  199. * :macro:`SFPARSE_VALUE_FLAG_ESCAPED_STRING` set. To unescape
  200. * the string, use `sfparse_unescape`.
  201. *
  202. * For :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ`, this field
  203. * contains base64 encoded string. To decode this byte string,
  204. * use `sfparse_base64decode`.
  205. *
  206. * For :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING`, this field
  207. * may contain percent-encoded UTF-8 byte sequences. To decode
  208. * it, use `sfparse_pctdecode`.
  209. *
  210. * If :member:`vec.len <sfparse_vec.len>` == 0, :member:`vec.base
  211. * <sfparse_vec.base>` is guaranteed to be NULL.
  212. */
  213. sfparse_vec vec;
  214. /**
  215. * @anonunion_end
  216. */
  217. };
  218. } sfparse_value;
  219. /**
  220. * @struct
  221. *
  222. * :type:`sfparse_parser` is the Structured Field Values parser. Use
  223. * `sfparse_parser_init` to initialize it.
  224. */
  225. typedef struct sfparse_parser {
  226. /* all fields are private */
  227. const uint8_t *pos;
  228. const uint8_t *end;
  229. uint32_t state;
  230. } sfparse_parser;
  231. /**
  232. * @function
  233. *
  234. * `sfparse_parser_init` initializes |sfp| with the given data encoded
  235. * in Structured Field Values pointed by |data| of length |datalen|.
  236. */
  237. void sfparse_parser_init(sfparse_parser *sfp, const uint8_t *data,
  238. size_t datalen);
  239. /**
  240. * @function
  241. *
  242. * `sfparse_parser_param` reads a parameter. If this function returns
  243. * 0, it stores parameter key and value in |dest_key| and |dest_value|
  244. * respectively, if they are not NULL.
  245. *
  246. * This function does no effort to find duplicated keys. Same key may
  247. * be reported more than once.
  248. *
  249. * Caller should keep calling this function until it returns negative
  250. * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all parameters
  251. * have read, and caller can continue to read rest of the values. If
  252. * it returns :macro:`SFPARSE_ERR_PARSE`, it encountered fatal error
  253. * while parsing field value.
  254. */
  255. int sfparse_parser_param(sfparse_parser *sfp, sfparse_vec *dest_key,
  256. sfparse_value *dest_value);
  257. /**
  258. * @function
  259. *
  260. * `sfparse_parser_dict` reads the next dictionary key and value pair.
  261. * If this function returns 0, it stores the key and value in
  262. * |dest_key| and |dest_value| respectively, if they are not NULL.
  263. *
  264. * Caller can optionally read parameters attached to the pair by
  265. * calling `sfparse_parser_param`.
  266. *
  267. * This function does no effort to find duplicated keys. Same key may
  268. * be reported more than once.
  269. *
  270. * Caller should keep calling this function until it returns negative
  271. * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all key and
  272. * value pairs have been read, and there is nothing left to read.
  273. *
  274. * This function returns 0 if it succeeds, or one of the following
  275. * negative error codes:
  276. *
  277. * :macro:`SFPARSE_ERR_EOF`
  278. * All values in the dictionary have read.
  279. * :macro:`SFPARSE_ERR_PARSE`
  280. * It encountered fatal error while parsing field value.
  281. */
  282. int sfparse_parser_dict(sfparse_parser *sfp, sfparse_vec *dest_key,
  283. sfparse_value *dest_value);
  284. /**
  285. * @function
  286. *
  287. * `sfparse_parser_list` reads the next list item. If this function
  288. * returns 0, it stores the item in |dest| if it is not NULL.
  289. *
  290. * Caller can optionally read parameters attached to the item by
  291. * calling `sfparse_parser_param`.
  292. *
  293. * Caller should keep calling this function until it returns negative
  294. * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in
  295. * the list have been read, and there is nothing left to read.
  296. *
  297. * This function returns 0 if it succeeds, or one of the following
  298. * negative error codes:
  299. *
  300. * :macro:`SFPARSE_ERR_EOF`
  301. * All values in the list have read.
  302. * :macro:`SFPARSE_ERR_PARSE`
  303. * It encountered fatal error while parsing field value.
  304. */
  305. int sfparse_parser_list(sfparse_parser *sfp, sfparse_value *dest);
  306. /**
  307. * @function
  308. *
  309. * `sfparse_parser_item` reads a single item. If this function
  310. * returns 0, it stores the item in |dest| if it is not NULL.
  311. *
  312. * This function is only used for the field value that consists of a
  313. * single item.
  314. *
  315. * Caller can optionally read parameters attached to the item by
  316. * calling `sfparse_parser_param`.
  317. *
  318. * Caller should call this function again to make sure that there is
  319. * nothing left to read. If this 2nd function call returns
  320. * :macro:`SFPARSE_ERR_EOF`, all data have been processed
  321. * successfully.
  322. *
  323. * This function returns 0 if it succeeds, or one of the following
  324. * negative error codes:
  325. *
  326. * :macro:`SFPARSE_ERR_EOF`
  327. * There is nothing left to read.
  328. * :macro:`SFPARSE_ERR_PARSE`
  329. * It encountered fatal error while parsing field value.
  330. */
  331. int sfparse_parser_item(sfparse_parser *sfp, sfparse_value *dest);
  332. /**
  333. * @function
  334. *
  335. * `sfparse_parser_inner_list` reads the next inner list item. If
  336. * this function returns 0, it stores the item in |dest| if it is not
  337. * NULL.
  338. *
  339. * Caller can optionally read parameters attached to the item by
  340. * calling `sfparse_parser_param`.
  341. *
  342. * Caller should keep calling this function until it returns negative
  343. * error code. If it returns :macro:`SFPARSE_ERR_EOF`, all values in
  344. * this inner list have been read, and caller can optionally read
  345. * parameters attached to this inner list by calling
  346. * `sfparse_parser_param`. Then caller can continue to read rest of
  347. * the values.
  348. *
  349. * This function returns 0 if it succeeds, or one of the following
  350. * negative error codes:
  351. *
  352. * :macro:`SFPARSE_ERR_EOF`
  353. * All values in the inner list have read.
  354. * :macro:`SFPARSE_ERR_PARSE`
  355. * It encountered fatal error while parsing field value.
  356. */
  357. int sfparse_parser_inner_list(sfparse_parser *sfp, sfparse_value *dest);
  358. /**
  359. * @function
  360. *
  361. * `sfparse_unescape` copies |src| to |dest| by removing escapes
  362. * (``\``). |src| should be the pointer to
  363. * :member:`sfparse_value.vec` of type
  364. * :enum:`sfparse_type.SFPARSE_TYPE_STRING` produced by either
  365. * `sfparse_parser_dict`, `sfparse_parser_list`,
  366. * `sfparse_parser_inner_list`, `sfparse_parser_item`, or
  367. * `sfparse_parser_param`, otherwise the behavior is undefined.
  368. *
  369. * :member:`dest->base <sfparse_vec.base>` must point to the buffer
  370. * that has sufficient space to store the unescaped string. The
  371. * memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
  372. * :member:`src->base <sfparse_vec.base>` must not overlap.
  373. *
  374. * This function sets the length of unescaped string to
  375. * :member:`dest->len <sfparse_vec.len>`.
  376. */
  377. void sfparse_unescape(sfparse_vec *dest, const sfparse_vec *src);
  378. /**
  379. * @function
  380. *
  381. * `sfparse_base64decode` decodes Base64 encoded string |src| and
  382. * writes the result into |dest|. |src| should be the pointer to
  383. * :member:`sfparse_value.vec` of type
  384. * :enum:`sfparse_type.SFPARSE_TYPE_BYTESEQ` produced by either
  385. * `sfparse_parser_dict`, `sfparse_parser_list`,
  386. * `sfparse_parser_inner_list`, `sfparse_parser_item`, or
  387. * `sfparse_parser_param`, otherwise the behavior is undefined.
  388. *
  389. * :member:`dest->base <sfparse_vec.base>` must point to the buffer
  390. * that has sufficient space to store the decoded byte string.
  391. *
  392. * This function sets the length of decoded byte string to
  393. * :member:`dest->len <sfparse_vec.len>`.
  394. */
  395. void sfparse_base64decode(sfparse_vec *dest, const sfparse_vec *src);
  396. /**
  397. * @function
  398. *
  399. * `sfparse_pctdecode` decodes percent-encoded string |src| and writes
  400. * the result into |dest|. |src| should be the pointer to
  401. * :member:`sfparse_value.vec` of type
  402. * :enum:`sfparse_type.SFPARSE_TYPE_DISPSTRING` produced by either
  403. * `sfparse_parser_dict`, `sfparse_parser_list`,
  404. * `sfparse_parser_inner_list`, `sfparse_parser_item`, or
  405. * `sfparse_parser_param`, otherwise the behavior is undefined.
  406. *
  407. * :member:`dest->base <sfparse_vec.base>` must point to the buffer
  408. * that has sufficient space to store the decoded byte string. The
  409. * memory areas pointed by :member:`dest->base <sfparse_vec.base>` and
  410. * :member:`src->base <sfparse_vec.base>` must not overlap.
  411. *
  412. * This function sets the length of decoded byte string to
  413. * :member:`dest->len <sfparse_vec.len>`.
  414. */
  415. void sfparse_pctdecode(sfparse_vec *dest, const sfparse_vec *src);
  416. #ifdef __cplusplus
  417. }
  418. #endif /* defined(__cplusplus) */
  419. #endif /* !defined(SFPARSE_H) */