/* 
   Unix SMB/Netbios implementation.
   Version 1.9.
   Kanji Extensions
   Copyright (C) Andrew Tridgell 1992-1998
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   Adding for Japanese language by <fujita@ainix.isac.co.jp> 1994.9.5
     and extend coding system to EUC/SJIS/JIS/HEX at 1994.10.11
     and add all jis codes sequence type at 1995.8.16
     Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp>

     Patched by Daisuke Taruki<daicyan@osa.att.ne.jp>
*/



#define euc_kana (0x8e)
#define is_euc_kana(c) (((unsigned char) (c)) == euc_kana)
#define is_euc(c)  (0xa0 < ((unsigned char) (c)) && ((unsigned char) (c)) < 0xff)


/* FOR SHIFT JIS CODE */
#define is_shift_jis(c) \
    ((0x81 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0x9f) \
     || (0xe0 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xef))
#define is_shift_jis2(c) \
    (0x40 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xfc \
    && ((unsigned char) (c)) != 0x7f)
#define is_kana(c) ((0xa0 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0xdf))


char cvtbuf[1024];

int euc2sjis (int hi, int lo)
{
    if (hi & 1)
      return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) |
	(lo - (lo >= 0xe0 ? 0x60 : 0x61));
    else
      return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2);
}

int sjis2euc (int hi, int lo)
{
    if (lo >= 0x9f)
      return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2);
    else
      return ((hi * 2 - (hi >= 0xe0 ? 0xe1 : 0x61)) << 8) |
	(lo + (lo >= 0x7f ? 0x60 : 0x61));
}

/* Convert to Shift-JIS to EUC */
char *sj_to_euc(char *from)
{
    char *out;
    char *save;

    save = (char *) from;
    for (out = cvtbuf; *from;) {
      if (is_shift_jis (*from)) {
            int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
            *out++ = (code >> 8) & 0xff;
            *out++ = code;
            from += 2;
      } else if (is_kana (*from)) {
            *out++ = (char)euc_kana;
            *out++ = *from++;
      } else {
            *out++ = *from++;
      }
    }
    *out = 0;
    return cvtbuf;
}

/* Convert EUC to Shift-JIS */
char *euc_to_sj(char *from)
{
    char *out;
    char *save;

    save = (char *) from;
    for (out = cvtbuf; *from; ) {
      if (is_euc (*from)) {
            int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
            *out++ = (code >> 8) & 0xff;
            *out++ = code;
            from += 2;
      } else if (is_euc_kana (*from)) {
            *out++ = from[1];
            from += 2;
      } else {
            *out++ = *from++;
      }
    }
    *out = 0;
    return cvtbuf;
}
