The attached patch implements a UTF-16 to ISO 8859-1 converter (by replacing characters > 0xff with a '?'). It allows to read the text surrounding the "special" characters. Life would be easier if Licq kept everything in UTF-8...
Daniel
diff -rwud licq/include/licq_translate.h xlicq/include/licq_translate.h --- licq/include/licq_translate.h Sun Oct 24 17:56:58 2004 +++ xlicq/include/licq_translate.h Sun Jan 23 22:39:22 2005 @@ -30,6 +30,7 @@ // Muse use delete[] on the returned value if it is not NULL char *ToUnicode(char *_sz); char *FromUnicode(char *_sz); + char *FromUTF16(char *_sz, unsigned short nLen); char *NToRN(const char* _szOldStr); char *RNToN(const char* _szOldStr); bool utf16to8(unsigned long c, string &s); diff -rwud licq/src/icqd-srv.cpp xlicq/src/icqd-srv.cpp --- licq/src/icqd-srv.cpp Wed Jan 19 22:03:01 2005 +++ xlicq/src/icqd-srv.cpp Sun Jan 23 22:42:49 2005 @@ -2695,8 +2695,8 @@ CBuffer msgTxt = msg.UnpackTLV(0x0101); nMsgLen = msgTxt.getDataSize(); - unsigned short nEncoding = msgTxt.UnpackUnsignedShort(); - nSubEncoding = msgTxt.UnpackUnsignedShort(); + unsigned short nEncoding = msgTxt.UnpackUnsignedShortBE(); + nSubEncoding = msgTxt.UnpackUnsignedShortBE(); nMsgLen -= 4; @@ -2706,10 +2706,10 @@ szMessage[nMsgLen] = '\0'; char* szMsg = 0; - if (nEncoding == 2) // utf-8 or utf-16? + if (nEncoding == 2) // utf-16! { char *szTmpMsg = 0; - szTmpMsg = gTranslator.FromUnicode(szMessage); + szTmpMsg = gTranslator.FromUTF16(szMessage, nMsgLen); szMsg = gTranslator.RNToN(szTmpMsg); delete [] szTmpMsg; } diff -rwud licq/src/translate.cpp xlicq/src/translate.cpp --- licq/src/translate.cpp Sun Oct 24 17:57:01 2004 +++ xlicq/src/translate.cpp Sun Jan 23 22:38:10 2005 @@ -253,6 +253,44 @@ return szNewStr; } + +//-----FromUTF16-------------------------------------------------------------- +char *CTranslator::FromUTF16(char *_sz, unsigned short nLen) +{ + if (_sz == NULL) return NULL; + unsigned int j, n = nLen/2; + char *szNewStr = new char[n + 1]; + unsigned char *p = (unsigned char *)_sz; + + for (unsigned int i = j = 0; i < n; i++) + { + int nChar; + + if ((p[0]&0xFC) != 0xD8) { + nChar = (p[0]<<8)+p[1]; + p += 2; + } else { + i++; + if(i == n || (p[2]&0xFC) != 0xDC) { + gLog.Error("%sString is not UTF-16BE.\n", L_ERRORxSTR); + break; + } + + nChar = ((p[0]&0x3)<<18)+(p[1]<<10)+((p[2]&0x3)<<8)+p[3]+0x10000; + p += 4; + } + + if (nChar > 0xFF) { + szNewStr[j++] = '?'; // discard those beautiful characters... + } else + szNewStr[j++] = (char)nChar; + } + + szNewStr[j] = '\0'; + return szNewStr; +} + + bool CTranslator::utf16to8(unsigned long c, string &s) { if (c <= 0x7F)
pgpakdKxCtLbJ.pgp
Description: PGP signature