1 /* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lib.h"
4 #include "array.h"
5 #include "mail-search.h"
6 #include "mail-search-register.h"
7 
8 struct mail_search_register {
9 	ARRAY(struct mail_search_register_arg) args;
10 	mail_search_register_fallback_t *fallback;
11 
12 	bool args_sorted:1;
13 };
14 
mail_search_register_init(void)15 struct mail_search_register *mail_search_register_init(void)
16 {
17 	struct mail_search_register *reg;
18 
19 	reg = i_new(struct mail_search_register, 1);
20 	i_array_init(&reg->args, 64);
21 	return reg;
22 }
23 
mail_search_register_deinit(struct mail_search_register ** _reg)24 void mail_search_register_deinit(struct mail_search_register **_reg)
25 {
26 	struct mail_search_register *reg = *_reg;
27 
28 	*_reg = NULL;
29 
30 	array_free(&reg->args);
31 	i_free(reg);
32 }
33 
mail_search_register_add(struct mail_search_register * reg,const struct mail_search_register_arg * arg,unsigned int count)34 void mail_search_register_add(struct mail_search_register *reg,
35 			      const struct mail_search_register_arg *arg,
36 			      unsigned int count)
37 {
38 	array_append(&reg->args, arg, count);
39 	reg->args_sorted = FALSE;
40 }
41 
mail_search_register_fallback(struct mail_search_register * reg,mail_search_register_fallback_t * fallback)42 void mail_search_register_fallback(struct mail_search_register *reg,
43 				   mail_search_register_fallback_t *fallback)
44 {
45 	reg->fallback = fallback;
46 }
47 
48 static int
mail_search_register_arg_cmp(const struct mail_search_register_arg * arg1,const struct mail_search_register_arg * arg2)49 mail_search_register_arg_cmp(const struct mail_search_register_arg *arg1,
50 			     const struct mail_search_register_arg *arg2)
51 {
52 	return strcmp(arg1->key, arg2->key);
53 }
54 
55 const struct mail_search_register_arg *
mail_search_register_get(struct mail_search_register * reg,unsigned int * count_r)56 mail_search_register_get(struct mail_search_register *reg,
57 			 unsigned int *count_r)
58 {
59 	if (!reg->args_sorted) {
60 		array_sort(&reg->args, mail_search_register_arg_cmp);
61 		reg->args_sorted = TRUE;
62 	}
63 
64 	return array_get(&reg->args, count_r);
65 }
66 
67 const struct mail_search_register_arg *
mail_search_register_find(struct mail_search_register * reg,const char * key)68 mail_search_register_find(struct mail_search_register *reg, const char *key)
69 {
70 	struct mail_search_register_arg arg;
71 
72 	if (!reg->args_sorted) {
73 		array_sort(&reg->args, mail_search_register_arg_cmp);
74 		reg->args_sorted = TRUE;
75 	}
76 
77 	arg.key = key;
78 	return array_bsearch(&reg->args, &arg, mail_search_register_arg_cmp);
79 }
80 
mail_search_register_get_fallback(struct mail_search_register * reg,mail_search_register_fallback_t ** fallback_r)81 bool mail_search_register_get_fallback(struct mail_search_register *reg,
82 				       mail_search_register_fallback_t **fallback_r)
83 {
84 	if (reg->fallback == NULL)
85 		return FALSE;
86 
87 	*fallback_r = reg->fallback;
88 	return TRUE;
89 }
90