13
static void rccIConvCopySymbol(char **in_buf, int *in_left, char **out_buf, int *out_left) {
14
if ((out_left>0)&&(in_left>0)) {
15
(**out_buf)=(**in_buf);
23
static int rccIConvUTFBytes(unsigned char c) {
28
if ((c&bit(j))==0) break;
30
if ((j==0)||(j==6)) return 1;
34
static int rccIConv(rcc_context *ctx, iconv_t icnv, char *buf, int len) {
35
char *in_buf, *out_buf, *res, err;
36
int in_left, out_left, olen;
40
if ((!buf)||(!ctx)||(icnv == (iconv_t)-1)) return -1;
42
len = STRNLEN(buf,len);
44
if (iconv(icnv, NULL, NULL, NULL, NULL) == -1) return -1;
50
out_buf = ctx->tmpbuffer;
51
out_left = RCC_MAX_STRING_CHARS;
54
err=iconv(icnv, &in_buf, &in_left, &out_buf, &out_left);
57
*(int*)(ctx->tmpbuffer+(CHARSET_MAX_STRING_SIZE-sizeof(int)))=0;
58
} else if (errno==EILSEQ) {
59
if (errors++<CHARSET_MAX_ERRORS) {
60
for (ub=utf_mode?rccIConvUTFBytes(*in_buf):1;ub>0;ub--)
61
rccIConvCopySymbol(&in_buf, &in_left, &out_buf, &out_left);
62
if (in_left>0) goto loop;
63
} else if (!utf_mode) {
74
return CHARSET_MAX_STRING_SIZE - out_left;
78
static charset_id rccIConvAuto(rcc_context *ctx, rcc_class_id class_id, char *buf, int len) {
79
rcc_class_type class_type;
81
if ((!ctx)||(!buf)) return -1;
83
class_type = rccGetClassType(ctx, class_id);
84
if ((class_type == RCC_CLASS_STANDARD)||((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_AUTODETECT_FS_TITLES)))) {
85
engine = rccGetCurrentEngine(ctx);
86
if ((!engine)||(!engine->func)||(!stricmp(engine->title, "off"))||(!strcmp(engine->title, "dissable"))) return -1;
88
return engine->func(buf, len);
94
rcc_string rccFrom(rcc_context *ctx, rcc_class_id class_id, const char *buf, int len, int *rlen) {
96
rcc_language_id language_id;
97
rcc_charset_id charset_id;
98
iconv_t icnv = (iconv_t)-1;
101
if ((!ctx)||(class_id<0)||(class_id>=ctx->n_classes)||(!buf)) return NULL;
103
err = rccConfigure(ctx);
104
if (err) return NULL;
107
language_id = rccGetCurrentLanguage(ctx);
108
// DS: Learning. check database (language_id)
110
charset_id = rccIConvAuto(ctx, buf, len);
111
if (charset_id > 0) icnv = ctx->iconv_auto[charset_id];
112
if (icnv == (iconv_t)-1) {
113
icnv = ctx->iconv_from[class_id];
114
if (icnv == (iconv_t)-1) return NULL;
117
if (icnv == (iconv_t)-2) {
118
result = rccCreateString(language_id, buf, len, rlen);
120
err = rccIConv(ctx, icnv, buf, len);
121
if (err<=0) return NULL;
122
result = rccCreateString(language_id, ctx->tmpbuffer, err, rlen);
125
// DS: Learning. write database
130
char *rccTo(rcc_context *ctx, rcc_class_id class_id, const rcc_string buf, int len, int *rlen) {
134
rcc_language_id language_id;
135
rcc_charset_id charset_id;
138
if ((!ctx)||(class_id<0)||(class_id>=ctx->n_classes)||(!buf)) return NULL;
140
language_id = rccCheckString(ctx, buf);
141
if (!language_id) return NULL;
143
err = rccConfigure(ctx);
144
if (err) return NULL;
146
icnv = ctx->iconv_to[class_id];
148
if ((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_AUTODETECT_FS_NAMES))) {
149
// DS: file_names (autodetect fspath)
150
prefix = NULL; name = buf + sizeof(rcc_string_header);
151
err = rccFS0(NULL, buf, &prefix, &name);
153
result = rccFS3(ctx, language_id, class_id, prefix, name, 0, rlen);
158
if (icnv == (iconv_t)-1) return NULL;
159
if (icnv == (iconv_t)-2) {
160
result = rccParseString(ctx, buf, len, rlen);
162
err = rccIConv(ctx, icnv, buf + sizeof(rcc_string_header), len?len-sizeof(rcc_string_header):0);
163
if (err<=0) return NULL;
165
result = rccCreateAnswer(ctx, err, rlen);
171
char *rccRecode(rcc_context *ctx, rcc_class_id from, rcc_class_id to, const char *buf, int len, int *rlen) {
174
charset_id from_charset_id, to_charset_id;
176
if ((!ctx)||(from<0)||(from>=ctx->n_classes)||(to<0)||(to>=ctx->n_classes)||(!buf)) return NULL;
178
if ((class_type == RCC_CLASS_FS)&&(rccGetOption(ctx, RCC_AUTODETECT_FS_NAMES))) goto recoding;
180
from_charset_id = rccIConvAuto(ctx, buf, len);
181
if (from_charset_id>0) {
182
from_charset = rccGetAutoCharsetName(ctx, from_charset_id);
183
to_charset = rccGetCurrentCharsetName(ctx, to);
184
if ((from_charset)&&(to_charset)&&(!stricmp(from_charset, to_charset))) return NULL;
186
from_charset_id = rccGetCurrentCharset(ctx, from)
187
to_charset_id = rccGetCurrentCharset(ctx, to);
188
if (from_charset_id == to_charset_id) return NULL;
192
stmp = rccFrom(ctx, from, buf, len, &nlen);
194
buf = rccTo(ctx, to, stmp, nlen, rlen);
199
return rccTo(ctx, to, buf, len, rlen);
202
char *rccFS(rcc_context *ctx, rcc_class_id from, rcc_class_id to, const char *fspath, const char *path, const char *filename) {
204
char *prefix = path, *name = filename;
208
char *result_fn = NULL;
211
err = rccFS1(ctx, fspath, &prefix, &name);
213
if (err<0) return NULL;
217
string = rccFrom(ctx, from, name, len, rlen);
219
language_id = rccGetCurrentLanguage(ctx);
220
result = rccFS3(ctx, language_id, to, prefix, string + sizeof(rcc_string_header), 0, NULL);
222
} else result = NULL;