bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2010-2018 Dovecot authors, see the included COPYING file */
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen#include "lib.h"
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen#include "array.h"
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen#include "mail-search.h"
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen#include "mail-search-register.h"
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenstruct mail_search_register {
4ee00532a265bdfb38539d811fcd12d51210ac35Timo Sirainen ARRAY(struct mail_search_register_arg) args;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen mail_search_register_fallback_t *fallback;
464bb87a4678ef3f37a15d14621e6b4a427b14d2Timo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool args_sorted:1;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen};
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenstruct mail_search_register *mail_search_register_init(void)
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen{
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen struct mail_search_register *reg;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen reg = i_new(struct mail_search_register, 1);
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen i_array_init(&reg->args, 64);
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen return reg;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen}
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenvoid mail_search_register_deinit(struct mail_search_register **_reg)
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen{
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen struct mail_search_register *reg = *_reg;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen *_reg = NULL;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen array_free(&reg->args);
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen i_free(reg);
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen}
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenvoid mail_search_register_add(struct mail_search_register *reg,
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen const struct mail_search_register_arg *arg,
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen unsigned int count)
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen{
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen array_append(&reg->args, arg, count);
464bb87a4678ef3f37a15d14621e6b4a427b14d2Timo Sirainen reg->args_sorted = FALSE;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen}
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenvoid mail_search_register_fallback(struct mail_search_register *reg,
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen mail_search_register_fallback_t *fallback)
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen{
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen reg->fallback = fallback;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen}
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenstatic int
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenmail_search_register_arg_cmp(const struct mail_search_register_arg *arg1,
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen const struct mail_search_register_arg *arg2)
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen{
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen return strcmp(arg1->key, arg2->key);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen}
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenconst struct mail_search_register_arg *
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainenmail_search_register_get(struct mail_search_register *reg,
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen unsigned int *count_r)
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen{
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen if (!reg->args_sorted) {
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen array_sort(&reg->args, mail_search_register_arg_cmp);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen reg->args_sorted = TRUE;
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen }
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen return array_get(&reg->args, count_r);
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen}
4fc52b7b25c3d3f42348903e0154840f8761f306Timo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenconst struct mail_search_register_arg *
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenmail_search_register_find(struct mail_search_register *reg, const char *key)
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen{
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen struct mail_search_register_arg arg;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
464bb87a4678ef3f37a15d14621e6b4a427b14d2Timo Sirainen if (!reg->args_sorted) {
464bb87a4678ef3f37a15d14621e6b4a427b14d2Timo Sirainen array_sort(&reg->args, mail_search_register_arg_cmp);
464bb87a4678ef3f37a15d14621e6b4a427b14d2Timo Sirainen reg->args_sorted = TRUE;
464bb87a4678ef3f37a15d14621e6b4a427b14d2Timo Sirainen }
464bb87a4678ef3f37a15d14621e6b4a427b14d2Timo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen arg.key = key;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen return array_bsearch(&reg->args, &arg, mail_search_register_arg_cmp);
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen}
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainenbool mail_search_register_get_fallback(struct mail_search_register *reg,
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen mail_search_register_fallback_t **fallback_r)
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen{
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen if (reg->fallback == NULL)
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen return FALSE;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen *fallback_r = reg->fallback;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen return TRUE;
20b2d47ed762ca2c009aa37e360af6f223ac71bdTimo Sirainen}