c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#ifndef IMAP_ARG_H
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#define IMAP_ARG_H
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#include "array.h"
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen/* ABNF:
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen CHAR = %x01-7F
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen CTL = %x00-1F / %x7F
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen SP = %x20
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen DQUOTE = %x22 */
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen/* ASTRING-CHAR = ATOM-CHAR / resp-specials */
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen#define IS_ASTRING_CHAR(c) (IS_ATOM_CHAR(c) || IS_RESP_SPECIAL(c))
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen/* ATOM-CHAR = <any CHAR except atom-specials> */
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen#define IS_ATOM_CHAR(c) (!IS_ATOM_SPECIAL(c))
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen/* atom-specials = "(" / ")" / "{" / SP / CTL / list-wildcards /
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen quoted-specials / resp-specials
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen Since atoms are only 7bit, we'll also optimize a bit by assuming 8bit chars
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen are also atom-specials. */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#define IS_ATOM_SPECIAL(c) \
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen ((unsigned char)(c) <= 0x20 || (unsigned char)(c) >= 0x7f || \
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen (c) == '(' || (c) == ')' || (c) == '{' || IS_LIST_WILDCARD(c) || \
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen IS_QUOTED_SPECIAL(c) || IS_RESP_SPECIAL(c))
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen/* list-wildcards = "%" / "*" */
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen#define IS_LIST_WILDCARD(c) ((c) == '%' || (c) == '*')
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen/* quoted-specials = DQUOTE / "\" */
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen#define IS_QUOTED_SPECIAL(c) ((c) == '\"' || (c) == '\\')
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen/* resp-specials = "]" */
73592a4e11ebdc306a9fd030bff879318c84270aTimo Sirainen#define IS_RESP_SPECIAL(c) ((c) == ']')
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenenum imap_arg_type {
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_NIL = 0,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_ATOM,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_STRING,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_LIST,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen /* literals are returned as IMAP_ARG_STRING by default */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_LITERAL,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_LITERAL_SIZE,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_LITERAL_SIZE_NONSYNC,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_EOL /* end of argument list */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen};
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo SirainenARRAY_DEFINE_TYPE(imap_arg_list, struct imap_arg);
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenstruct imap_arg {
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen enum imap_arg_type type;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen struct imap_arg *parent; /* always of type IMAP_ARG_LIST */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
f6a8cd6eab1ca716ce480962b36a58f9f7379af3Timo Sirainen /* Set when _data.str is set */
f6a8cd6eab1ca716ce480962b36a58f9f7379af3Timo Sirainen size_t str_len;
f6a8cd6eab1ca716ce480962b36a58f9f7379af3Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen union {
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen const char *str;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen uoff_t literal_size;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ARRAY_TYPE(imap_arg_list) list;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen } _data;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool literal8:1; /* BINARY literal8 used */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen};
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c4699302bd6965ee803ab34613b8840a3d8203d1Timo Sirainen/* RFC 3501's astring type. Note that this doesn't return TRUE for
c4699302bd6965ee803ab34613b8840a3d8203d1Timo Sirainen IMAP_ARG_NIL, although it should be treated the same as "NIL" string when
c4699302bd6965ee803ab34613b8840a3d8203d1Timo Sirainen reading an astring. */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#define IMAP_ARG_TYPE_IS_ASTRING(type) \
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ((type) == IMAP_ARG_ATOM || \
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen (type) == IMAP_ARG_STRING || \
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen (type) == IMAP_ARG_LITERAL)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#define IMAP_ARG_IS_ASTRING(arg) \
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen IMAP_ARG_TYPE_IS_ASTRING((arg)->type)
7f1e41e54ebc22282a7c9a0c561f1743c43fe9b1Timo Sirainen#define IMAP_ARG_IS_NSTRING(arg) \
7f1e41e54ebc22282a7c9a0c561f1743c43fe9b1Timo Sirainen (IMAP_ARG_IS_ASTRING(arg) || (arg)->type == IMAP_ARG_NIL)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#define IMAP_ARG_IS_EOL(arg) \
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ((arg)->type == IMAP_ARG_EOL)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_atom(const struct imap_arg *arg, const char **str_r)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_quoted(const struct imap_arg *arg, const char **str_r)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_string(const struct imap_arg *arg, const char **str_r)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_astring(const struct imap_arg *arg, const char **str_r)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen/* str is set to NULL for NIL. */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_nstring(const struct imap_arg *arg, const char **str_r)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_literal_size(const struct imap_arg *arg, uoff_t *size_r)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_list(const struct imap_arg *arg,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen const struct imap_arg **list_r)
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_get_list_full(const struct imap_arg *arg,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen const struct imap_arg **list_r,
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen unsigned int *list_count_r) ATTR_WARN_UNUSED_RESULT;
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen/* Similar to above, but assumes that arg is already of correct type. */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenconst char *imap_arg_as_astring(const struct imap_arg *arg);
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenconst char *imap_arg_as_nstring(const struct imap_arg *arg);
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenuoff_t imap_arg_as_literal_size(const struct imap_arg *arg);
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenconst struct imap_arg *imap_arg_as_list(const struct imap_arg *arg);
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen/* Returns TRUE if arg is atom and case-insensitively matches str */
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainenbool imap_arg_atom_equals(const struct imap_arg *arg, const char *str);
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen
c2fbbf7515aa419dc8b2d62a3c2bb0471d51a391Timo Sirainen#endif