recoding implementation using iconv library

This commit is contained in:
Stas Degteff 2006-04-10 19:20:44 +00:00
parent 0cd4980adc
commit fad4dba1fe
5 changed files with 84 additions and 3 deletions

View File

@ -81,6 +81,10 @@ EscTab* I51TP = NULL;
EscTab* MNETP = NULL; EscTab* MNETP = NULL;
ChsTab* ChsTP = NULL; ChsTab* ChsTP = NULL;
#ifdef HAS_ICONV
iconv_t iconv_cd = (iconv_t)(-1);
#endif
bool quiet = true; bool quiet = true;
bool ignore = false; bool ignore = false;
int cfgerrors = 0; int cfgerrors = 0;

View File

@ -35,6 +35,10 @@
// ------------------------------------------------------------------ // ------------------------------------------------------------------
#ifdef HAS_ICONV
#include <iconv.h>
#endif
extern glog LOG; extern glog LOG;
extern gareafile* AFILE; extern gareafile* AFILE;
@ -128,6 +132,10 @@ extern EscTab* I51TP;
extern EscTab* MNETP; extern EscTab* MNETP;
extern ChsTab* ChsTP; extern ChsTab* ChsTP;
#ifdef HAS_ICONV
extern iconv_t iconv_cd;
#endif
//extern char gversion[]; //extern char gversion[];
extern bool quiet; extern bool quiet;

View File

@ -34,6 +34,10 @@
#include <malloc.h> #include <malloc.h>
#endif #endif
#ifdef HAS_ICONV
#include <iconv.h>
#endif
// ------------------------------------------------------------------ // ------------------------------------------------------------------
@ -1731,12 +1735,29 @@ void Latin2Local(std::string &str)
str = temp; str = temp;
} }
// ------------------------------------------------------------------
#ifdef HAS_ICONV
void IconvClear(void){
if( iconv_cd!=(iconv_t)(-1) ){
iconv_close(iconv_cd);
iconv_cd = (iconv_t)(-1);
}
}
#endif
// ------------------------------------------------------------------ // ------------------------------------------------------------------
char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded, bool i51) { char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded, bool i51) {
if(not chrtbl) if( src==NULL )
return dest;
if( not chrtbl
#ifdef HAS_ICONV
&& iconv_cd==(iconv_t)(-1)
#endif
)
return stpcpy(dest, src); return stpcpy(dest, src);
uint n; uint n;
@ -1749,6 +1770,12 @@ char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded
char dochar; char dochar;
ChsTab* chrs = chrtbl ? chrtbl->t : (ChsTab*)NULL; ChsTab* chrs = chrtbl ? chrtbl->t : (ChsTab*)NULL;
#ifdef HAS_ICONV
size_t iconvrc=-1;
if( iconv_cd!=(iconv_t)(-1) ){
iconvrc=iconv( iconv_cd, NULL, NULL, NULL, NULL ); // init iconv
}
#endif
while(*sptr) { while(*sptr) {
switch(*sptr) { switch(*sptr) {
case 0x02: case 0x02:
@ -1858,6 +1885,31 @@ char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded
dochar = *sptr++; dochar = *sptr++;
chardo: chardo:
// Translate level 1 and 2 // Translate level 1 and 2
#ifdef HAS_ICONV
if( iconv_cd!=(iconv_t)(-1) ){
unsigned srcleft=1;
unsigned dstleft=3;
char* tsptr = &dochar;
iconvrc=iconv( iconv_cd, &tsptr, &srcleft, &dptr, &dstleft );
if( iconvrc==((size_t)-1) ){
switch( errno ){
case EINVAL:
LOG.printf("An incomplete multibyte sequence has been encountered before:");
LOG.printf("%s",sptr);
case EILSEQ:
LOG.printf("An invalid multibyte sequence has been encountered in the input before:");
LOG.printf("%s",sptr);
case E2BIG:
LOG.printf("There is not sufficient destination size before '%s'", sptr);
default:
LOG.printf("Unknown error %u in iconv() before %s", errno, sptr);
}
}
}
else
#endif
if (((level == 1) || (level == 2)) && chrs) if (((level == 1) || (level == 2)) && chrs)
{ {
tptr = (char*)chrs[(byte)dochar]; tptr = (char*)chrs[(byte)dochar];
@ -2968,6 +3020,16 @@ int LoadCharset(const char* imp, const char* exp, int query) {
break; break;
} }
#ifdef HAS_ICONV
if( iconv_cd != (iconv_t)(-1) )
iconv_close(iconv_cd);
iconv_cd = iconv_open(imp,exp);
if(iconv_cd != (iconv_t)(-1) )
LOG.printf("iconv is initialised to convert from %s to %s", imp, exp);
else
LOG.printf("Can't initialise iconv to convert from %s to %s", imp, exp);
#endif
// Find and load charset table // Find and load charset table
std::vector<Map>::iterator xlt; std::vector<Map>::iterator xlt;
for(n = 0, xlt = CFG->xlatcharset.begin(); xlt != CFG->xlatcharset.end(); xlt++, n++) for(n = 0, xlt = CFG->xlatcharset.begin(); xlt != CFG->xlatcharset.end(); xlt++, n++)

View File

@ -186,7 +186,10 @@ char* XlatStr(char* dest, const char* src, int level, Chs* chrtbl, int qpencoded
char* mime_header_decode(char* decoded, const char* encoded, char* charset = NULL); char* mime_header_decode(char* decoded, const char* encoded, char* charset = NULL);
char* strxmimecpy(char* dest, const char* source, int level, int size, bool detect = false); char* strxmimecpy(char* dest, const char* source, int level, int size, bool detect = false);
void InvalidateControlInfo(GMsg *msg); void InvalidateControlInfo(GMsg *msg);
#ifdef HAS_ICONV
void IconvClear(void);
#endif
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// GEMENU prototypes // GEMENU prototypes
@ -444,7 +447,7 @@ uint32_t getClassicMsgId();
// ------------------------------------------------------------------ // ------------------------------------------------------------------
// SOFTCR management // SOFTCR management
inline bool issoftcr(char c) inline bool issoftcr(char c)
{ {
return (c == SOFTCR) and not WideDispsoftcr; return (c == SOFTCR) and not WideDispsoftcr;

View File

@ -1041,6 +1041,10 @@ void Reader() {
// Invalidate reader_msg since the actual data has just been freed. // Invalidate reader_msg since the actual data has just been freed.
reader_msg = NULL; reader_msg = NULL;
#ifdef HAS_ICONV
IconvClear();
#endif
HandleGEvent(EVTT_EXIT); HandleGEvent(EVTT_EXIT);
} }