summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ToDo5
-rw-r--r--engines/Makefile.am5
-rw-r--r--engines/russian.c2
-rw-r--r--engines/western.c72
-rw-r--r--examples/rcc.xml18
-rw-r--r--src/Makefile.am1
-rw-r--r--src/curconfig.c9
-rw-r--r--src/engine.c24
-rw-r--r--src/engine.h5
-rw-r--r--src/fs.c35
-rw-r--r--src/fs.h1
-rw-r--r--src/internal.h4
-rw-r--r--src/librcc.c33
-rw-r--r--src/librcc.h49
-rw-r--r--src/lng.c2
-rw-r--r--src/lngconfig.c247
-rw-r--r--src/lngconfig.h9
-rw-r--r--src/lngrecode.c169
-rw-r--r--src/lngrecode.h5
-rw-r--r--src/opt.c2
-rw-r--r--src/rccenca.c6
-rw-r--r--src/rcctranslate.c1
-rw-r--r--src/recode.c195
23 files changed, 587 insertions, 312 deletions
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 <librcc.h>
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 <stdio.h>
+#include <string.h>
+
+#include <librcc.h>
+
+#define bit(i) (1<<i)
+
+/*
+ * Latin unicode subset:
+ * 0x100 - 0x17E
+ * 0x180 - 0x24F
+ * 0x1E00 - 0x1EFF
+ */
+
+static rcc_autocharset_id AutoengineWestern(rcc_engine_context ctx, const char *sbuf, int len) {
+ const unsigned char *buf = sbuf;
+ long i,j;
+ int bytes=0,rflag=0;
+ int res=0;
+
+ if (!len) len = strlen(buf);
+ for (i=0;i<len;i++) {
+ if (buf[i]<128) continue;
+
+ if (bytes>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 @@
<Charset>SHIFT-JIS</Charset>
</Charsets>
</Language>
+ <Language name="de">
+ <FullName>German</FullName>
+ <Charsets>
+ <Charset>UTF-8</Charset>
+ </Charsets>
+ <Engines>
+ <Engine>western</Engine>
+ </Engines>
+ </Language>
+ <Language name="fr">
+ <FullName>French</FullName>
+ <Charsets>
+ <Charset>UTF-8</Charset>
+ </Charsets>
+ <Engines>
+ <Engine>western</Engine>
+ </Engines>
+ </Language>
</Languages>
</LibRCC> \ 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;i<max_languages;i++)
configs[i].charset = NULL;
- err = rccEngineInitContext(&ctx->engine_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;i<ctx->n_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
@@ -624,6 +624,25 @@ rcc_language_config rccCheckConfig(rcc_context ctx, rcc_language_id language_id)
*/
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.
*
@@ -642,6 +661,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
*
* @param config is language configuration
@@ -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
@@ -1133,16 +1168,6 @@ char *rccSizedRecodeCharsets(rcc_context ctx, const char *from, const char *to,
/**
- * 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
* preconfigured encoding of class is assumed.
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;i<ctx->n_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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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;
}