summaryrefslogtreecommitdiffstats
path: root/src/rcctranslate.c
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@dside.dyndns.org>2005-08-03 01:48:35 +0000
committerSuren A. Chilingaryan <csa@dside.dyndns.org>2005-08-03 01:48:35 +0000
commitdcd966ba50fa18853c5ae06125a5b08b0ee6b10d (patch)
tree8147928dbe65fc6b4d83e5cc15d1b3ac5993e0eb /src/rcctranslate.c
parent8b75f9bb6a09d54d634ff661655659951378aa2c (diff)
downloadlibrcc-dcd966ba50fa18853c5ae06125a5b08b0ee6b10d.tar.gz
librcc-dcd966ba50fa18853c5ae06125a5b08b0ee6b10d.tar.bz2
librcc-dcd966ba50fa18853c5ae06125a5b08b0ee6b10d.tar.xz
librcc-dcd966ba50fa18853c5ae06125a5b08b0ee6b10d.zip
Language Fixes and Improvements
- rccmutex - Language autodetection fixes and improvements - Language translation fixes and improvements - The current state is near to be usable
Diffstat (limited to 'src/rcctranslate.c')
-rw-r--r--src/rcctranslate.c133
1 files changed, 110 insertions, 23 deletions
diff --git a/src/rcctranslate.c b/src/rcctranslate.c
index d7bb4e4..9dcf411 100644
--- a/src/rcctranslate.c
+++ b/src/rcctranslate.c
@@ -3,10 +3,12 @@
#include <string.h>
#include "internal.h"
+#include "rccconfig.h"
#include "rccexternal.h"
+#include "rccmutex.h"
#include "rcctranslate.h"
-
+#define RCC_TRANSLATE_DEFAULT_TIMEOUT 1000000 /* 1s */
int rccTranslateInit() {
@@ -26,18 +28,37 @@ rcc_translate rccTranslateOpen(const char *from, const char *to) {
translate = (rcc_translate)malloc(sizeof(rcc_translate_s));
if (!translate) return NULL;
+
+ translate->mutex = rccMutexCreate();
+ translate->wmutex = rccMutexCreate();
+ if ((!translate->mutex)||(!translate->wmutex)) {
+ if (translate->mutex) rccMutexFree(translate->mutex);
+ if (translate->wmutex) rccMutexFree(translate->wmutex);
+ free(translate);
+ return NULL;
+ }
translate->sock = rccExternalConnect(RCC_EXTERNAL_MODULE_LIBRTRANSLATE);
if (translate->sock == -1) {
+ rccMutexFree(translate->mutex);
+ rccMutexFree(translate->wmutex);
free(translate);
return NULL;
}
translate->remaining = 0;
+ translate->werror = 0;
+
translate->prefix.cmd.cmd = RCC_EXTERNAL_COMMAND_TRANSLATE;
translate->prefix.cmd.size = sizeof(rcc_translate_prefix_s);
memcpy(translate->prefix.from, from, 3*sizeof(char));
memcpy(translate->prefix.to, to, 3*sizeof(char));
+
+ translate->wprefix.cmd.cmd = RCC_EXTERNAL_COMMAND_TRANSLATE_QUEUE;
+ translate->wprefix.cmd.size = sizeof(rcc_translate_prefix_s);
+ memcpy(translate->wprefix.from, from, 3*sizeof(char));
+ memcpy(translate->wprefix.to, to, 3*sizeof(char));
+
rccTranslateSetTimeout(translate, RCC_TRANSLATE_DEFAULT_TIMEOUT);
return translate;
@@ -50,18 +71,40 @@ void rccTranslateClose(rcc_translate translate) {
#ifdef HAVE_LIBTRANSLATE
if (!translate) return;
if (translate->sock != -1) rccExternalClose(translate->sock);
+ rccMutexFree(translate->mutex);
+ rccMutexFree(translate->wmutex);
free(translate);
#endif /* HAVE_LIBTRANSLATE */
}
int rccTranslateSetTimeout(rcc_translate translate, unsigned long us) {
-#ifdef HAVE_LIBTRANSLATE_TIMED_TRANSLATE
if (!translate) return -1;
translate->prefix.timeout = us;
return 0;
-#else
- return -1;
-#endif /* HAVE_LIBTRANSLATE_TIMED_TRANSLATE */
+}
+
+#define RCC_UNLOCK_W 1
+#define RCC_UNLOCK_R 2
+#define RCC_UNLOCK_RW 3
+#define RCC_UNLOCK_WR 3
+static char *rccTranslateReturn(rcc_translate translate, char *ret, int unlock) {
+ if (unlock&RCC_UNLOCK_R) rccMutexUnLock(translate->mutex);
+ if (unlock&RCC_UNLOCK_W) rccMutexUnLock(translate->wmutex);
+ return ret;
+}
+#define rccTranslateReturnNULL(translate, unlock) rccTranslateReturn(translate, NULL, unlock)
+
+static int rccTranslateQueue(rcc_translate translate, const char *buf) {
+ size_t len, err;
+
+
+ len = strlen(buf);
+ translate->wprefix.cmd.size = sizeof(rcc_translate_prefix_s) + len - sizeof(rcc_external_command_s);
+
+ 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;
}
char *rccTranslate(rcc_translate translate, const char *buf) {
@@ -69,27 +112,57 @@ char *rccTranslate(rcc_translate translate, const char *buf) {
rcc_external_command_s resp;
size_t err, len;
char *buffer;
-/*
size_t i;
-*/
-
+
if ((!translate)||(!buf)) return NULL;
-/*
- if (!strcmp(translate->prefix.to, "en")) {
- for (i=0;buf[i];i++)
+ if (!strcmp(translate->prefix.to, rcc_english_language_sn)) {
+ for (i=0;buf[i];i++) {
if ((unsigned char)buf[i]>0x7F) break;
+ if ((buf[i]>='A')&&(buf[i]<='Z')) break;
+ if ((buf[i]>='a')&&(buf[i]<='z')) break;
+ }
if (!buf[i]) return NULL;
}
-*/
+
+ rccMutexLock(translate->wmutex);
+
+ if (rccMutexTryLock(translate->mutex)) {
+ if ((translate->werror)||(translate->sock == -1)) return rccTranslateReturnNULL(translate,RCC_UNLOCK_W);
+
+ if (rccTranslateQueue(translate, buf)) translate->werror = 1;
+ return rccTranslateReturnNULL(translate, RCC_UNLOCK_W);
+ }
+
+ if (translate->werror) {
+ rccExternalClose(translate->sock);
+ translate->sock = -1;
+ translate->werror = 0;
+ }
if (translate->sock == -1) {
translate->sock = rccExternalConnect(RCC_EXTERNAL_MODULE_LIBRTRANSLATE);
- if (translate->sock == -1) return NULL;
+ if (translate->sock == -1) {
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_RW);
+ } else {
+ translate->werror = 0;
+ translate->remaining = 0;
+ }
} else if (translate->remaining) {
if (translate->remaining == (size_t)-1) {
err = rccExternalRead(translate->sock, (char*)&resp, sizeof(rcc_external_command_s), 0);
- if (err) return NULL;
+ if (err) {
+ if (err == sizeof(rcc_external_command_s)) {
+ if (rccTranslateQueue(translate, buf)) {
+ rccExternalClose(translate->sock);
+ translate->sock = -1;
+ }
+ } else {
+ rccExternalClose(translate->sock);
+ translate->sock = -1;
+ }
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_RW);
+ }
translate->remaining = resp.size;
}
@@ -97,13 +170,18 @@ char *rccTranslate(rcc_translate translate, const char *buf) {
if (!buffer) {
rccExternalClose(translate->sock);
translate->sock = -1;
- return NULL;
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_RW);
}
+
err = rccExternalRead(translate->sock, buffer, translate->remaining, 0);
free(buffer);
if (err) {
translate->remaining = err;
- return NULL;
+ if (rccTranslateQueue(translate, buf)) {
+ rccExternalClose(translate->sock);
+ translate->sock = -1;
+ }
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_RW);
}
translate->remaining = 0;
}
@@ -114,41 +192,50 @@ char *rccTranslate(rcc_translate translate, const char *buf) {
if (err) {
rccExternalClose(translate->sock);
translate->sock = -1;
- return NULL;
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_RW);
}
err = rccExternalWrite(translate->sock, buf, len + 1, 0);
if (err) {
rccExternalClose(translate->sock);
translate->sock = -1;
- return NULL;
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_RW);
}
+ rccMutexUnLock(translate->wmutex);
err = rccExternalRead(translate->sock, (char*)&resp, sizeof(rcc_external_command_s), translate->prefix.timeout);
if (err) {
if (err == sizeof(rcc_external_command_s)) {
translate->remaining = (size_t)-1;
} else {
+ rccMutexLock(translate->wmutex);
rccExternalClose(translate->sock);
translate->sock = -1;
+ rccMutexUnLock(translate->wmutex);
}
- return NULL;
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_R);
}
- if ((resp.cmd!=RCC_EXTERNAL_COMMAND_TRANSLATE)||(!resp.size)) return NULL;
+
+ if ((resp.cmd!=RCC_EXTERNAL_COMMAND_TRANSLATE)||(!resp.size))
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_R);
buffer = (char*)malloc(resp.size*sizeof(char));
if (!buffer) {
+ rccMutexLock(translate->wmutex);
rccExternalClose(translate->sock);
translate->sock = -1;
- return NULL;
+ rccMutexUnLock(translate->wmutex);
+
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_R);
}
+
err = rccExternalRead(translate->sock, buffer, resp.size, 0);
if (err) {
translate->remaining = err;
free(buffer);
- return NULL;
+ return rccTranslateReturnNULL(translate,RCC_UNLOCK_R);
}
- return buffer;
+ return rccTranslateReturn(translate, buffer, RCC_UNLOCK_R);
#else
return NULL;
#endif /* HAVE_LIBTRANSLATE */