1 /* Copyright (c) 2015-2018 Dovecot authors, see the included COPYING file */
2 
3 #include "lib.h"
4 #include "str.h"
5 #include "fts-language.h"
6 #include "fts-filter-private.h"
7 
8 #ifdef HAVE_LIBICU
9 #  include "fts-icu.h"
10 #  include "fts-filter-common.h"
11 #endif
12 
13 static int
fts_filter_lowercase_create(const struct fts_language * lang ATTR_UNUSED,const char * const * settings,struct fts_filter ** filter_r,const char ** error_r)14 fts_filter_lowercase_create(const struct fts_language *lang ATTR_UNUSED,
15                             const char *const *settings,
16                             struct fts_filter **filter_r,
17                             const char **error_r)
18 {
19 	struct fts_filter *filter;
20 	unsigned int i, max_length = 250;
21 
22 	for (i = 0; settings[i] != NULL; i += 2) {
23 		const char *key = settings[i], *value = settings[i+1];
24 
25 		if (strcmp(key, "maxlen") == 0) {
26 			if (str_to_uint(value, &max_length) < 0 ||
27 			    max_length == 0) {
28 				*error_r = t_strdup_printf("Invalid lowercase filter maxlen setting: %s", value);
29 				return -1;
30 			}
31 		}
32 		else {
33 			*error_r = t_strdup_printf("Unknown setting: %s", key);
34 			return -1;
35 		}
36 	}
37 	filter = i_new(struct fts_filter, 1);
38 	*filter = *fts_filter_lowercase;
39 	filter->token = str_new(default_pool, 64);
40 	filter->max_length = max_length;
41 
42 	*filter_r = filter;
43 	return 0;
44 }
45 
46 static int
fts_filter_lowercase_filter(struct fts_filter * filter ATTR_UNUSED,const char ** token,const char ** error_r ATTR_UNUSED)47 fts_filter_lowercase_filter(struct fts_filter *filter ATTR_UNUSED,
48                             const char **token,
49                             const char **error_r ATTR_UNUSED)
50 {
51 #ifdef HAVE_LIBICU
52 	str_truncate(filter->token, 0);
53 	fts_icu_lcase(filter->token, *token);
54 	fts_filter_truncate_token(filter->token, filter->max_length);
55 	*token = str_c(filter->token);
56 #else
57 	*token = t_str_lcase(*token);
58 #endif
59 	return 1;
60 }
61 
62 static const struct fts_filter fts_filter_lowercase_real = {
63 	.class_name = "lowercase",
64 	.v = {
65 		fts_filter_lowercase_create,
66 		fts_filter_lowercase_filter,
67 		NULL
68 	}
69 };
70 
71 const struct fts_filter *fts_filter_lowercase = &fts_filter_lowercase_real;
72