/rusxmms/librcc

To get this branch, use:
bzr branch http://suren.me/webbzr/rusxmms/librcc

« back to all changes in this revision

Viewing changes to external/rcclibtranslate.c

  • Committer: Suren A. Chilingaryan
  • Date: 2005-07-29 03:26:28 UTC
  • Revision ID: Arch-1:ds@dside.dyndns.org--darksoft-2004%librcc--main--0.1--patch-23
Translation
    - Language Translation using libtranslate is implemented
    - Autoengine sets current charset (option)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include <stdio.h>
 
2
#include <stdlib.h>
 
3
#include <string.h>
 
4
 
 
5
 
 
6
#include "../config.h"
 
7
 
 
8
#ifdef HAVE_UNISTD_H
 
9
# include <unistd.h>
 
10
#endif /* HAVE_UNISTD_H */
 
11
#ifdef HAVE_SYS_TYPES_H
 
12
# include <sys/types.h>
 
13
#endif /* HAVE_SYS_TYPES_H */
 
14
#ifdef HAVE_SYS_STAT_H
 
15
# include <sys/stat.h>
 
16
#endif /* HAVE_SYS_STAT_H */
 
17
 
 
18
#ifdef HAVE_LIBTRANSLATE
 
19
#include <translate.h>
 
20
#endif /* HAVE_LIBTRANSLATE */
 
21
 
 
22
#include "../src/rccexternal.h"
 
23
#include "../src/rcctranslate.h"
 
24
#include "../src/rccdb4.h"
 
25
#include "rcclibtranslate.h"
 
26
 
 
27
 
 
28
#ifdef HAVE_LIBTRANSLATE
 
29
static TranslateSession *session = NULL;
 
30
static db4_context db4ctx = NULL;
 
31
 
 
32
static int exitflag = 0;
 
33
static GMutex *mutex = NULL;
 
34
static GCond *cond = NULL;
 
35
static GQueue *queue = NULL;
 
36
static GThread *thread = NULL;
 
37
 
 
38
 
 
39
static char *rccCreateKey(const char *from, const char *to, const char *data, size_t *keysize) {
 
40
    char *res;
 
41
 
 
42
    *keysize = strlen(data) + 4;
 
43
    res = (char*)malloc((*keysize+1)*sizeof(char));
 
44
    if (res) sprintf(res,"%s%s%s",from,to,data);
 
45
    return res;
 
46
}
 
47
 
 
48
static void *rccLibPostponed(void *info) {
 
49
    char *result;
 
50
    char *data;
 
51
    char from[3];
 
52
    char to[3];
 
53
    
 
54
    from[2] = 0;
 
55
    to[2] = 0;
 
56
    
 
57
    g_mutex_lock(mutex);
 
58
    while (!exitflag) {
 
59
        data = (char*)g_queue_pop_head(queue);
 
60
        if (data) {
 
61
            g_mutex_unlock(mutex);
 
62
            
 
63
            memcpy(from, data, 2);
 
64
            memcpy(to, data + 2, 2);
 
65
            result = translate_session_translate_text(session, data + 4, from, to, NULL, NULL, NULL);
 
66
 
 
67
            if (result) {
 
68
                rccDb4SetKey(db4ctx, data, strlen(data), result);
 
69
                free(result);
 
70
            }
 
71
 
 
72
            free(data);
 
73
            g_mutex_lock(mutex);
 
74
        } else {
 
75
            g_cond_wait(cond, mutex);
 
76
        }
 
77
    }
 
78
    g_mutex_unlock(mutex);
 
79
    return NULL;
 
80
}
 
81
 
 
82
#endif /* HAVE_LIBTRANSLATE */
 
83
 
 
84
 
 
85
int rccLibTranslateInit(const char *rcc_home_dir) {
 
86
#ifdef HAVE_LIBTRANSLATE
 
87
    size_t size;
 
88
    char *dbname;
 
89
    GSList *list = NULL;
 
90
 
 
91
    const char *http_proxy;
 
92
 
 
93
    if (!translate_init(NULL)) return -1;
 
94
    
 
95
    http_proxy = getenv("HTTP_PROXY");
 
96
    if (!http_proxy) http_proxy = getenv("http_proxy");
 
97
    translate_set_proxy(http_proxy);
 
98
 
 
99
    list = translate_get_services();
 
100
 
 
101
    session = translate_session_new(list);
 
102
 
 
103
    g_slist_foreach(list, (GFunc) g_object_unref, NULL);
 
104
    g_slist_free(list);
 
105
    
 
106
 
 
107
    size = strlen(rcc_home_dir) + 32;
 
108
    dbname = (char*)malloc(size*sizeof(char));
 
109
    if (dbname) {
 
110
        sprintf(dbname,"%s/.rcc/",rcc_home_dir);
 
111
        mkdir(dbname, 00644);
 
112
    
 
113
        sprintf(dbname,"%s/.rcc/libtranslate.db/",rcc_home_dir);
 
114
        mkdir(dbname, 00644);
 
115
 
 
116
        db4ctx = rccDb4CreateContext(dbname, 0);
 
117
        free(dbname);
 
118
    }
 
119
    if (db4ctx) {
 
120
        mutex = g_mutex_new();
 
121
        cond = g_cond_new();
 
122
        if ((mutex)&&(cond))
 
123
            queue = g_queue_new();
 
124
        if (queue)
 
125
            thread = g_thread_create(rccLibPostponed, NULL, TRUE, NULL);
 
126
    }
 
127
#endif /* HAVE_LIBTRANSLATE */
 
128
 
 
129
    return 0;
 
130
}
 
131
 
 
132
void rccLibTranslateFree() {
 
133
#ifdef HAVE_LIBTRANSLATE
 
134
    char *ptr;
 
135
    if  (session) {
 
136
        if (thread) {
 
137
            exitflag = 1;
 
138
            g_cond_signal(cond);
 
139
            g_thread_join(thread);
 
140
            thread = NULL;
 
141
            exitflag = 0;
 
142
        }
 
143
        if (queue) {
 
144
            do {
 
145
                ptr = g_queue_pop_head(queue);
 
146
                if (ptr) free(ptr);
 
147
            } while (ptr);
 
148
            g_queue_free(queue);
 
149
            queue = NULL;
 
150
        }
 
151
        if (mutex) {
 
152
            g_mutex_free(mutex);
 
153
            mutex = NULL;
 
154
        }
 
155
        if (cond) {
 
156
            g_cond_free(cond);
 
157
            cond = NULL;
 
158
        }
 
159
        if (db4ctx) rccDb4FreeContext(db4ctx);
 
160
        g_object_unref(session);
 
161
        session = NULL;
 
162
    }
 
163
#endif /* HAVE_LIBTRANSLATE */
 
164
}
 
165
 
 
166
 
 
167
static char *rccLibTranslateDo(const char *from, const char *to, const char *text, unsigned long timeout) {
 
168
#ifdef HAVE_LIBTRANSLATE
 
169
    char *result;
 
170
    char *key = NULL;
 
171
    size_t keysize;
 
172
    
 
173
    if ((!session)||(!from)||(!to)||(!text)) return NULL;
 
174
    if ((strlen(from)!=2)||(strlen(to)!=2)) return NULL;
 
175
 
 
176
    if (db4ctx) {
 
177
        key = rccCreateKey(from,to,text,&keysize);
 
178
        if (key) {
 
179
            result = rccDb4GetKey(db4ctx, key, keysize);
 
180
            if (result) {
 
181
                free(key);
 
182
                return result;
 
183
            }
 
184
        }
 
185
    }
 
186
# ifdef HAVE_LIBTRANSLATE_TIMED_TRANSLATE    
 
187
    result = translate_session_timed_translate_text(session, text, from, to, timeout, NULL, NULL, NULL);
 
188
# else
 
189
    result = translate_session_translate_text(session, text, from, to, NULL, NULL, NULL);
 
190
# endif /* HAVE_LIBTRANSLATE_TIMED_TRANSLATE */
 
191
    
 
192
    if ((db4ctx)&&(key)) {
 
193
        if (result) {
 
194
            rccDb4SetKey(db4ctx, key, keysize, result);
 
195
            free(key);
 
196
        }
 
197
        else {
 
198
            g_mutex_lock(mutex);
 
199
            g_queue_push_tail(queue, key);
 
200
            g_mutex_unlock(mutex);
 
201
            g_cond_signal(cond);
 
202
        }
 
203
    }
 
204
 
 
205
    return result;
 
206
#else
 
207
    return NULL;
 
208
#endif /* HAVE_LIBTRANSLATE */
 
209
}
 
210
 
 
211
 
 
212
void *rccLibTranslate(void *info) {
 
213
    int s;
 
214
#ifdef HAVE_LIBTRANSLATE
 
215
    unsigned char connected = 1;
 
216
    rcc_translate_prefix_s prefix;
 
217
    ssize_t readed, writed, res;
 
218
    char *buffer;
 
219
    size_t size;
 
220
    char *translated = NULL;
 
221
#endif /* HAVE_LIBTRANSLATE */
 
222
 
 
223
    if (!info) return NULL;
 
224
    
 
225
    s = ((rcc_external_info)info)->s;
 
226
    free(info);
 
227
    
 
228
#ifdef HAVE_LIBTRANSLATE
 
229
    while (connected) {
 
230
        readed = read(s, &prefix, sizeof(rcc_translate_prefix_s)-1);
 
231
        if ((readed<=0)||(readed != (sizeof(rcc_translate_prefix_s)-1))) break;
 
232
 
 
233
        switch (prefix.cmd.cmd) {
 
234
            case RCC_EXTERNAL_COMMAND_CLOSE:
 
235
                connected = 0;
 
236
            break;
 
237
            case RCC_EXTERNAL_COMMAND_TRANSLATE:
 
238
                size = 1 + prefix.cmd.size + sizeof(rcc_external_command_s) - sizeof(rcc_translate_prefix_s);
 
239
                buffer = (char*)malloc(size);
 
240
                if (buffer) {
 
241
                    for (readed = 0; (readed < size)&&(connected); readed += res) {
 
242
                        res = read(s, buffer + readed, size - readed);
 
243
                        if (res<=0) connected = 0;
 
244
                    }
 
245
                    
 
246
                    prefix.cmd.cmd = 0;
 
247
                    prefix.cmd.size = 0;
 
248
                    
 
249
                    if ((prefix.from[2])||(prefix.to[2])||(buffer[readed-1])) goto respond;
 
250
                    
 
251
                    translated = rccLibTranslateDo(prefix.from, prefix.to, buffer, prefix.timeout);
 
252
                    if (translated) {
 
253
                        prefix.cmd.cmd = RCC_EXTERNAL_COMMAND_TRANSLATE;
 
254
                        prefix.cmd.size = strlen(translated) + 1;
 
255
                    }
 
256
                    
 
257
respond:
 
258
                    res = write(s, &prefix.cmd, sizeof(rcc_external_command_s));
 
259
                    if (res == sizeof(rcc_external_command_s)) {
 
260
                        for (writed = 0; (writed < prefix.cmd.size)&&(connected); writed += res) {
 
261
                            res = write(s, translated + writed, prefix.cmd.size - writed);
 
262
                            if (res<=0) connected = 0;
 
263
                        }
 
264
                    } else connected = 0;
 
265
                    
 
266
                    if (prefix.cmd.size) free(translated);                  
 
267
                    free(buffer);
 
268
                } else connected = 0;
 
269
            break;
 
270
            default:
 
271
                buffer = (char*)malloc(prefix.cmd.size);
 
272
                if (buffer) {
 
273
                    for (readed = 0; (readed < prefix.cmd.size)&&(connected); readed += res) {
 
274
                        res = read(s, buffer + readed, prefix.cmd.size - readed);
 
275
                        if (res<=0) connected = 0;
 
276
                    }
 
277
                    free(buffer);
 
278
                } else connected = 0;
 
279
        }
 
280
    }    
 
281
#endif /* HAVE_LIBTRANSLATE */
 
282
    
 
283
    close(s);
 
284
    return NULL;
 
285
}
 
286