summaryrefslogtreecommitdiffstats
path: root/pigeonhole/src/lib-sieve/sieve-comparators.h
blob: fdfb9ee61fb6d272874a83db97e2c8edba63dfb6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#ifndef SIEVE_COMPARATORS_H
#define SIEVE_COMPARATORS_H

#include "sieve-common.h"
#include "sieve-extensions.h"
#include "sieve-commands.h"
#include "sieve-objects.h"
#include "sieve-code.h"

/*
 * Core comparators
 */

enum sieve_comparator_code {
	SIEVE_COMPARATOR_I_OCTET,
	SIEVE_COMPARATOR_I_ASCII_CASEMAP,
	SIEVE_COMPARATOR_CUSTOM
};

extern const struct sieve_comparator_def i_octet_comparator;
extern const struct sieve_comparator_def i_ascii_casemap_comparator;

/*
 * Comparator flags
 */

enum sieve_comparator_flags {
	SIEVE_COMPARATOR_FLAG_ORDERING = (1 << 0),
	SIEVE_COMPARATOR_FLAG_EQUALITY = (1 << 1),
	SIEVE_COMPARATOR_FLAG_PREFIX_MATCH = (1 << 2),
	SIEVE_COMPARATOR_FLAG_SUBSTRING_MATCH = (1 << 3),
};

/*
 * Comparator definition
 */

struct sieve_comparator_def {
	struct sieve_object_def obj_def;

	unsigned int flags;

	/* Equality and ordering */

	int (*compare)(const struct sieve_comparator *cmp,
		const char *val1, size_t val1_size,
		const char *val2, size_t val2_size);

	/* Prefix and substring match */

	bool (*char_match)(const struct sieve_comparator *cmp,
		const char **val, const char *val_end,
		const char **key, const char *key_end);
	bool (*char_skip)(const struct sieve_comparator *cmp,
		const char **val, const char *val_end);
};

/*
 * Comparator instance
 */

struct sieve_comparator {
	struct sieve_object object;

	const struct sieve_comparator_def *def;
};

#define SIEVE_COMPARATOR_DEFAULT(definition) \
	{ SIEVE_OBJECT_DEFAULT(definition), &(definition) }

#define sieve_comparator_name(cmp) \
	( (cmp)->object.def->identifier )
#define sieve_comparator_is(cmp, definition) \
	( (cmp)->def == &(definition) )

static inline const struct sieve_comparator *sieve_comparator_copy
(pool_t pool, const struct sieve_comparator *cmp_orig)
{
	struct sieve_comparator *cmp = p_new(pool, struct sieve_comparator, 1);

	*cmp = *cmp_orig;

	return cmp;
}

/*
 * Comparator tagged argument
 */

extern const struct sieve_argument_def comparator_tag;

static inline bool sieve_argument_is_comparator
(struct sieve_ast_argument *arg)
{
	return ( arg->argument != NULL &&
		(arg->argument->def == &comparator_tag) );
}

void sieve_comparators_link_tag
	(struct sieve_validator *validator,
		struct sieve_command_registration *cmd_reg,	int id_code);
bool sieve_comparator_tag_is
	(struct sieve_ast_argument *tag, const struct sieve_comparator_def *cmp);
const struct sieve_comparator *sieve_comparator_tag_get
	(struct sieve_ast_argument *tag);

void sieve_comparator_register
	(struct sieve_validator *validator, const struct sieve_extension *ext,
		const struct sieve_comparator_def *cmp);

/*
 * Comparator operand
 */

#define SIEVE_EXT_DEFINE_COMPARATOR(OP) SIEVE_EXT_DEFINE_OBJECT(OP)
#define SIEVE_EXT_DEFINE_COMPARATORS(OPS) SIEVE_EXT_DEFINE_OBJECTS(OPS)

extern const struct sieve_operand_class sieve_comparator_operand_class;
extern const struct sieve_operand_def comparator_operand;

static inline void sieve_opr_comparator_emit
(struct sieve_binary_block *sblock, const struct sieve_comparator *cmp)
{
	sieve_opr_object_emit(sblock, cmp->object.ext, cmp->object.def);
}
static inline bool sieve_opr_comparator_dump
(const struct sieve_dumptime_env *denv, sieve_size_t *address)
{
	return sieve_opr_object_dump
		(denv, &sieve_comparator_operand_class, address, NULL);
}

static inline int sieve_opr_comparator_read
(const struct sieve_runtime_env *renv, sieve_size_t *address,
	struct sieve_comparator *cmp)
{
	if ( !sieve_opr_object_read
		(renv, &sieve_comparator_operand_class, address, &cmp->object) )
		return SIEVE_EXEC_BIN_CORRUPT;

	cmp->def = (const struct sieve_comparator_def *) cmp->object.def;
	return SIEVE_EXEC_OK;
}

/*
 * Trivial/Common comparator method implementations
 */

bool sieve_comparator_octet_skip
	(const struct sieve_comparator *cmp ATTR_UNUSED,
		const char **val, const char *val_end);

#endif