--- src/common/jcode.c.fix-incoming-hankaku-kana-messages	Fri Apr  5 12:49:38 2002
+++ src/common/jcode.c	Sun Jun 15 08:01:20 2003
@@ -294,83 +294,272 @@
 char *
 kanji_conv_to_locale(char *str)
 {
-   static char *jpcode = NULL;
-   static char *locale_euc[]  = { JCODE_LOCALE_EUC, NULL };
-   /*static char *locale_jis[]  = { JCODE_LOCALE_JIS, NULL };*/
-   static char *locale_sjis[] = { JCODE_LOCALE_SJIS, NULL };
-
-   static struct LOCALE_TABLE {
-       char *code;
-       char **name_list;
-   } locale_table[] = { 
-       {"EUC-JP", locale_euc},
-       {"ISO-2022-JP", locale_sjis},
-       {"SJIS", locale_sjis}
-   };
-
-   if(!str)
-       return NULL;
-
-   if(jpcode == NULL) {
-       char *ctype = setlocale(LC_CTYPE, "");
-       int i, j;
-       for( j=0; jpcode == NULL && 
-                j < sizeof(locale_table)/sizeof(struct LOCALE_TABLE); j++ ) {
-           char **name = locale_table[j].name_list;
-           for( i=0; name[i]; i++ )
-               if (strcasecmp(ctype, name[i]) == 0) {
-                   jpcode = locale_table[j].code;
-                   break;
-               }
-       }
-       if(jpcode == NULL)
-           jpcode = locale_table[1].code;
-   }
-   
-   return kanji_conv_auto(str, jpcode);
-}
+/* ISO-2022-JP + broken hankaku-kana --> EUC-JP
+ * these codes derive from Mozilla.
+ */
+/* ***** BEGIN LICENSE BLOCK *****
+ * These codes are subject to the GNU General Public License Version
+ * 2.0; you may not use this file except in The Original Code is
+ * Mozilla Communicator client code.
+ *
+ * The Initial Developer of the Original Code is 
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ * ***** END LICENSE BLOCK ***** */
+  int srcLen = strlen(str);
+  const unsigned char* src =(unsigned char*)str;
+  const unsigned char* srcEnd = (unsigned char*)str + srcLen;
 
-char *
-kanji_conv(char *str, const char *dstset, const char *srcset)
-{
-    unsigned char *buf, *ret;
-    iconv_t cd;
-    size_t insize = 0;
-    size_t outsize = 0;
-    size_t nconv = 0;
-    char *inptr;
-    char *outptr;
-    
-    if(!str)
-        return NULL;
-    
-    buf = (unsigned char *)malloc(strlen(str) * 4 + 1);
-    if(!buf)
-        return NULL;
-    
-    insize = strlen(str);
-    inptr = str;
-    outsize = strlen(str) * 4 ;
-    outptr = buf;
-    
-    cd = iconv_open (dstset, srcset);
-    if(cd == (iconv_t) -1) {
-        if(errno == EINVAL)
-            return strdup(str);
-    }
-    
-    nconv = iconv (cd, (const char **)&inptr, &insize, &outptr, &outsize);
-    if (nconv == (size_t) -1) {
-        if(errno == EINVAL)
-            memmove (buf, inptr, insize);
-    } else
-       iconv (cd, NULL, NULL, &outptr, &outsize);
-    
-    *outptr = '\0';
-    iconv_close(cd);
-    
-    ret = strdup(buf);
-    free(buf);
-    
-    return ret;
+  const char* msg1 = " <broken_string>";
+  const char* msg2 = " <unexpected_code>";
+  int destLen = srcLen * 2 + 1;
+  unsigned char* dest = (unsigned char *)malloc(destLen + strlen(msg2));
+  unsigned char* destEnd = dest + destLen;
+  const unsigned char* destBegin = dest;
+  unsigned char mData;
+
+  enum {
+   mState_ASCII,
+   mState_ESC,
+   mState_ESC_28,
+   mState_ESC_24,
+   mState_ESC_24_28,
+   mState_JISX0201_1976Roman,
+   mState_JISX0201_1976Kana,
+   mState_JISX0208_1978,
+   mState_GB2312_1980,
+   mState_JISX0208_1983,
+   mState_KSC5601_1987,
+   mState_JISX0212_1990,
+   mState_JISX0208_1978_2ndbyte,
+   mState_GB2312_1980_2ndbyte,
+   mState_JISX0208_1983_2ndbyte,
+   mState_KSC5601_1987_2ndbyte,
+   mState_JISX0212_1990_2ndbyte,
+   mState_ESC_2e,
+   mState_ESC_4e,
+   mState_ERROR
+  } mState, mLastLegalState;
+  int shiftState = 0;
+
+  mState = mState_ASCII;
+  mLastLegalState = mState_ASCII;
+
+  while ((src < srcEnd)) {
+    switch (mState) {
+    case mState_ASCII:
+      if(0x1b == *src) {
+	mLastLegalState = mState;
+	mState = mState_ESC;
+      } else if(*src & 0x80) {
+	goto error2;
+      } else {
+	*dest++ = *src;
+	if(dest >= destEnd)
+	  goto error1;
+      }
+      break;
+          
+    case mState_ESC:
+      if( '(' == *src) {
+	mState = mState_ESC_28;
+      } else if ('$' == *src)  {
+	mState = mState_ESC_24;
+      } else  {
+	if((dest+2) >= destEnd)
+	  goto error1;
+	*dest++ = 0x1b;
+	if(0x80 & *src)
+	  goto error2;
+	*dest++ = *src;
+	mState = mLastLegalState;
+      }
+      break;
+
+    case mState_ESC_28: /* ESC ( */
+      if( 'B' == *src) {
+	mState = mState_ASCII;
+      } else if ('J' == *src)  {
+	mState = mState_JISX0201_1976Roman;
+      } else if ('I' == *src)  {
+	mState = mState_JISX0201_1976Kana;
+      } else  {
+	if((dest+3) >= destEnd)
+	  goto error1;
+	*dest++ = 0x1b;
+	*dest++ = '(';
+	if(0x80 & *src)
+	  goto error2;
+	*dest++ = *src;
+	mState = mLastLegalState;
+      }
+      break;
+
+    case mState_ESC_24: /* ESC $ */
+      if( '@' == *src) {
+	mState = mState_JISX0208_1978;
+      } else if ('A' == *src)  {
+	mState = mState_GB2312_1980;
+      } else if ('B' == *src)  {
+	mState = mState_JISX0208_1983;
+      } else if ('(' == *src)  {
+	mState = mState_ESC_24_28;
+      } else  {
+	if((dest+3) >= destEnd)
+	  goto error1;
+	*dest++ = 0x1b;
+	*dest++ = '$';
+	if(0x80 & *src)
+	  goto error2;
+	*dest++ = *src;
+	mState = mLastLegalState;
+      }
+      break;
+
+    case mState_ESC_24_28: /* ESC $ ( */
+      if( 'C' == *src) {
+	mState = mState_KSC5601_1987;
+      } else if ('D' == *src) {
+	mState = mState_JISX0212_1990;
+      } else  {
+	if((dest+4) >= destEnd)
+	  goto error1;
+	*dest++ = 0x1b;
+	*dest++ = '$';
+	*dest++ = '(';
+	if(0x80 & *src)
+	  goto error2;
+	*dest++ = *src;
+	mState = mLastLegalState;
+      }
+      break;
+
+    case mState_JISX0201_1976Roman:
+      if(0x1b == *src) {
+	mLastLegalState = mState;
+	mState = mState_ESC;
+      } else if(*src == 0x0E) { /* SO */
+	shiftState = 1;
+      } else if(*src == 0x0F) { /* SI */
+	shiftState = 0;
+      } else if(*src & 0x80) {
+	/* Japanese IRC conventional code*/
+	*dest++ = 0x8e;
+	*dest++ = *src;
+      } else {
+	/* XXX We need to  decide how to handle \ and ~ here
+	   we may need a if statement here for '\' and '~' 
+	   to map them to Yen and Overbar */
+	if(shiftState == 1) {
+	  /* Japanese IRC conventional code*/
+	  *dest++ = 0x8e;
+	  *dest++ = *src | 0x80;
+	} else {
+	  *dest++ = *src;
+	}
+	if(dest >= destEnd)
+	  goto error1;
+      }
+      break;
+
+    case mState_JISX0201_1976Kana:
+      if(0x1b == *src) {
+	mLastLegalState = mState;
+	mState = mState_ESC;
+      } else {
+	if((0x21 <= *src) && (*src <= 0x5F)) {
+	  *dest++ = 0x8e;
+	  *dest++ = *src;
+	} else {
+	  goto error2;
+	}
+	if(dest >= destEnd)
+	  goto error1;
+      }
+      break;
+
+    case mState_JISX0208_1978:
+      if(0x1b == *src) {
+	mLastLegalState = mState;
+	mState = mState_ESC;
+      } else if(*src & 0x80) {
+	mLastLegalState = mState;
+	mState = mState_ERROR;
+      } else {
+	mData = 0x80 | *src;
+	mState = mState_JISX0208_1978_2ndbyte;
+      }
+      break;
+
+    case mState_JISX0208_1983:
+      if(0x1b == *src) {
+	mLastLegalState = mState;
+	mState = mState_ESC;
+      } else if(*src & 0x80) {
+	mLastLegalState = mState;
+	mState = mState_ERROR;
+      } else {
+	mData = 0x80 | *src;
+	mState = mState_JISX0208_1983_2ndbyte;
+      }
+      break;
+
+    case mState_JISX0212_1990:
+      if(0x1b == *src) {
+	mLastLegalState = mState;
+	mState = mState_ESC;
+      } else if(*src & 0x80) {
+	mLastLegalState = mState;
+	mState = mState_ERROR;
+      } else {
+	mData = 0x80 | *src;
+	mState = mState_JISX0212_1990_2ndbyte;
+      }
+      break;
+
+    case mState_JISX0208_1978_2ndbyte:
+      *dest++ = mData;
+      *dest++ = 0x80 | *src;
+      if(dest >= destEnd)
+	goto error1;
+      mState = mState_JISX0208_1978;
+      break;
+
+    case mState_JISX0208_1983_2ndbyte:
+      *dest++ = mData;
+      *dest++ = 0x80 | *src;
+      if(dest >= destEnd)
+	goto error1;
+      mState = mState_JISX0208_1983;
+      break;
+
+    case mState_JISX0212_1990_2ndbyte:
+      *dest++ = mData;
+      *dest++ = 0x80 | *src;
+      if(dest >= destEnd)
+	goto error1;
+      mState = mState_JISX0212_1990;
+      break;
+
+    case mState_ERROR:
+      mState = mLastLegalState;
+      goto error2;
+      break;
+
+    } /* switch */
+    src++;
+  }
+  *dest++ = '\0';
+  return destBegin;
+
+ error1:
+  *dest++ = '\0';
+  strcat(destBegin, msg1);
+  return (char*)destBegin;
+  
+ error2:
+  *dest++ = '\0';
+  strcat(destBegin, msg2);
+  return (char*)destBegin;
 }
