From 50aa5cd62ef4a66da41d68f4a50ddfca97863c38 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Wed, 3 Aug 2005 18:24:08 +0000 Subject: Multithreading - Multithreaded access to recoding functions using same context - Engine plugin to select between UTF-8 and ISO8859-1 for Western European Languages - Fix: 'rccTo' converting FS classes - FS class support in 'rccConfigSizedToCharset' --- ToDo | 5 ++ engines/Makefile.am | 5 +- engines/russian.c | 2 +- engines/western.c | 72 +++++++++++++++ examples/rcc.xml | 18 ++++ src/Makefile.am | 1 + src/curconfig.c | 9 ++ src/engine.c | 24 ++--- src/engine.h | 5 +- src/fs.c | 35 +++++++- src/fs.h | 1 + src/internal.h | 4 +- src/librcc.c | 33 +++---- src/librcc.h | 49 ++++++++--- src/lng.c | 2 + src/lngconfig.c | 247 +++++++++++++++++++--------------------------------- src/lngconfig.h | 9 +- src/lngrecode.c | 169 +++++++++++++++++++++++++++++++++++ src/lngrecode.h | 5 ++ src/opt.c | 2 + src/rccenca.c | 6 +- src/rcctranslate.c | 1 - src/recode.c | 195 +++++++++++++++++++++-------------------- 23 files changed, 587 insertions(+), 312 deletions(-) create mode 100644 engines/western.c create mode 100644 src/lngrecode.c create mode 100644 src/lngrecode.h diff --git a/ToDo b/ToDo index 026888d..53ce4c5 100644 --- a/ToDo +++ b/ToDo @@ -6,6 +6,10 @@ translation and language detection. + Implement ispell support + Configurable timeouts + - Move all recoding functionality on rccConfig level + - Revise locking subsystem + - Think about parrent languages ( For example, it is possible to get ukrainian music band + with russian name and ukrainian song titles ) 1.x: - Common encodings: @@ -17,6 +21,7 @@ * Code some options in charset name. (SpecialEncodingPrefix_Encoding_EncodingOptions) - Recoding options: + Skip Translation + - Switch to Get/Ref/UnRef system on request: - Multibyte(not-UTF8) support for FS classes diff --git a/engines/Makefile.am b/engines/Makefile.am index 7226682..404cc32 100644 --- a/engines/Makefile.am +++ b/engines/Makefile.am @@ -1,4 +1,4 @@ -lib_LTLIBRARIES = +lib_LTLIBRARIES = libwestern.la libdir = $(pkgdatadir)/engines @@ -8,4 +8,7 @@ librussian_la_SOURCES = russian.c librussian_la_LDFLAGS = -module -avoid-version -export-symbols-regex "rccGetInfo" endif +libwestern_la_SOURCES = western.c +libwestern_la_LDFLAGS = -module -avoid-version -export-symbols-regex "rccGetInfo" + AM_CPPFLAGS = -I../src @RCD_INCLUDES@ diff --git a/engines/russian.c b/engines/russian.c index 08b8310..0df145c 100644 --- a/engines/russian.c +++ b/engines/russian.c @@ -5,7 +5,7 @@ #include static rcc_autocharset_id AutoengineRussian(rcc_engine_context ctx, const char *buf, int len) { - return (rcc_charset_id)rcdGetRussianCharset(buf,len); + return (rcc_autocharset_id)rcdGetRussianCharset(buf,len); } static rcc_engine russian_engine = { diff --git a/engines/western.c b/engines/western.c new file mode 100644 index 0000000..4c6e1aa --- /dev/null +++ b/engines/western.c @@ -0,0 +1,72 @@ +#include +#include + +#include + +#define bit(i) (1<0) { + if ((buf[i]&0xC0)==0x80) { + if (rflag) { + // Western is 0x100-0x17e + res++; + } + bytes--; + } else { + res--; + bytes=1-bytes; + rflag=0; + } + } else { + for (j=6;j>=0;j--) + if ((buf[i]&bit(j))==0) break; + + if ((j==0)||(j==6)) { + if ((j==6)&&(bytes<0)) bytes++; + else res--; + continue; + } + bytes=6-j; + if (bytes==1) { + // Western Languages (C2-C3) + if (buf[i]==0xC2) rflag=1; + else if (buf[i]==0xC3) rflag=2; + } + } + + if ((buf[i]==0xC0)||(buf[i]==0xC1)) { + if (i+1==len) break; + + } + } + + if (res > 0) return (rcc_autocharset_id)0; + return (rcc_autocharset_id)1; +} + +static rcc_engine western_engine = { + "Western", NULL, NULL, &AutoengineWestern, {"UTF-8","ISO8859-1", NULL} +}; + +rcc_engine *rccGetInfo(const char *lang) { + if (!lang) return NULL; + + return &western_engine; +} diff --git a/examples/rcc.xml b/examples/rcc.xml index 02ee297..50d2ee2 100644 --- a/examples/rcc.xml +++ b/examples/rcc.xml @@ -10,5 +10,23 @@ SHIFT-JIS + + German + + UTF-8 + + + western + + + + French + + UTF-8 + + + western + + \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index 0a1fdc1..6d1ca98 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,6 +21,7 @@ librcc_la_SOURCES = librcc.c \ rcctranslate.c rcctranslate.h \ fs.c fs.h \ recode.c recode.h \ + lngrecode.c lngrecode.h \ internal.h include_HEADERS = librcc.h diff --git a/src/curconfig.c b/src/curconfig.c index 72aa4c1..ac1b722 100644 --- a/src/curconfig.c +++ b/src/curconfig.c @@ -160,3 +160,12 @@ rcc_charset_id rccGetLocaleCharset(rcc_context ctx, const char *locale_variable) } return rccConfigGetLocaleCharset(ctx->current_config, locale_variable); } + +rcc_autocharset_id rccDetectCharset(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len) { + if (!ctx) { + if (rcc_default_ctx) ctx = rcc_default_ctx; + else return -1; + } + + return rccConfigDetectCharset(ctx->current_config, class_id, buf, len); +} diff --git a/src/engine.c b/src/engine.c index d83fbf7..8058faf 100644 --- a/src/engine.c +++ b/src/engine.c @@ -92,10 +92,10 @@ void rccEngineFree() { #endif /* RCC_RCD_DYNAMIC */ } -int rccEngineInitContext(rcc_engine_context engine_ctx, rcc_context ctx) { - if ((!ctx)||(!engine_ctx)) return -1; +int rccEngineInitContext(rcc_engine_context engine_ctx, rcc_language_config config) { + if ((!config)||(!engine_ctx)) return -1; - engine_ctx->ctx = ctx; + engine_ctx->config = config; engine_ctx->free_func = NULL; engine_ctx->func = NULL; return 0; @@ -114,25 +114,19 @@ void rccEngineFreeContext(rcc_engine_context engine_ctx) { } int rccEngineConfigure(rcc_engine_context ctx) { - rcc_language_id language_id; rcc_engine_id engine_id; rcc_engine *engine; - if ((!ctx)||(!ctx->ctx)) return -1; + if ((!ctx)||(!ctx->config)) return -1; rccEngineFreeContext(ctx); - - language_id = rccGetCurrentLanguage(ctx->ctx); - if (language_id == (rcc_language_id)-1) return -1; - - engine_id = rccGetCurrentEngine(ctx->ctx); + engine_id = rccConfigGetCurrentEngine(ctx->config); if (engine_id == (rcc_engine_id)-1) return -1; - - engine = ctx->ctx->languages[language_id]->engines[engine_id]; + + engine = ctx->config->language->engines[engine_id]; ctx->free_func = engine->free_func; ctx->func = engine->func; - ctx->language = ctx->ctx->languages[language_id]; if (engine->init_func) ctx->internal = engine->init_func(ctx); else ctx->internal = NULL; @@ -149,11 +143,11 @@ rcc_engine_internal rccEngineGetInternal(rcc_engine_context ctx) { rcc_language *rccEngineGetLanguage(rcc_engine_context ctx) { if (!ctx) return NULL; - return ctx->language; + return ctx->config->language; } rcc_context rccEngineGetRccContext(rcc_engine_context ctx) { if (!ctx) return NULL; - return ctx->ctx; + return ctx->config->ctx; } diff --git a/src/engine.h b/src/engine.h index 9cae53d..445e962 100644 --- a/src/engine.h +++ b/src/engine.h @@ -21,8 +21,7 @@ #endif struct rcc_engine_context_t { - rcc_context ctx; - rcc_language *language; + rcc_language_config config; rcc_engine_function func; rcc_engine_free_function free_func; @@ -34,7 +33,7 @@ typedef struct rcc_engine_context_t rcc_engine_context_s; int rccEngineInit(); void rccEngineFree(); -int rccEngineInitContext(rcc_engine_context engine_ctx, rcc_context ctx); +int rccEngineInitContext(rcc_engine_context engine_ctx, rcc_language_config config); void rccEngineFreeContext(rcc_engine_context engine_ctx); int rccEngineConfigure(rcc_engine_context ctx); diff --git a/src/fs.c b/src/fs.c index fb0a2bc..f8f6094 100644 --- a/src/fs.c +++ b/src/fs.c @@ -190,7 +190,7 @@ int rccFS1(rcc_language_config config, const char *fspath, char **prefix, char * /* Checks if 'prefix/name' is accessible using 'icnv' recoding. In case of sucess returns pointer on statically allocated memory, and NULL overwise */ -const char *rccFS2(rcc_language_config config, iconv_t icnv, const char *prefix, const char *name) { +char *rccFS2(rcc_language_config config, iconv_t icnv, const char *prefix, const char *name) { size_t size; char *tmpbuffer = config->ctx->tmpbuffer; @@ -207,9 +207,9 @@ const char *rccFS2(rcc_language_config config, iconv_t icnv, const char *prefix, /* Tries to find 'name' encoding in 'prefix/name' file. Returns pointer on statically allocated string with correct filename or NULL. */ -const char *rccFS3(rcc_language_config config, rcc_class_id class_id, const char *prefix, const char *name) { +char *rccFS3(rcc_language_config config, rcc_class_id class_id, const char *prefix, const char *name) { unsigned int i; - const char *result; + char *result; rcc_charset charset; rcc_language *language; iconv_t icnv = config->fsiconv; @@ -251,3 +251,32 @@ const char *rccFS3(rcc_language_config config, rcc_class_id class_id, const char return result; } + +char *rccFS5(rcc_context ctx, rcc_language_config config, rcc_class_id class_id, const char *utfstring) { + int err; + char *prefix, *name; + char *result; + + if (rccIsASCII(utfstring)) return strdup(utfstring); + + name = NULL; + prefix = NULL; + + rccMutexLock(ctx->mutex); + rccMutexLock(config->mutex); + err = rccFS0(config, NULL, utfstring, &prefix, &name); + if (err>=0) { + result = rccFS3(config, class_id, prefix, name); + rccMutexUnLock(config->mutex); + rccMutexUnLock(ctx->mutex); + if (!err) { + if (prefix) free(prefix); + free(name); + } + return result; + } + rccMutexUnLock(config->mutex); + rccMutexUnLock(ctx->mutex); + + return NULL; +} diff --git a/src/fs.h b/src/fs.h index 74ceb25..cc5f4cf 100644 --- a/src/fs.h +++ b/src/fs.h @@ -5,5 +5,6 @@ int rccFS0(rcc_language_config config, const char *fspath, const char *filename, int rccFS1(rcc_language_config config, const char *fspath, char **prefix, char **name); char *rccFS2(rcc_language_config config, iconv_t icnv, const char *prefix, const char *name); char *rccFS3(rcc_language_config config, rcc_class_id class_id, const char *prefix, const char *name); +char *rccFS5(rcc_context ctx, rcc_language_config config, rcc_class_id class_id, const char *utfstring); #endif /* _RCC_FS_H */ diff --git a/src/internal.h b/src/internal.h index 3a07a67..fcaa4c6 100644 --- a/src/internal.h +++ b/src/internal.h @@ -13,6 +13,7 @@ #include "rccdb4.h" #include "rcciconv.h" #include "rccstring.h" +#include "rccmutex.h" #ifdef HAVE_STRNLEN #define STRNLEN(str,n) (n?strnlen(str,n):strlen(str)) @@ -42,8 +43,6 @@ struct rcc_context_t { unsigned int n_classes; rcc_class_ptr *classes; - rcc_engine_context_s engine_ctx; - rcc_iconv *iconv_from; rcc_iconv iconv_auto[RCC_MAX_CHARSETS]; @@ -60,6 +59,7 @@ struct rcc_context_t { db4_context db4ctx; + rcc_mutex mutex; unsigned int configuration_lock; }; typedef struct rcc_context_t rcc_context_s; diff --git a/src/librcc.c b/src/librcc.c index c0112df..757b71b 100644 --- a/src/librcc.c +++ b/src/librcc.c @@ -121,7 +121,6 @@ void rccFree() { } rcc_context rccCreateContext(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags) { - int err; unsigned int i; rcc_context ctx; @@ -129,6 +128,7 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu rcc_class_ptr *classes; rcc_language_config configs; rcc_iconv *from; + rcc_mutex mutex; if (!initialized) return NULL; @@ -151,10 +151,12 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu languages = (rcc_language_ptr*)malloc((max_languages+1)*sizeof(rcc_language_ptr)); classes = (rcc_class_ptr*)malloc((max_classes+1)*sizeof(rcc_class_ptr)); from = (rcc_iconv*)malloc((max_classes)*sizeof(rcc_iconv)); + mutex = rccMutexCreate(); configs = (rcc_language_config)malloc((max_languages)*sizeof(struct rcc_language_config_t)); - if ((!ctx)||(!languages)||(!classes)) { + if ((!ctx)||(!languages)||(!classes)||(!mutex)) { + if (mutex) rccMutexFree(mutex); if (from) free(from); if (configs) free(configs); if (classes) free(classes); @@ -165,6 +167,8 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu ctx->configuration_lock = 0; + ctx->mutex = mutex; + ctx->db4ctx = NULL; ctx->aliases[0] = NULL; @@ -191,12 +195,6 @@ rcc_context rccCreateContext(const char *locale_variable, unsigned int max_langu for (i=0;iengine_ctx, ctx); - if (err) { - rccFree(ctx); - return NULL; - } - ctx->current_language = 0; ctx->default_language = 0; @@ -275,7 +273,6 @@ void rccFreeContext(rcc_context ctx) { if (ctx) { if (ctx->db4ctx) rccDb4FreeContext(ctx->db4ctx); - rccEngineFreeContext(&ctx->engine_ctx); rccFreeIConv(ctx); if (ctx->iconv_from) free(ctx->iconv_from); @@ -286,6 +283,7 @@ void rccFreeContext(rcc_context ctx) { } if (ctx->classes) free(ctx->classes); if (ctx->languages) free(ctx->languages); + if (ctx->mutex) rccMutexFree(ctx->mutex); free(ctx); } } @@ -428,7 +426,6 @@ rcc_class_type rccGetClassType(rcc_context ctx, rcc_class_id class_id) { int rccConfigure(rcc_context ctx) { - int err; unsigned int i; rcc_charset *charsets; const char *charset; @@ -437,9 +434,14 @@ int rccConfigure(rcc_context ctx) { if (!ctx) return -1; if (!ctx->configure) return 0; - cfg = rccGetCurrentConfig(ctx); - if (!cfg) return 1; + + cfg = rccGetCurrentConfig(ctx); + if (!cfg) return -1; + + rccMutexLock(ctx->mutex); + rccMutexLock(cfg->mutex); + rccFreeIConv(ctx); for (i=0;in_classes;i++) { charset = rccConfigGetCurrentCharsetName(cfg, (rcc_class_id)i); @@ -456,10 +458,11 @@ int rccConfigure(rcc_context ctx) { } } - err = rccEngineConfigure(&ctx->engine_ctx); - if (err) return err; - ctx->configure = 0; + + rccMutexUnLock(cfg->mutex); + rccMutexUnLock(ctx->mutex); + return 0; } diff --git a/src/librcc.h b/src/librcc.h index d08937e..cbd9b3d 100644 --- a/src/librcc.h +++ b/src/librcc.h @@ -623,6 +623,25 @@ rcc_language_config rccCheckConfig(rcc_context ctx, rcc_language_id language_id) * dummy (Dissable LibRCC) language is selected. */ rcc_language_config rccGetConfig(rcc_context ctx, rcc_language_id language_id); +/** + * Checks if supplied language is usable. The usability of language is determined + * regarding #RCC_OPTION_CONFIGURED_LANGUAGES_ONLY option. Depending on that + * option there are several possibilities for language usability: + * Any non-dummy language is usable + * Any configured or AutoEngine enabled language is usable + * Only configured languages are usable + * + * Language configuration is initialized if not yet configured. And pointer on + * that configuration is returned. If default language is supplied (language_id = 0), the + * language id will be resolved to particular language and config of that language + * will be returned. + * + * @param ctx is working context ( or default one if NULL supplied ) + * @param language_id is concerned language id + * @return configuration context. The NULL is returned in the case of errors or + * if unusable language is supplied. + */ +rcc_language_config rccGetUsableConfig(rcc_context ctx, rcc_language_id language_id); /** * Initializes language configuration if not yet configured and returns pointer on * that configuration. @@ -641,6 +660,19 @@ rcc_language_config rccGetConfigByName(rcc_context ctx, const char *name); */ rcc_language_config rccGetCurrentConfig(rcc_context ctx); +/** + * Return language associated with supplied configuration. + * + * @param config is language configuration + */ +rcc_language_id rccConfigGetLanguage(rcc_language_config config); +/** + * Return name of the language associated with supplied configuration. + * + * @param config is language configuration + */ +const char *rccConfigGetLanguageName(rcc_language_config config); + /** * Return supplied engine name * @@ -822,6 +854,8 @@ int rccSetCharsetByName(rcc_context ctx, rcc_class_id class_id, const char *name rcc_charset_id rccGetLocaleCharset(rcc_context ctx, const char *locale_variable); +rcc_autocharset_id rccDetectCharset(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len); + /******************************************************************************* ************************ Language Configuaration ******************************* *******************************************************************************/ @@ -998,15 +1032,16 @@ char *rccTranslate(rcc_translate translate, const char *buf); * @result is language_id or -1 if autodetection is failed */ rcc_language_id rccDetectLanguage(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len); + /** * Tries to detect charset of string - * @param ctx is working context ( or default one if NULL supplied ) + * @param config is language configuration * @param class_id is encoding class * @param buf is original string (perhaps not zero terminated) * @param len is exact size of string or 0. In the last case the size is determined using 'strlen' function. * @result is auto_charset_id or -1 if autodetection is failed */ -int rccDetectCharset(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len); +rcc_autocharset_id rccConfigDetectCharset(rcc_language_config config, rcc_class_id class_id, const char *buf, size_t len); /** * Recode string from specified encoding class to #rcc_string. Encoding detection engines and @@ -1132,16 +1167,6 @@ rcc_string rccSizedRecodeFromCharset(rcc_context ctx, rcc_class_id class_id, con char *rccSizedRecodeCharsets(rcc_context ctx, const char *from, const char *to, const char *buf, size_t len, size_t *rlen); -/** - * Tries to detect charset of string - * @param config is language configuration - * @param class_id is encoding class - * @param buf is original string (perhaps not zero terminated) - * @param len is exact size of string or 0. In the last case the size is determined using 'strlen' function. - * @result is auto_charset_id or -1 if autodetection is failed - */ -rcc_autocharset_id rccConfigDetectCharset(rcc_language_config config, rcc_class_id class_id, const char *buf, size_t len); - /** * Recode string from specified encoding class to #rcc_string. Encoding detection engines and * recoding cache are used (if possible) to detect original 'buf' encoding. Otherwise the diff --git a/src/lng.c b/src/lng.c index 4589de6..4b0676d 100644 --- a/src/lng.c +++ b/src/lng.c @@ -157,9 +157,11 @@ int rccSetLanguage(rcc_context ctx, rcc_language_id language_id) { config = rccGetConfig(ctx, language_id); // NULL is Okey (Off), if (!config) return -1; + rccMutexLock(ctx->mutex); ctx->configure = 1; ctx->current_language = language_id; ctx->current_config = config; + rccMutexUnLock(ctx->mutex); } return 0; diff --git a/src/lngconfig.c b/src/lngconfig.c index 26d0779..2a108b9 100644 --- a/src/lngconfig.c +++ b/src/lngconfig.c @@ -9,6 +9,32 @@ #include "rcclocale.h" #include "lng.h" +rcc_language_id rccConfigGetLanguage(rcc_language_config config) { + unsigned long i; + rcc_language_ptr *llist; + + if (!config) return (rcc_language_id)-1; + + llist = rccGetLanguageList(config->ctx); + for (i=0;llist[i];i++) + if (llist[i] == config->language) return (rcc_language_id)i; + + return (rcc_language_id)-1; +} + +rcc_language_ptr rccConfigGetLanguagePointer(rcc_language_config config) { + if (!config) return NULL; + + return config->language; +} + +const char *rccConfigGetLanguageName(rcc_language_config config) { + if ((!config)||(!config->language)) return NULL; + + return config->language->sn; +} + + rcc_engine_ptr rccConfigGetEnginePointer(rcc_language_config config, rcc_engine_id engine_id) { unsigned int i; rcc_engine_ptr *engines; @@ -143,17 +169,30 @@ rcc_autocharset_id rccConfigGetAutoCharsetByName(rcc_language_config config, con } int rccConfigInit(rcc_language_config config, rcc_context ctx) { + int err; unsigned int i; rcc_charset_id *charsets; rcc_charset_id *dcharsets; rcc_iconv *iconv_to; + rcc_mutex mutex; if ((!ctx)||(!config)) return -1; charsets = (rcc_charset_id*)malloc((ctx->max_classes)*sizeof(rcc_charset_id)); dcharsets = (rcc_charset_id*)malloc((ctx->max_classes)*sizeof(rcc_charset_id)); iconv_to = (rcc_iconv*)malloc((ctx->max_classes)*sizeof(rcc_iconv)); - if ((!charsets)||(!dcharsets)||(!iconv_to)) { + mutex = rccMutexCreate(); + if ((!charsets)||(!dcharsets)||(!iconv_to)||(!mutex)) { + if (mutex) rccMutexFree(mutex); + if (dcharsets) free(dcharsets); + if (charsets) free(charsets); + if (iconv_to) free(iconv_to); + return -1; + } + + err = rccEngineInitContext(&config->engine_ctx, config); + if (err) { + if (mutex) rccMutexFree(mutex); if (dcharsets) free(dcharsets); if (charsets) free(charsets); if (iconv_to) free(iconv_to); @@ -177,6 +216,7 @@ int rccConfigInit(rcc_language_config config, rcc_context ctx) { config->default_charset = dcharsets; config->configured = 0; config->speller = NULL; + config->mutex = mutex; config->iconv_to = iconv_to; config->configure = 1; @@ -204,6 +244,7 @@ void rccConfigFreeIConv(rcc_language_config config) { void rccConfigClear(rcc_language_config config) { if ((config)&&(config->charset)) { + rccEngineFreeContext(&config->engine_ctx); rccConfigFreeIConv(config); if (config->trans) { rccTranslateClose(config->trans); @@ -229,6 +270,10 @@ void rccConfigClear(rcc_language_config config) { rccSpellerFree(config->speller); config->speller = NULL; } + if (config->mutex) { + rccMutexFree(config->mutex); + config->mutex = NULL; + } } } @@ -297,12 +342,42 @@ rcc_language_config rccGetCurrentConfig(rcc_context ctx) { rcc_speller rccConfigGetSpeller(rcc_language_config config) { if (!config) return NULL; - if (config->speller) return config->speller; + rccMutexLock(config->mutex); + if (!config->speller) config->speller = rccSpellerCreate(config->language->sn); + rccMutexUnLock(config->mutex); - config->speller = rccSpellerCreate(config->language->sn); return config->speller; } +rcc_translate rccConfigGetTranslator(rcc_language_config config, rcc_language_id to) { + if (!config) return NULL; + + rccMutexLock(config->mutex); + if ((config->trans)&&(config->translang != to)) { + rccTranslateClose(config->trans); + config->trans = NULL; + } + + if (!config->trans) { + config->trans = rccTranslateOpen(config->language->sn, rccGetLanguageName(config->ctx, to)); + config->translang = to; + } + rccMutexUnLock(config->mutex); + + return config->trans; +} + +rcc_translate rccConfigGetEnglishTranslator(rcc_language_config config) { + if (!config) return NULL; + + rccMutexLock(config->mutex); + if (!config->entrans) + config->entrans = rccTranslateOpen(config->language->sn, rcc_english_language_sn); + rccMutexUnLock(config->mutex); + + return config->entrans; +} + rcc_engine_id rccConfigGetSelectedEngine(rcc_language_config config) { if (!config) return (rcc_engine_id)-1; @@ -462,9 +537,11 @@ int rccConfigSetEngine(rcc_language_config config, rcc_engine_id engine_id) { } if (config->engine != engine_id) { + rccMutexLock(config->mutex); if (config->ctx->current_config == config) config->ctx->configure = 1; config->configure = 1; config->engine = engine_id; + rccMutexUnLock(config->mutex); } config->configured = 1; @@ -498,9 +575,11 @@ int rccConfigSetCharset(rcc_language_config config, rcc_class_id class_id, rcc_c if (config->charset[class_id] != charset_id) { if (config->ctx->classes[class_id]->flags&RCC_CLASS_FLAG_CONST) return -1; + rccMutexLock(config->mutex); if (config->ctx->current_config == config) config->ctx->configure = 1; config->configure = 1; config->charset[class_id] = charset_id; + rccMutexUnLock(config->mutex); } config->configured = 1; @@ -552,6 +631,7 @@ rcc_charset_id rccConfigGetLocaleUnicodeCharset(rcc_language_config config, cons } int rccConfigConfigure(rcc_language_config config) { + int err; rcc_context ctx; const char *charset; unsigned int i; @@ -559,8 +639,9 @@ int rccConfigConfigure(rcc_language_config config) { if (!config) return -1; if (!config->configure) return 0; + rccMutexLock(config->mutex); + ctx = config->ctx; - if (!ctx) return -1; rccConfigFreeIConv(config); for (i=0;in_classes;i++) { @@ -569,163 +650,13 @@ int rccConfigConfigure(rcc_language_config config) { config->iconv_to[i] = rccIConvOpen(charset, "UTF-8"); } - config->configure = 0; - - return 0; -} - - -rcc_string rccConfigSizedFrom(rcc_language_config config, rcc_class_id class_id, const char *buf, size_t len) { - rcc_context ctx; - rcc_string result; - rcc_option_value usedb4; - rcc_autocharset_id charset_id; - const char *charset; + err = rccEngineConfigure(&config->engine_ctx); + if (!err) config->configure = 0; - - if (!config) return NULL; - ctx = config->ctx; - - if (rccStringSizedCheck(buf, len)) return NULL; + rccMutexUnLock(config->mutex); - usedb4 = rccGetOption(ctx, RCC_OPTION_LEARNING_MODE); - - if (usedb4&RCC_OPTION_LEARNING_FLAG_USE) { - result = rccDb4GetKey(ctx->db4ctx, buf, len); - if (result) { - if (rccStringFixID(result, ctx)) free(result); - else return result; - } - } - - charset_id = rccConfigDetectCharset(config, class_id, buf, len); - if (charset_id != (rcc_autocharset_id)-1) - charset = rccConfigGetAutoCharsetName(config, charset_id); - else - charset = rccConfigGetCurrentCharsetName(config, class_id); - - if (charset) { - result = rccSizedFromCharset(ctx, charset, buf, len); - if (result) rccStringChangeID(result, rccGetLanguageByName(ctx, config->language->sn)); - return result; - } - - return NULL; -} -char *rccConfigSizedTo(rcc_language_config config, rcc_class_id class_id, rcc_const_string buf, size_t *rlen) { - rcc_context ctx; - const char *charset; - - if (!config) return NULL; - ctx = config->ctx; - - charset = rccConfigGetCurrentCharsetName(config, class_id); - - if (charset) - return rccSizedToCharset(ctx, charset, buf, rlen); - - return NULL; -} - - -char *rccConfigSizedRecode(rcc_language_config config, rcc_class_id from, rcc_class_id to, const char *buf, size_t len, size_t *rlen) { - rcc_context ctx; - rcc_string result; - rcc_option_value usedb4; - rcc_autocharset_id charset_id; - rcc_string stmp; - const char *tocharset, *fromcharset; - - - if (!config) return NULL; - ctx = config->ctx; - - if (rccStringSizedCheck(buf, len)) return NULL; - - usedb4 = rccGetOption(ctx, RCC_OPTION_LEARNING_MODE); - - if (usedb4&RCC_OPTION_LEARNING_FLAG_USE) { - stmp = rccDb4GetKey(ctx->db4ctx, buf, len); - if (stmp) { - if (rccStringFixID(stmp, ctx)) free(stmp); - else { - result = rccConfigSizedTo(config, to, stmp, rlen); - free(stmp); - return result; - } - } - } - - charset_id = rccConfigDetectCharset(config, from, buf, len); - if (charset_id != (rcc_autocharset_id)-1) - fromcharset = rccConfigGetAutoCharsetName(config, charset_id); - else - fromcharset = rccConfigGetCurrentCharsetName(config, from); - - tocharset = rccConfigGetCurrentCharsetName(config, to); - - if ((fromcharset)&&(tocharset)) - return rccSizedRecodeCharsets(ctx, fromcharset, tocharset, buf, len, rlen); - - return NULL; - -} - - -char *rccConfigSizedRecodeToCharset(rcc_language_config config, rcc_class_id class_id, const char *charset, rcc_const_string buf, size_t len, size_t *rlen) { - rcc_context ctx; - rcc_string result; - rcc_option_value usedb4; - rcc_autocharset_id charset_id; - rcc_string stmp; - const char *ocharset; - - - if (!config) return NULL; - ctx = config->ctx; - - if (rccStringSizedCheck(buf, len)) return NULL; - - usedb4 = rccGetOption(ctx, RCC_OPTION_LEARNING_MODE); - - if (usedb4&RCC_OPTION_LEARNING_FLAG_USE) { - stmp = rccDb4GetKey(ctx->db4ctx, buf, len); - if (stmp) { - if (rccStringFixID(stmp, ctx)) free(stmp); - else { - result = rccSizedToCharset(ctx, charset, stmp, rlen); - free(stmp); - return result; - } - } - } - - charset_id = rccConfigDetectCharset(config, class_id, buf, len); - if (charset_id != (rcc_autocharset_id)-1) - ocharset = rccConfigGetAutoCharsetName(config, charset_id); - else - ocharset = rccConfigGetCurrentCharsetName(config, class_id); - - if (ocharset) - return rccSizedRecodeCharsets(ctx, ocharset, charset, buf, len, rlen); - - return NULL; -} - -char *rccConfigSizedRecodeFromCharset(rcc_language_config config, rcc_class_id class_id, const char *charset, const char *buf, size_t len, size_t *rlen) { - rcc_context ctx; - const char *ocharset; - - if (!config) return NULL; - ctx = config->ctx; - - ocharset = rccConfigGetCurrentCharsetName(config, class_id); - - if (ocharset) - return rccSizedRecodeCharsets(ctx, charset, ocharset, buf, len, rlen); - - return NULL; + return err; } diff --git a/src/lngconfig.h b/src/lngconfig.h index 9d23139..edfc782 100644 --- a/src/lngconfig.h +++ b/src/lngconfig.h @@ -4,6 +4,7 @@ #include "rcciconv.h" #include "rcctranslate.h" #include "rccspell.h" +#include "rccmutex.h" struct rcc_language_config_t { rcc_context ctx; @@ -24,9 +25,13 @@ struct rcc_language_config_t { rcc_translate entrans; rcc_iconv fsiconv; + + rcc_engine_context_s engine_ctx; + rcc_mutex mutex; }; typedef struct rcc_language_config_t rcc_language_config_s; +rcc_language_ptr rccConfigGetLanguagePointer(rcc_language_config config); rcc_engine_ptr rccConfigGetEnginePointer(rcc_language_config config, rcc_engine_id engine_id); rcc_engine_ptr rccConfigCheckEnginePointer(rcc_language_config config, rcc_engine_id engine_id); @@ -34,12 +39,12 @@ rcc_engine_ptr rccConfigGetCurrentEnginePointer(rcc_language_config config); rcc_engine_ptr rccConfigCheckCurrentEnginePointer(rcc_language_config config); rcc_speller rccConfigGetSpeller(rcc_language_config config); +rcc_translate rccConfigGetTranslator(rcc_language_config config, rcc_language_id to); +rcc_translate rccConfigGetEnglishTranslator(rcc_language_config config); int rccConfigInit(rcc_language_config config, rcc_context ctx); void rccConfigClear(rcc_language_config config); -rcc_language_config rccGetUsableConfig(rcc_context ctx, rcc_language_id language_id); - int rccConfigConfigure(rcc_language_config config); rcc_charset_id rccConfigGetLocaleUnicodeCharset(rcc_language_config config, const char *locale_variable); diff --git a/src/lngrecode.c b/src/lngrecode.c new file mode 100644 index 0000000..aef8e24 --- /dev/null +++ b/src/lngrecode.c @@ -0,0 +1,169 @@ +#include +#include +#include + +#include "../config.h" + +#include "internal.h" +#include "fs.h" + +rcc_string rccConfigSizedFrom(rcc_language_config config, rcc_class_id class_id, const char *buf, size_t len) { + rcc_context ctx; + rcc_string result; + rcc_option_value usedb4; + rcc_autocharset_id charset_id; + const char *charset; + + + if (!config) return NULL; + ctx = config->ctx; + + if (rccStringSizedCheck(buf, len)) return NULL; + + usedb4 = rccGetOption(ctx, RCC_OPTION_LEARNING_MODE); + + if (usedb4&RCC_OPTION_LEARNING_FLAG_USE) { + result = rccDb4GetKey(ctx->db4ctx, buf, len); + if (result) { + if (rccStringFixID(result, ctx)) free(result); + else return result; + } + } + + charset_id = rccConfigDetectCharset(config, class_id, buf, len); + if (charset_id != (rcc_autocharset_id)-1) + charset = rccConfigGetAutoCharsetName(config, charset_id); + else + charset = rccConfigGetCurrentCharsetName(config, class_id); + + if (charset) { + result = rccSizedFromCharset(ctx, charset, buf, len); + if (result) rccStringChangeID(result, rccGetLanguageByName(ctx, config->language->sn)); + return result; + } + + return NULL; +} + +/* The supplied config have priority over language tag in the buf! */ +char *rccConfigSizedTo(rcc_language_config config, rcc_class_id class_id, rcc_const_string buf, size_t *rlen) { + char *result; + const char *charset; + + if (!config) return NULL; + + if ((rccGetClassType(config->ctx, class_id) == RCC_CLASS_FS)&&(rccGetOption(config->ctx, RCC_OPTION_AUTODETECT_FS_NAMES))) { + result = rccFS5(config->ctx, config, class_id, rccStringGetString(buf)); + if (result) { + if (rlen) *rlen = strlen(result); + return result; + } + } + + charset = rccConfigGetCurrentCharsetName(config, class_id); + + if (charset) + return rccSizedToCharset(config->ctx, charset, buf, rlen); + + return NULL; +} + + +char *rccConfigSizedRecode(rcc_language_config config, rcc_class_id from, rcc_class_id to, const char *buf, size_t len, size_t *rlen) { + rcc_context ctx; + rcc_string result; + rcc_option_value usedb4; + rcc_autocharset_id charset_id; + rcc_string stmp; + const char *tocharset, *fromcharset; + + + if (!config) return NULL; + ctx = config->ctx; + + if (rccStringSizedCheck(buf, len)) return NULL; + + usedb4 = rccGetOption(ctx, RCC_OPTION_LEARNING_MODE); + + if (usedb4&RCC_OPTION_LEARNING_FLAG_USE) { + stmp = rccDb4GetKey(ctx->db4ctx, buf, len); + if (stmp) { + if (rccStringFixID(stmp, ctx)) free(stmp); + else { + result = rccConfigSizedTo(config, to, stmp, rlen); + free(stmp); + return result; + } + } + } + + charset_id = rccConfigDetectCharset(config, from, buf, len); + if (charset_id != (rcc_autocharset_id)-1) + fromcharset = rccConfigGetAutoCharsetName(config, charset_id); + else + fromcharset = rccConfigGetCurrentCharsetName(config, from); + + tocharset = rccConfigGetCurrentCharsetName(config, to); + + if ((fromcharset)&&(tocharset)) + return rccSizedRecodeCharsets(ctx, fromcharset, tocharset, buf, len, rlen); + + return NULL; + +} + + +char *rccConfigSizedRecodeToCharset(rcc_language_config config, rcc_class_id class_id, const char *charset, rcc_const_string buf, size_t len, size_t *rlen) { + rcc_context ctx; + rcc_string result; + rcc_option_value usedb4; + rcc_autocharset_id charset_id; + rcc_string stmp; + const char *ocharset; + + + if (!config) return NULL; + ctx = config->ctx; + + if (rccStringSizedCheck(buf, len)) return NULL; + + usedb4 = rccGetOption(ctx, RCC_OPTION_LEARNING_MODE); + + if (usedb4&RCC_OPTION_LEARNING_FLAG_USE) { + stmp = rccDb4GetKey(ctx->db4ctx, buf, len); + if (stmp) { + if (rccStringFixID(stmp, ctx)) free(stmp); + else { + result = rccSizedToCharset(ctx, charset, stmp, rlen); + free(stmp); + return result; + } + } + } + + charset_id = rccConfigDetectCharset(config, class_id, buf, len); + if (charset_id != (rcc_autocharset_id)-1) + ocharset = rccConfigGetAutoCharsetName(config, charset_id); + else + ocharset = rccConfigGetCurrentCharsetName(config, class_id); + + if (ocharset) + return rccSizedRecodeCharsets(ctx, ocharset, charset, buf, len, rlen); + + return NULL; +} + +char *rccConfigSizedRecodeFromCharset(rcc_language_config config, rcc_class_id class_id, const char *charset, const char *buf, size_t len, size_t *rlen) { + rcc_context ctx; + const char *ocharset; + + if (!config) return NULL; + ctx = config->ctx; + + ocharset = rccConfigGetCurrentCharsetName(config, class_id); + + if (ocharset) + return rccSizedRecodeCharsets(ctx, charset, ocharset, buf, len, rlen); + + return NULL; +} diff --git a/src/lngrecode.h b/src/lngrecode.h new file mode 100644 index 0000000..218c8b9 --- /dev/null +++ b/src/lngrecode.h @@ -0,0 +1,5 @@ +#ifndef _RCC_LNG_RECODE_H +#define _RCC_LNG_RECODE_H + + +#endif /* _RCC_LNG_RECODE_H */ diff --git a/src/opt.c b/src/opt.c index 18d2054..e6f8486 100644 --- a/src/opt.c +++ b/src/opt.c @@ -50,8 +50,10 @@ int rccSetOption(rcc_context ctx, rcc_option option, rcc_option_value value) { ctx->default_options[option] = 0; if (ctx->options[option] != value) { + rccMutexLock(ctx->mutex); ctx->configure = 1; ctx->options[option]=value; + rccMutexUnLock(ctx->mutex); } return 0; diff --git a/src/rccenca.c b/src/rccenca.c index 8263742..28d3ccf 100644 --- a/src/rccenca.c +++ b/src/rccenca.c @@ -24,9 +24,9 @@ rcc_engine_internal rccEncaInitContext(rcc_engine_context ctx) { #ifdef RCC_ENCA_SUPPORT EncaAnalyser enca; - if ((!ctx)||(!ctx->language)) return NULL; + if ((!ctx)||(!ctx->config)) return NULL; - enca = enca_analyser_alloc(ctx->language->sn); + enca = enca_analyser_alloc(rccConfigGetLanguageName(ctx->config)); if (!enca) return NULL; enca_set_threshold(enca, 1); @@ -65,7 +65,7 @@ rcc_autocharset_id rccEnca(rcc_engine_context ctx, const char *buf, int len) { if (ee.charset<0) return (rcc_charset_id)-1; charset = enca_charset_name(ee.charset, ENCA_NAME_STYLE_ICONV); - return rccGetAutoCharsetByName(ctx->ctx, charset); + return rccGetAutoCharsetByName(ctx->config->ctx, charset); #else /* RCC_ENCA_SUPPORT */ return (rcc_charset_id)-1; #endif /* RCC_ENCA_SUPPORT */ diff --git a/src/rcctranslate.c b/src/rcctranslate.c index 9dcf411..37f0f01 100644 --- a/src/rcctranslate.c +++ b/src/rcctranslate.c @@ -103,7 +103,6 @@ static int rccTranslateQueue(rcc_translate translate, const char *buf) { err = rccExternalWrite(translate->sock, (char*)&translate->wprefix, sizeof(rcc_translate_prefix_s) - 1, 0); if (!err) err = rccExternalWrite(translate->sock, buf, len + 1, 0); - fsync(translate->sock); return err?1:0; } diff --git a/src/recode.c b/src/recode.c index d337164..48ce2d6 100644 --- a/src/recode.c +++ b/src/recode.c @@ -21,7 +21,7 @@ #define RCC_ACCEPTABLE_PROBABILITY 0 #define RCC_ACCEPTABLE_LENGTH 3 -rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len, rcc_string *retstring) { +static rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len, rcc_string *retstring) { rcc_speller speller = NULL, english_speller = NULL; unsigned long i, nlanguages; rcc_language_config config, config0 = NULL; @@ -90,7 +90,6 @@ rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id class_id else english_mode = 0; utf8 = (char*)rccStringGetString(recoded); - printf("%s\n", config->language->sn); for (result=0,english=0,words=0,longest=0,mode=0,j=0;utf8[j];j++) { if (isSpace(utf8[j])) { @@ -100,7 +99,6 @@ rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id class_id else { if ((english_mode)&&(!english_word)) is_english_string = 0; spres = rccSpellerSized(speller, utf8 + mode - 1, j - mode + 1)?1:0; - printf("%.*s %s\n",j-mode+1,utf8+mode-1, spres?"<======":""); if ((spres)&&((j - mode + 1)>longest)) longest = j - mode + 1; result+=spres; } @@ -131,7 +129,6 @@ rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id class_id if (english_mode) { if (english_string) free(english_string); - printf("%u %u\n", result, words); english_res = 1.*result/words; english_lang = (rcc_language_id)i; @@ -139,7 +136,6 @@ rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id class_id english_string = recoded; } else if (words>english) { res = 1.*result/(words - english); - printf("%u %u %u\n", result, words, english); if ((res > RCC_REQUIRED_PROBABILITY)&&(longest > RCC_REQUIRED_LENGTH)) { if (best_string) free(best_string); if (english_string) free(english_string); @@ -214,35 +210,38 @@ rcc_language_id rccDetectLanguage(rcc_context ctx, rcc_class_id class_id, const } -rcc_autocharset_id rccConfigDetectCharset(rcc_language_config config, rcc_class_id class_id, const char *buf, size_t len) { +static rcc_autocharset_id rccConfigDetectCharsetInternal(rcc_language_config config, rcc_class_id class_id, const char *buf, size_t len) { + int err; rcc_context ctx; rcc_class_type class_type; rcc_engine_ptr engine; + rcc_autocharset_id autocharset_id; if ((!buf)||(!config)) return (rcc_autocharset_id)-1; ctx = config->ctx; + + err = rccConfigConfigure(config); + if (err) return (rcc_autocharset_id)-1; class_type = rccGetClassType(ctx, class_id); if ((class_type != RCC_CLASS_FS)||((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_OPTION_AUTODETECT_FS_TITLES)))) { + rccMutexLock(config->mutex); engine = rccConfigGetCurrentEnginePointer(config); - if ((!engine)||(!engine->func)) return (rcc_autocharset_id)-1; - return engine->func(&ctx->engine_ctx, buf, len); + if ((engine)&&(engine->func)) autocharset_id = engine->func(&config->engine_ctx, buf, len); + else autocharset_id = (rcc_autocharset_id)-1; + rccMutexUnLock(config->mutex); + return autocharset_id; } return (rcc_autocharset_id)-1; } -int rccDetectCharset(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len) { - if (!ctx) { - if (rcc_default_ctx) ctx = rcc_default_ctx; - else return -1; - } - return rccConfigDetectCharset(ctx->current_config, class_id, buf, len); +rcc_autocharset_id rccConfigDetectCharset(rcc_language_config config, rcc_class_id class_id, const char *buf, size_t len) { + return rccConfigDetectCharsetInternal(config, class_id, buf, len); } - rcc_string rccSizedFrom(rcc_context ctx, rcc_class_id class_id, const char *buf, size_t len) { int err; size_t ret; @@ -287,7 +286,7 @@ rcc_string rccSizedFrom(rcc_context ctx, rcc_class_id class_id, const char *buf, detected_language_id = rccDetectLanguageInternal(ctx, class_id, buf, len, &result); if (detected_language_id != (rcc_language_id)-1) { - printf("Language %i: %s\n", rccStringGetLanguage(result), result); + /*printf("Language %i: %s\n", rccStringGetLanguage(result), result);*/ return result; } @@ -295,6 +294,7 @@ rcc_string rccSizedFrom(rcc_context ctx, rcc_class_id class_id, const char *buf, err = rccConfigure(ctx); if (err) return NULL; + rccMutexLock(ctx->mutex); charset_id = rccDetectCharset(ctx, class_id, buf, len); if (charset_id != (rcc_autocharset_id)-1) { icnv = ctx->iconv_auto[charset_id]; @@ -312,13 +312,14 @@ rcc_string rccSizedFrom(rcc_context ctx, rcc_class_id class_id, const char *buf, } else { result = rccCreateString(language_id, buf, len); } + rccMutexUnLock(ctx->mutex); if ((result)&&(usedb4&RCC_OPTION_LEARNING_FLAG_LEARN)) { if (!rccStringSetLang(result, ctx->languages[language_id]->sn)) { rccDb4SetKey(ctx->db4ctx, buf, len, result); } } - + return result; } @@ -326,7 +327,6 @@ char *rccSizedTo(rcc_context ctx, rcc_class_id class_id, rcc_const_string buf, s int err; size_t newlen; char *result; - char *prefix, *name; const char *utfstring; char *translated = NULL; rcc_language_config config; @@ -334,6 +334,7 @@ char *rccSizedTo(rcc_context ctx, rcc_class_id class_id, rcc_const_string buf, s rcc_language_id current_language_id; rcc_class_type class_type; rcc_option_value translate; + rcc_translate trans, entrans; const char *langname; unsigned char english_source; rcc_iconv icnv; @@ -365,32 +366,27 @@ char *rccSizedTo(rcc_context ctx, rcc_class_id class_id, rcc_const_string buf, s else english_source = 1; if ((class_type != RCC_CLASS_FS)&&((translate==RCC_OPTION_TRANSLATE_FULL)||((translate)&&(!english_source)))) { + rccMutexLock(ctx->mutex); + current_language_id = rccGetCurrentLanguage(ctx); if (current_language_id != language_id) { - if ((config->trans)&&(config->translang != current_language_id)) { - rccTranslateClose(config->trans); - config->trans = NULL; - } - if (translate != RCC_OPTION_TRANSLATE_TO_ENGLISH) { - if (!config->trans) { - config->trans = rccTranslateOpen(rccGetLanguageName(ctx, language_id), rccGetLanguageName(ctx, current_language_id)); - config->translang = current_language_id; - } - - if (config->trans) { - translated = rccTranslate(config->trans, utfstring); + trans = rccConfigGetTranslator(config, current_language_id); + if (trans) { + translated = rccTranslate(trans, utfstring); if (translated) { language_id = current_language_id; config = rccGetConfig(ctx, language_id); if (!config) { + rccMutexUnLock(ctx->mutex); free(translated); return NULL; } err = rccConfigConfigure(config); if (err) { + rccMutexUnLock(ctx->mutex); free(translated); return NULL; } @@ -399,53 +395,46 @@ char *rccSizedTo(rcc_context ctx, rcc_class_id class_id, rcc_const_string buf, s } if ((translate == RCC_OPTION_TRANSLATE_TO_ENGLISH)||((config->trans)&&(!translated))) { - if (!config->entrans) { - config->entrans = rccTranslateOpen(rccGetLanguageName(ctx, language_id), rcc_english_language_sn); - } - - if (config->entrans) { + entrans = rccConfigGetEnglishTranslator(config); + if (entrans) { translated = rccTranslate(config->entrans, utfstring); config = rccGetConfig(ctx, language_id); - if (!config) return translated; + if (!config) { + rccMutexUnLock(ctx->mutex); + return translated; + } err = rccConfigConfigure(config); - if (err) return translated; + if (err) { + rccMutexUnLock(ctx->mutex); + return translated; + } } } } + rccMutexUnLock(ctx->mutex); } if ((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_OPTION_AUTODETECT_FS_NAMES))) { - if (rccIsASCII(utfstring)) { - result = rccStringExtractString(buf); - if ((result)&&(rlen)) *rlen = strlen(result); - return result; - } - - name = (char*)utfstring; - prefix = NULL; - - err = rccFS0(config, NULL, buf, &prefix, &name); - if (err>=0) { - result = rccFS3(config, class_id, prefix, name); - if (!err) { - if (prefix) free(prefix); - free(name); - } - if (rlen) *rlen = strlen(result); - return result; - } + result = rccFS5(ctx, config, class_id, utfstring); + if (result) { + if (rlen) *rlen = strlen(result); + return result; + } } + rccMutexLock(ctx->mutex); + rccMutexLock(config->mutex); icnv = config->iconv_to[class_id]; if (icnv) { newlen = rccIConvInternal(ctx, icnv, translated?translated:utfstring, translated?0:newlen); if (translated) free(translated); - if (newlen == (size_t)-1) return NULL; - - result = rccCreateResult(ctx, newlen); - if (rlen) *rlen = newlen; + if (newlen == (size_t)-1) result = NULL; + else { + result = rccCreateResult(ctx, newlen); + if (rlen) *rlen = newlen; + } } else { if (translated) { result = translated; @@ -455,12 +444,13 @@ char *rccSizedTo(rcc_context ctx, rcc_class_id class_id, rcc_const_string buf, s if (rlen) *rlen = newlen; } } + rccMutexUnLock(config->mutex); + rccMutexUnLock(ctx->mutex); return result; } char *rccSizedRecode(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *buf, size_t len, size_t *rlen) { - int err; rcc_string stmp; char *result; const char *from_charset, *to_charset; @@ -479,17 +469,17 @@ char *rccSizedRecode(rcc_context ctx, rcc_class_id from, rcc_class_id to, const if (rccGetOption(ctx, RCC_OPTION_AUTODETECT_LANGUAGE)) goto recoding; if (rccGetOption(ctx, RCC_OPTION_TRANSLATE)) goto recoding; - err = rccConfigure(ctx); - if (err) return NULL; - + rccMutexLock(ctx->mutex); from_charset_id = rccDetectCharset(ctx, from, buf, len); if (from_charset_id != (rcc_charset_id)-1) { from_charset = rccGetAutoCharsetName(ctx, from_charset_id); to_charset = rccGetCurrentCharsetName(ctx, to); + rccMutexUnLock(ctx->mutex); if ((from_charset)&&(to_charset)&&(!strcasecmp(from_charset, to_charset))) return NULL; } else { from_charset_id = rccGetCurrentCharset(ctx, from); to_charset_id = rccGetCurrentCharset(ctx, to); + rccMutexUnLock(ctx->mutex); if (from_charset_id == to_charset_id) return NULL; } @@ -520,8 +510,10 @@ char *rccFS(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *fsp config = rccGetCurrentConfig(ctx); if (!config) return NULL; - + + rccMutexLock(config->mutex); err = rccFS1(config, fspath, &prefix, &name); + rccMutexUnLock(config->mutex); if (err) { if (err < 0) return NULL; @@ -538,8 +530,13 @@ char *rccFS(rcc_context ctx, rcc_class_id from, rcc_class_id to, const char *fsp string = rccFrom(ctx, from, name); if (string) { config = rccGetConfig(ctx, rccStringGetLanguage(string)); - if (config) result = rccFS3(config, to, prefix, rccStringGetString(string)); - else result = NULL; + if (config) { + rccMutexLock(ctx->mutex); + rccMutexLock(config->mutex); + result = rccFS3(config, to, prefix, rccStringGetString(string)); + rccMutexUnLock(config->mutex); + rccMutexUnLock(ctx->mutex); + } else result = NULL; free(string); } else result = NULL; @@ -557,25 +554,30 @@ rcc_string rccSizedFromCharset(rcc_context ctx, const char *charset, const char rcc_language_config config; rcc_language_id language_id; size_t res; + rcc_string ret; if ((!buf)||(!charset)) return NULL; - language_id = rccGetCurrentLanguage(ctx); - if ((language_id == (rcc_language_id)-1)||(language_id == 0)) return NULL; - config = rccGetConfig(ctx, language_id); + config = rccGetCurrentConfig(ctx); if (!config) return NULL; + language_id = rccConfigGetLanguage(config); + icnv = rccIConvOpen("UTF-8", charset); if (icnv) { + rccMutexLock(ctx->mutex); res = rccIConvInternal(ctx, icnv, buf, len); rccIConvClose(icnv); - if (res == (size_t)-1) return NULL; - return rccCreateString(language_id, ctx->tmpbuffer, res); - } - return rccCreateString(language_id, buf, len); + if (res == (size_t)-1) ret = NULL; + else ret = rccCreateString(language_id, ctx->tmpbuffer, res); + rccMutexUnLock(ctx->mutex); + } else ret = rccCreateString(language_id, buf, len); + + return ret; } char *rccSizedToCharset(rcc_context ctx, const char *charset, rcc_const_string buf, size_t *rlen) { + char *ret; rcc_iconv icnv; size_t res; @@ -586,12 +588,17 @@ char *rccSizedToCharset(rcc_context ctx, const char *charset, rcc_const_string b icnv = rccIConvOpen(charset, "UTF-8"); if (icnv) { + rccMutexLock(ctx->mutex); res = rccIConvInternal(ctx, icnv, rccStringGetString(buf), res); rccIConvClose(icnv); - if (res == (size_t)-1) return NULL; - - if (rlen) *rlen = res; - return rccCreateResult(ctx, res); + if (res == (size_t)-1) ret = NULL; + else { + ret = rccCreateResult(ctx, res); + if (rlen) *rlen = res; + } + rccMutexUnLock(ctx->mutex); + + return ret; } if (rlen) *rlen = res; @@ -602,6 +609,7 @@ char *rccSizedToCharset(rcc_context ctx, const char *charset, rcc_const_string b char *rccSizedRecodeToCharset(rcc_context ctx, rcc_class_id class_id, const char *charset, rcc_const_string buf, size_t len, size_t *rlen) { size_t res; rcc_iconv icnv; + char *ret; const char *str; char *utf8, *extracted; @@ -614,13 +622,18 @@ char *rccSizedRecodeToCharset(rcc_context ctx, rcc_class_id class_id, const char icnv = rccIConvOpen(charset, "UTF-8"); if (icnv) { + rccMutexLock(ctx->mutex); res = rccIConvInternal(ctx, icnv, str, 0); rccIConvClose(icnv); free(utf8); - if (res == (size_t)-1) return NULL; - if (rlen) *rlen = res; - return rccCreateResult(ctx, res); + if (res == (size_t)-1) ret = NULL; + else { + ret = rccCreateResult(ctx, res); + if (rlen) *rlen = res; + } + rccMutexUnLock(ctx->mutex); + return ret; } extracted = rccStringExtractString(utf8); @@ -644,12 +657,13 @@ char *rccSizedRecodeFromCharset(rcc_context ctx, rcc_class_id class_id, const ch icnv = rccIConvOpen("UTF-8", charset); if (icnv) { + rccMutexLock(ctx->mutex); res = rccIConvInternal(ctx, icnv, buf, len); rccIConvClose(icnv); - if (res == (size_t)-1) return NULL; - - str = rccCreateString(rccGetCurrentLanguage(ctx), ctx->tmpbuffer, res); + if (res == (size_t)-1) str = NULL; + else str = rccCreateString(rccGetCurrentLanguage(ctx), ctx->tmpbuffer, res); + rccMutexUnLock(ctx->mutex); } else str = rccCreateString(rccGetCurrentLanguage(ctx), buf, len); if (!str) return NULL; @@ -662,23 +676,12 @@ char *rccSizedRecodeFromCharset(rcc_context ctx, rcc_class_id class_id, const ch char *rccSizedRecodeCharsets(rcc_context ctx, const char *from, const char *to, const char *buf, size_t len, size_t *rlen) { char *str; - size_t res; rcc_iconv icnv; icnv = rccIConvOpen(to, from); if (!icnv) return NULL; - - res = rccIConvInternal(ctx, icnv, buf, len); + str = rccIConv(icnv, buf, len, rlen); rccIConvClose(icnv); - if (res == (size_t)-1) return NULL; - - - - str = (char*)malloc((res+1)*sizeof(char)); - if (!str) return NULL; - memcpy(str, ctx->tmpbuffer, res); - if (rlen) *rlen = res; - return str; } -- cgit v1.2.3