Mercurial > dovecot > core-2.2
changeset 18553:3ae8ae7f1022
lib-fts: normalizer-icu now delays initialization of libicu.
This way the normalizer can be quickly created even if it's never even used.
author | Teemu Huovila <teemu.huovila@dovecot.fi> |
---|---|
date | Sat, 09 May 2015 11:09:37 +0300 |
parents | 95a827d97e5b |
children | 8c33d375c73e |
files | src/lib-fts/fts-filter-normalizer-icu.c src/lib-fts/test-fts-filter.c |
diffstat | 2 files changed, 29 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/lib-fts/fts-filter-normalizer-icu.c Sat May 09 11:06:45 2015 +0300 +++ b/src/lib-fts/fts-filter-normalizer-icu.c Sat May 09 11:09:37 2015 +0300 @@ -18,6 +18,7 @@ struct fts_filter filter; const char *error; pool_t pool; + const char *transliterator_id; UTransliterator *transliterator; }; @@ -170,15 +171,9 @@ { struct fts_filter_normalizer *np; pool_t pp; - UErrorCode err = U_ZERO_ERROR; - UParseError perr; - UChar *id_uchar = NULL; - int32_t id_len_uchar = 0; unsigned int i; const char *id = "Any-Lower; NFKD; [: Nonspacing Mark :] Remove; NFC"; - memset(&perr, 0, sizeof(perr)); - for (i = 0; settings[i] != NULL; i += 2) { const char *key = settings[i], *value = settings[i+1]; @@ -195,22 +190,36 @@ np = p_new(pp, struct fts_filter_normalizer, 1); np->pool = pp; np->filter = *fts_filter_normalizer_icu; - if (make_uchar(id, &id_uchar, &id_len_uchar) < 0) { + np->transliterator_id = p_strdup(pp, id); + *filter_r = &np->filter; + return 0; +} +static int fts_filter_normalizer_icu_create_trans(struct fts_filter_normalizer *np) +{ + UErrorCode err = U_ZERO_ERROR; + UParseError perr; + UChar *id_uchar = NULL; + int32_t id_len_uchar = 0; + + memset(&perr, 0, sizeof(perr)); + + if (make_uchar(np->transliterator_id, &id_uchar, &id_len_uchar) < 0) { + return -1; } np->transliterator = utrans_openU(id_uchar, u_strlen(id_uchar), UTRANS_FORWARD, NULL, 0, &perr, &err); if (U_FAILURE(err)) { if (perr.line >= 1) { - fts_filter_normalizer_icu_error(error_r, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.", id, u_errorName(err), perr.line, perr.offset); + fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s. Parse error on line %u offset %u.", + np->transliterator_id, u_errorName(err), perr.line, perr.offset); } else { - fts_filter_normalizer_icu_error(error_r, "Failed to open transliterator for id: %s. Lib ICU error: %s.", id, u_errorName(err)); + fts_filter_normalizer_icu_error(&np->error, "Failed to open transliterator for id: %s. Lib ICU error: %s.", + np->transliterator_id, u_errorName(err)); } - fts_filter_normalizer_icu_destroy(&np->filter); return -1; } - *filter_r = &np->filter; return 0; } @@ -229,14 +238,15 @@ if (np->error != NULL) goto err_exit; + if (np->transliterator == NULL) + if (fts_filter_normalizer_icu_create_trans(np) < 0) + goto err_exit; + if (make_uchar(*token, &utext, &utext_cap) < 0) { fts_filter_normalizer_icu_error(&np->error, "Conversion to UChar failed"); goto err_exit; } - /* - TODO: Some problems here. How much longer can the result - be, than the source? Can it be calculated? Preflighted? - */ + utext_limit = u_strlen(utext); utrans_transUChars(np->transliterator, utext, &utext_len, utext_cap, 0, &utext_limit, &err);
--- a/src/lib-fts/test-fts-filter.c Sat May 09 11:06:45 2015 +0300 +++ b/src/lib-fts/test-fts-filter.c Sat May 09 11:09:37 2015 +0300 @@ -459,14 +459,15 @@ const char *settings[] = {"id", "Any-One-Out-There; DKFN; [: Nonspacing Mark :] Remove", NULL}; - const char *error = NULL; + const char *error = NULL, *token = "foo"; int ret; test_begin("fts filter normalizer invalid id"); filter_class = fts_filter_find(ICU_NORMALIZER_FILTER_NAME); ret = fts_filter_create(filter_class, NULL, NULL, settings, &norm, &error); - test_assert(ret < 0 && error != NULL); - test_assert(norm == NULL); + test_assert(ret == 0 && error == NULL); + ret = fts_filter_filter(norm, &token); + test_assert(ret < 0); test_end(); }