Logo Search packages:      
Sourcecode: canna version File versions  Download package

kana.c

/* Copyright 1994 NEC Corporation, Tokyo, Japan.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without
 * fee, provided that the above copyright notice appear in all copies
 * and that both that copyright notice and this permission notice
 * appear in supporting documentation, and that the name of NEC
 * Corporation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior
 * permission.  NEC Corporation makes no representations about the
 * suitability of this software for any purpose.  It is provided "as
 * is" without express or implied warranty.
 *
 * NEC CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN 
 * NO EVENT SHALL NEC CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 
 * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 
 * OTHER TORTUOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
 * PERFORMANCE OF THIS SOFTWARE. 
 */

#if !defined(lint) && !defined(__CODECENTER__)
static char rcsid[]="@(#) 102.1 $Id: kana.c,v 1.2 2003/09/17 08:50:52 aida_s Exp $";
#endif

/* LINTLIBRARY */
#include    "RKintern.h"

#define SUUJI_THROUGH         0
#define SUUJI_HANKAKU         1
#define SUUJI_ZENKAKU         2
#define SUUJI_SIMPLEKANJI     3
#define SUUJI_FULLKANJI       4
#define SUUJI_FULLKANJITRAD   5
#define SUUJI_WITHKANJIUNIT   6
#define SUUJI_WITHCOMMA       7

/* RkCvtZen
 *    hankaku moji wo zenkaku moji ni suru 
 */
static
Wchar
hiragana[] = 
{
/* 0x00 */
      0x0000,     0x0000, 0x0000, 0x0000,       0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/* 0x10 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/* 0x20 */
      0xa1a1, 0xa1aa, 0xa1ed, 0xa1f4,           0xa1f0, 0xa1f3, 0xa1f5, 0xa1c7,
      0xa1ca, 0xa1cb, 0xa1f6, 0xa1dc,           0xa1a4, 0xa1dd, 0xa1a5, 0xa1bf,
/* 0x30 */
      0xa3b0, 0xa3b1, 0xa3b2, 0xa3b3,           0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7,
      0xa3b8, 0xa3b9, 0xa1a7, 0xa1a8,           0xa1e3, 0xa1e1, 0xa1e4, 0xa1a9,
/* 0x40 */
      0xa1f7, 0xa3c1, 0xa3c2, 0xa3c3,           0xa3c4, 0xa3c5, 0xa3c6, 0xa3c7,
      0xa3c8, 0xa3c9, 0xa3ca, 0xa3cb,           0xa3cc, 0xa3cd, 0xa3ce, 0xa3cf,
/* 0x50 */
      0xa3d0, 0xa3d1, 0xa3d2, 0xa3d3,           0xa3d4, 0xa3d5, 0xa3d6, 0xa3d7,
      0xa3d8, 0xa3d9, 0xa3da, 0xa1ce,           0xa1ef, 0xa1cf, 0xa1b0, 0xa1b2,
/* 0x60 */
      0xa1c6, 0xa3e1, 0xa3e2, 0xa3e3,           0xa3e4, 0xa3e5, 0xa3e6, 0xa3e7,
      0xa3e8, 0xa3e9, 0xa3ea, 0xa3eb,           0xa3ec, 0xa3ed, 0xa3ee, 0xa3ef,
/* 0x70 */
      0xa3f0, 0xa3f1, 0xa3f2, 0xa3f3,           0xa3f4, 0xa3f5, 0xa3f6, 0xa3f7,
      0xa3f8, 0xa3f9, 0xa3fa, 0xa1d0,           0xa1c3, 0xa1d1, 0xa1c1, 0xa2a2,
/*0x80 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x90 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0xa0 */
      0xa1a1, 0xa1a3, 0xa1d6, 0xa1d7,           0xa1a2, 0xa1a6, 0xa4f2, 0xa4a1,
      0xa4a3, 0xa4a5, 0xa4a7, 0xa4a9,           0xa4e3, 0xa4e5, 0xa4e7, 0xa4c3,
/*0xb0 */
      0xa1bc, 0xa4a2, 0xa4a4, 0xa4a6,           0xa4a8, 0xa4aa, 0xa4ab, 0xa4ad,
      0xa4af, 0xa4b1, 0xa4b3, 0xa4b5,           0xa4b7, 0xa4b9, 0xa4bb, 0xa4bd,
/*0xc0 */
      0xa4bf, 0xa4c1, 0xa4c4, 0xa4c6,           0xa4c8, 0xa4ca, 0xa4cb, 0xa4cc,
      0xa4cd, 0xa4ce, 0xa4cf, 0xa4d2,           0xa4d5, 0xa4d8, 0xa4db, 0xa4de,
/*0xd0 */
      0xa4df, 0xa4e0, 0xa4e1, 0xa4e2,           0xa4e4, 0xa4e6, 0xa4e8, 0xa4e9,
      0xa4ea, 0xa4eb, 0xa4ec, 0xa4ed,           0xa4ef, 0xa4f3, 0xa1ab, 0xa1ac,
/* 0xe0 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/* 0xf0 */
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
};

static
Wchar 
hankaku[] = {
/*0x00*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x10*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x20*/
      0x0000,    ' ', 0x8ea4, 0x8ea1,              ',',    '.', 0x8ea5,    ':',
         ';',    '?',    '!', 0x8ede,           0x8edf, 0x0000, 0x0000, 0x0000,
/*0x30*/
         '^', 0x0000,    '_', 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x8eb0, 0x0000, 0x0000,    '/',
/*0x40*/
      0x0000,    '~', 0x0000,    '|',           0x0000, 0x0000,   '\'',   '\'',
         '"',    '"',    '(',    ')',              '[',    ']',    '[',    ']',
/*0x50*/
      '{',    '}', 0x0000, 0x0000,        0x0000, 0x0000, 0x8ea2, 0x8ea3,
      0x0000, 0x0000, 0x0000, 0x0000,              '+',    '-', 0x0000, 0x0000,
/*0x60*/
      0x0000,    '=', 0x0000,    '<',              '>', 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000,   '\\',
/*0x70*/
          '$',0x0000, 0x0000,    '%',              '#',    '&',    '*',    '@',
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x80*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0x90*/
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
/*0xa0*/
      0x0020, 0x00a7, 0x00b1, 0x00a8,     0x00b2, 0x00a9, 0x00b3, 0x00aa,
      0x00b4, 0x00ab, 0x00b5, 0x00b6,     0xb6de, 0x00b7, 0xb7de, 0x00b8,
/*0xb0*/
      0xb8de, 0x00b9, 0xb9de, 0x00ba,     0xbade, 0x00bb, 0xbbde, 0x00bc,
      0xbcde, 0x00bd, 0xbdde, 0x00be,     0xbede, 0x00bf, 0xbfde, 0x00c0,
/*0xc0*/
      0xc0de, 0x00c1, 0xc1de, 0x00af,     0x00c2, 0xc2de, 0x00c3, 0xc3de,
      0x00c4, 0xc4de, 0x00c5, 0x00c6,     0x00c7, 0x00c8, 0x00c9, 0x00ca,
/*0xd0*/
      0xcade, 0xcadf, 0x00cb, 0xcbde,     0xcbdf, 0x00cc, 0xccde, 0xccdf,
      0x00cd, 0xcdde, 0xcddf, 0x00ce,     0xcede, 0xcedf, 0x00cf, 0x00d0,
/*0xe0*/
      0x00d1, 0x00d2, 0x00d3, 0x00ac,     0x00d4, 0x00ad, 0x00d5, 0x00ae,
      0x00d6, 0x00d7, 0x00d8, 0x00d9,     0x00da, 0x00db, 0x00dc, 0x00dc,
/*0xf0*/
      0x00b2, 0x00b4, 0x00a6, 0x00dd,           0xb3de, 0x00b6, 0x00b9, 0x0000,
      0x0000, 0x0000, 0x0000, 0x0000,           0x0000, 0x0000, 0x0000, 0x0000,
};

#ifdef OBSOLETE_RKKANA

#define     ADDCODE(dst, maxdst, count, code, length) {\
    if ( (unsigned long)(length) <= (unsigned long)(maxdst) ) {\
      (maxdst) -= (length); (count) += (length);\
      if ( (dst) ) {\
          (dst) += (length);\
          switch((length)) {\
          case 4: *--(dst) = (code)&255; (code) >>= 8;\
          case 3: *--(dst) = (code)&255; (code) >>= 8;\
          case 2: *--(dst) = (code)&255; (code) >>= 8;\
          case 1: *--(dst) = (code)&255; (code) >>= 8;\
          };\
          (dst) += (length);\
      };\
    };\
}

#else /* !OBSOLETE_RKKANA */

static int
_ADDCODE(dst, maxdst, count, code, length)
unsigned char *dst;
int maxdst, count, length;
unsigned long code;
{
  if ((unsigned long)length <= (unsigned long)maxdst) {
    maxdst -= length;
    count += length;
    if (dst) {
      dst += length;
      switch (length) {
      case 4:     *--dst = (unsigned char)code; code >>= 8;
      case 3:     *--dst = (unsigned char)code; code >>= 8;
      case 2:     *--dst = (unsigned char)code; code >>= 8;
      case 1:     *--dst = (unsigned char)code; code >>= 8;
      }
    }
    return length;
  }
  return 0;
}

#define ADDCODE(dst, maxdst, count, code, length) \
{ int llen = _ADDCODE(dst, maxdst, count, (unsigned long) code, length); \
  if (llen > 0 && (dst)) { (dst) += llen; (maxdst) -= llen; (count) += llen; }}

#endif /* !OBSOLETE_RKKANA */

#define     ADDWCODE(dst, maxdst, count, code) {\
    if ( (maxdst) > 0 ) {\
      (maxdst)-- ; (count)++ ;\
      if ( (dst) ) {\
          *(dst)++ = (code);\
      }\
    }\
}

static int
euccharlen(s, bytelen)
     unsigned char      *s;
     int          bytelen;
{
  unsigned char   ch;
  int       res = 0;

  while ((ch = *s++) && bytelen--) {
    res++;
    if (ch & 0x80) {
      if (ch == RK_SS3) {
      s++;
      bytelen--;
      }
      s++;
      bytelen--;
    }
  }
  return res;
}

/* RkCvtZen
 *    hankaku moji(ASCII+katakana) wo taiou suru zenkaku moji ni suru
 *    dakuten,handakuten shori mo okonau.
 */
int RkCvtZen pro((unsigned char *, int, unsigned char *, int));

int
RkCvtZen(zen, maxzen, han, maxhan)
     unsigned char      *zen;
     int          maxzen;
     unsigned char      *han;
     int          maxhan;
{
  unsigned char   *z = zen;
  unsigned char   *h = han;
  unsigned char   *H = han + maxhan;
  Wchar           hi, lo;
  unsigned  byte;
  int             count = 0;
  unsigned long   code;

  if ( --maxzen <= 0 )
    return count;
  while ( h < H ) {
    hi = *h++;
    byte = 2;
    if ( hi == 0x8e ) { /* hankaku katakana */
      if ( !(code = hiragana[lo = *h++]) )
      code = (hi<<8)|lo;
      byte = (code>>8) ? 2 : 1;
      if ( (code>>8) == 0xa4 ) {
      code |= 0x100;
      /* dakuten/handakuten ga tuku baai */
      if ( h + 1 < H && h[0] == 0x8e ) {
        lo = h[1];
        switch( LOMASK(code) ) {
        case 0xa6: /* u */
          if ( lo == 0xde ) code = 0xa5f4, h += 2;
          break;
          /* ha */case 0xcf: case 0xd2: case 0xd5: case 0xd8: case 0xdb:
          if ( lo == 0xdf ) {
            code += 2, h += 2;
            break;
          };
        case 0xab: case 0xad: case 0xaf: case 0xb1: case 0xb3: /* ka */
        case 0xb5: case 0xb7: case 0xb9: case 0xbb: case 0xbd: /* sa */
        case 0xbf: case 0xc1: case 0xc4: case 0xc6: case 0xc8: /* ta */
          if ( lo == 0xde ) {
            code += 1, h += 2;
            break;
          };
        };
      };
      };
    }
    else if (hi == 0x8f) {
      ADDCODE(z, maxzen, count, hi, 1);
      code = (((Wchar) h[0]) << 8) | ((Wchar) h[1]); h += 2;
      byte = 2;
    } else if ( hi & 0x80 )
      code = (hi<<8)|*h++;
    else {
      if ( !(code = hiragana[hi]) ) 
      code = hi;
      byte = (code>>8) ? 2 : 1;
    }
    ADDCODE(z, maxzen, count, code, byte);
  };
  if ( z )
    *z = 0;
  return count;
}

/* RkCvtHan
 *    zenkaku kana moji wo hankaku moji ni suru 
 */
int RkCvtHan pro((unsigned char *, int, unsigned char *, int));

int
RkCvtHan(han, maxhan, zen, maxzen)
     unsigned char      *han;
     int          maxhan;
     unsigned char      *zen;
     int          maxzen;
{
  unsigned char   *h = han;
  unsigned char   *z = zen;
  unsigned char   *Z = zen + maxzen;
  Wchar           hi, lo;
  Wchar           byte;
  int             count = 0;
  unsigned long   code;

  if ( --maxhan <= 0 )
    return 0;
  while ( z < Z ) {
    hi = *z++;
    byte = 1;
    switch(hi) {
    case    0xa1: /* kigou */
      lo = *z++;
      if ( !(code = hankaku[lo&0x7f]) )
      code = (hi<<8)|lo;
      byte = (code>>8) ? 2 : 1;
      break;
    case    0xa3: /* eisuuji */
      lo = *z++;
      if ( 0xb0 <= lo && lo <= 0xb9 ) code = (lo - 0xb0) + '0';
      else
      if ( 0xc1 <= lo && lo <= 0xda ) code = (lo - 0xc1) + 'A';
      else
        if ( 0xe1 <= lo && lo <= 0xfa ) code = (lo - 0xe1) + 'a';
        else
          code = (hi<<8)|lo, byte = 2;
      break;
    case    0xa4: /* hiragana */
    case    0xa5: /* katakana */
      lo = *z++;
      if ( (code = hankaku[lo]) &&
        (lo <= (Wchar)(hi == 0xa4 ? 0xf3 : 0xf6)) ) {
      if ( code>>8 ) {
        code = 0x8e000000|((code>>8)<<16)|0x00008e00|LOMASK(code);
        byte = 4;
      }
      else {
        code = 0x00008e00|LOMASK(code);
        byte = 2;
      };
      }
      else
      code = (hi<<8)|lo, byte = 2;
      break;
    default:
      if (hi == 0x8f) {
      ADDCODE(h, maxhan, count, hi, 1);
      code = (((Wchar) z[0]) << 8) | ((Wchar) z[1]); z += 2;
      byte = 2;
      }
      else if ( hi & 0x80 ) {       /* kanji */
      code = (hi<<8)|(*z++);
      byte = 2;
      }
      else
      switch(hi) {
        /*
          case    ',':  code = 0x8ea4; byte = 2; break;
          case    '-':  code = 0x8eb0; byte = 2; break;
          case    '.':  code = 0x8ea1; byte = 2; break;
          */
      default:    code = hi; break;
      };
      break;
    };
    ADDCODE(h, maxhan, count, code, byte);
  };
  if ( h )
    *h = 0;
  return count;
}

/* RkCvtKana/RkCvtHira
 *    zenkaku hiragana wo katakana ni suru 
 */
int RkCvtKana pro((unsigned char *, int, unsigned char *, int));

int
RkCvtKana(kana, maxkana, hira, maxhira)
     unsigned char      *kana;
     int          maxkana;
     unsigned char      *hira;
     int          maxhira;
{
  unsigned char   *k = kana;
  unsigned char   *h = hira;
  unsigned char   *H = hira + maxhira;
  Wchar           hi;
  Wchar           byte;
  int             count = 0;
  unsigned long   code;

  if ( --maxkana <= 0 )
    return 0;
  while ( h < H ) {
    hi = *h++;
    if (hi == 0x8f) {
      ADDCODE(k, maxkana, count, hi, 1);
      code = (((Wchar) h[0]) << 8) | ((Wchar) h[1]); h += 2;
      byte = 2;
    }
    else if ( hi & 0x80 ) {
      int   dakuon;
      
      code = (hi == 0xa4) ? (0xa500|(*h++)) : ((hi<<8)|(*h++));
      byte = 2;
      /* hiragana U + " */
      dakuon = ( h + 1 < H && ((((Wchar) h[0])<<8)| ((Wchar) h[1])) == 0xa1ab );
      if ( hi == 0xa4 && code == 0xa5a6 && dakuon ) {
      code = 0xa5f4;
      h += 2;
      };
    } else 
      code = hi, byte = 1;
    ADDCODE(k, maxkana, count, code, byte);
  };
  if ( k )
    *k = 0;
  return count;
}

int RkCvtHira pro((unsigned char *, int, unsigned char *, int));

int
RkCvtHira(hira, maxhira, kana, maxkana)
     unsigned char      *hira;
     int          maxhira;
     unsigned char      *kana;
     int          maxkana;
{
  unsigned char   *h = hira;
  unsigned char   *k = kana;
  unsigned char   *K = kana + maxkana;
  Wchar           hi;
  Wchar           byte;
  int                   count = 0;
  unsigned long         code;
  
  if ( --maxhira <= 0 )
    return 0;
  while ( k < K ) {
    hi = *k++;
    if (hi == 0x8f) {
      ADDCODE(h, maxhira, count, hi, 1);
      code = (((Wchar) k[0]) << 8) | ((Wchar) k[1]); k += 2;
      byte = 2;
    } else if ( hi & 0x80 ) {
      code = (hi == 0xa5) ? (0xa400|(*k++)) : ((hi<<8)|(*k++));
      byte = 2;
      /* katakana U + " */
      if ( code == 0xa4f4 ) { /* u no dakuon */
      code = 0xa4a6a1ab;
      byte = 4;
      } else if ( code == 0xa4f5 ) 
      code = 0xa4ab;
      else if ( code == 0xa4f6 ) 
      code = 0xa4b1;
    } else 
      code = hi, byte = 1;
    ADDCODE(h, maxhira, count, code, byte);
  };
  if ( h )
    *h = 0;
  return count;
}

int RkCvtNone pro((unsigned char *, int, unsigned char *, int));

int
RkCvtNone(dst, maxdst, src, maxsrc)
     unsigned char      *dst;
     int          maxdst;
     unsigned char      *src;
     int          maxsrc;
{
  unsigned char   *d = dst;
  unsigned char   *s = src;
  unsigned char   *S = src + maxsrc;
  Wchar           byte;
  int             count = 0;
  unsigned long   code;
  
  if ( --maxdst <= 0 )
    return 0;
  while ( s < S ) {
    code = *s++;
    byte = 1;
    if (code == 0x8f) {
      ADDCODE(d, maxdst, count, code, 1);
      code = (((Wchar) s[0]) << 8) | ((Wchar) s[1]); s += 2;
      byte = 2;
    } else if ( code & 0x80 ) 
      code = (code<<8)|(*s++), byte = 2;
    ADDCODE(d, maxdst, count, code, byte);
  };
  if ( d )
    *d = 0;
  return count;
}

#ifdef USE_SJIS_TEXT_DIC
canna_export(int)
SJistowcs(wc_return, maxwc, sj, maxsj)
Wchar *wc_return;
int maxwc;
char *sj;
int maxsj;
{
    Wchar *e = wc_return, *ee = wc_return + maxwc;
    unsigned char *s = (unsigned char *)sj;
    unsigned char *S = (unsigned char *)sj + maxsj;
    unsigned short      hi, lo;
    unsigned short      byte;
    int           count = 0;
    unsigned long code;

    if ( --maxwc <= 0 )
      return 0;

    while ( s < S ) {
      hi = *s++;
      if ( hi <= 0x7f )                   /* ascii */
          code = hi, byte = 1;
      else 
      if ( 0xa0 <= hi && hi <= 0xdf )     /* hankaku katakana */
          code = hi, byte = 2;
        else
        if (0xf0 <= hi && hi <= 0xfc) {         /* gaiji */
            hi -= 0xf0;
            hi = 2*hi + 0x21;
            if ((lo = *s++) <= 0x9e) {
                if (lo < 0x80)
                    lo++;
                lo -= 0x20;
            }
            else {
                hi++;
                lo -= 0x7e;
            }
            code = 0x8000 | (hi<<8) | lo, byte = 3;
        }
      else {
          hi -= (hi <= 0x9f) ?  0x80 : 0xc0;
          hi = 2*hi + 0x20;
          if ( (lo = *s++) <= 0x9e ) {    /* kisuu ku */
            hi--;
            if ( 0x80 <= lo ) lo--;
            lo -= (0x40 - 0x21);
          }
          else                /* guusuu ku */
            lo -= (0x9f - 0x21);
          code = 0x8080|(hi<<8)|lo, byte = 2;
      };
      if (wc_return && e < ee) {
        *e++ = (Wchar)code;
      }
    };
    if (wc_return && e && e < ee) {
      *e = 0;
    }
    return count;
}
#endif /* USE_SJIS_TEXT_DIC */

/* RkCvtWide
 *
 */
int
RkCvtWide(dst, maxdst, src, maxsrc)
     Wchar        *dst;
     int          maxdst;
     char         *src;
     int          maxsrc;
{
#ifdef USE_SJIS_TEXT_DIC
  return SJistowcs(dst, maxdst, src, maxsrc);
#else /* !USE_SJIS_TEXT_DIC, that is, EUC */
  Wchar           *d = dst;
  unsigned char   *s = (unsigned char *)src;
  unsigned char   *S = (unsigned char *)src + maxsrc;
  int             count = 0;
  unsigned long   code;

    if ( --maxdst <= 0 )
      return count;
    while ( s < S )
    {
      code = *s++;
      if ( code & 0x80 )
      {
          switch(code)
          {
          case RK_SS2:  /* hankaku katakana */
            code = 0x0080|(s[0]&0x7f);
            s++;
            break;
          case RK_SS3:  /* gaiji */
            code = 0x8000|(((s[0]<<8)|s[1])&0x7f7f);
            s += 2;
            break;
          default:
            code = 0x8080|(((s[-1]<<8)|s[0])&0x7f7f);
                s += 1;
            };
        };
      ADDWCODE(d, maxdst, count, (Wchar)code);
    };
    if ( d )
      *d = 0;
    return count;
#endif /* !USE_SJIS_TEXT_DIC */
}

#ifdef USE_SJIS_TEXT_DIC
/* 
  Wcstosjis -- To convert Wchar string to SJIS string.

   This function should not copy after NULL character even if
   the srclen is too large
 */

static int
Wcstosjis(char *dst, int dstlen, Wchar *src, int srclen)
{
  register int i, j;
  unsigned char *sjise_kanjip, sjise_area[2];
  Wchar codeset;
  register Wchar wc;

  sjise_kanjip = sjise_area;

  for (i = 0, j = 0; src[i] != (Wchar)0 && j < dstlen && i < srclen ; i++) {
    wc = src[i];
    codeset = wc & 0x8080; /* to know what codeset is `wc' */

    switch (codeset) {
    case 0x0000: /* ASCII */
      /* continue to the following line ... */
    case 0x0080: /* Codeset 2, that is Katakana */
      if (dst) dst[j++] = (unsigned char)wc;
      break;

    case 0x8080: /* Codeset 1, that is Kanji */
      if (j + 2 > dstlen) {
      return j; /* overflow */
      }
      sjise_kanjip[0] = ((wc >> 8) & 0x7f);
      sjise_kanjip[1] = (wc & 0x7f);
      sjise_kanjip[1] = ((sjise_kanjip[0] % 2) ?
                   (sjise_kanjip[1] + 0x1f +
                    ((sjise_kanjip[1] < 0x60) ? 0 : 1)) :
                   (sjise_kanjip[1] + 0x7e));
      sjise_kanjip[0] = ((sjise_kanjip[0] < 0x5f) ?
                   ((sjise_kanjip[0] - 0x21) / 2 + 0x81) :
                   ((sjise_kanjip[0] - 0x5f) / 2 + 0xe0));
      if (dst) {
      dst[j++] = sjise_kanjip[0];
      dst[j++] = sjise_kanjip[1];
      }
      break;

    case 0x8000: /* Codeset 3 */
      if (j + 2 > dstlen) {
      return j; /* overflow */
      }
      sjise_kanjip[0] = ((wc >> 8) & 0x7f);
      sjise_kanjip[1] = (wc & 0x7fb);
      sjise_kanjip[1] = ((sjise_kanjip[0] % 2) ?
                   (sjise_kanjip[1] + 0x1f +
                    ((sjise_kanjip[1] < 0x60) ? 0 : 1)) :
                   (sjise_kanjip[1] + 0x7e));
      sjise_kanjip[0] = ((sjise_kanjip[0] - 0x21) / 2 + 0xf0);
      if (dst) {
      dst[j++] = sjise_kanjip[0];
      dst[j++] = sjise_kanjip[1];
      }
      break;
    }
  }
  if (j < dstlen && dst) {
    dst[j] = '\0';
  }
  return j;
}
#endif /* USE_SJIS_TEXT_DIC */

/* RkCvtNarrow
 *
 */
int
RkCvtNarrow(dst, maxdst, src, maxsrc)
     char         *dst;
     int          maxdst;
     Wchar        *src;
     int          maxsrc;
{
#ifdef USE_SJIS_TEXT_DIC
  return Wcstosjis(dst, maxdst, src, maxsrc);
#else /* !USE_SJIS_TEXT_DIC */
  unsigned char   *d = (unsigned char *)dst;
  Wchar           *s = src;
  Wchar           *S = src + maxsrc;
  int             count = 0;
  long            code;
  int       byte;

    if ( --maxdst <= 0 )
      return count;
    while ( s < S )
    {
      code = *s++;
      switch(code&0x8080)
      {
      case 0x0000:
          code &= 0xff;
          byte = 1;
          break;
      case 0x0080:
          code &= 0xff;
          code |= 0x8e00;
          byte = 2;
          break;
      case 0x8000:
          code &= 0xffff;
          code |= 0x8f8080;
          byte = 3;
          break;
      case 0x8080:
          code &= 0xffff;
          byte = 2;
          break;
        };
      ADDCODE(d, maxdst, count, code, byte);
    };
    if ( d )
      *d = 0;
    return count;
#endif /* !USE_SJIS_TEXT_DIC */
}

#ifdef notdef
/* RkEuc
 *    shift jis --> euc 
 */
int   
RkCvtEuc(euc, maxeuc, sj, maxsj)
     unsigned char      *euc;
     int          maxeuc;
     unsigned char      *sj;
     int          maxsj;
{
  unsigned char   *e = euc;
  unsigned char   *s = sj;
  unsigned char   *S = sj + maxsj;
  Wchar           hi, lo;
  Wchar           byte;
  int             count = 0;
  unsigned long   code;
  
  if ( --maxeuc <= 0 )
    return 0;
  
  while ( s < S ) {
    hi = *s++;
    if ( hi <= 0x7f )               /* ascii */
      code = hi, byte = 1;
    else 
      if ( 0xa0 <= hi && hi <= 0xdf )     /* hankaku katakana */
      code = 0x8e00|hi, byte = 2;
      else {
      hi -= (hi <= 0x9f) ?  0x80 : 0xc0;
      hi = 2*hi + 0x20;
      if ( (lo = *s++) <= 0x9e ) {  /* kisuu ku */
        hi--;
        if ( 0x80 <= lo ) lo--;
        lo -= (0x40 - 0x21);
      } else                  /* guusuu ku */
        lo -= (0x9f - 0x21);
      code = 0x8080|(hi<<8)|lo, byte = 2;
      };
    ADDCODE(e, maxeuc, count, code, byte);
  };
  if ( e )
    *e = 0;
  return count;
}
#endif /* notdef */

/* RkCvtSuuji
 *    arabia suuji wo kansuuji ni kaeru
 */
static Wchar suujinew[] = {
  0xa1bb, 0xb0ec, 0xc6f3, 0xbbb0, 0xbbcd, 
  0xb8de, 0xcfbb, 0xbcb7, 0xc8ac, 0xb6e5,
};
static Wchar suujiold[] = {
  0xa1bb, 0xb0ed, 0xc6f5, 0xbbb2, 0xbbcd, 
  0xb8e0, 0xcfbb, 0xbcb7, 0xc8ac, 0xb6e5,
};
static Wchar kurai4[] = {
  0, 0xcbfc, 0xb2af, 0xc3fb, 0xb5fe, 0,         
};

static Wchar kurai3new[] = { 0, 0xbdbd, 0xc9b4, 0xc0e9, };
static Wchar kurai3old[] = { 0, 0xbdbd, 0xc9b4, 0xc0e9, };

int
RkwCvtSuuji(dst, maxdst, src, maxsrc, format)
     Wchar  *dst;
     int    maxdst;
     Wchar  *src;
     int    maxsrc;
     int    format;
{
  int count;
  int i, j, k;
  int digit[4], pend;
  Wchar     code, tmp;
  Wchar     *d = dst;
  Wchar     *s = src + maxsrc - 1;
  
  if ( --maxdst <= 0 )
    return 0;
  /* 有効な桁数を数える */
  pend = 0;
  for ( count = k = 0; s >= src; k++ ) {
    int     dec, thru = *s;
    
    if ( thru & 0x8080 ) {
      if ( !((Wchar)0xa3b0 <= *s && *s <= (Wchar)0xa3b9) )
      break;
      dec = *s-- - 0xa3b0;
    }
    else {
      if ( !((Wchar)'0' <= *s && *s <= (Wchar)'9') )
      break;
      dec = *s-- - '0';
    }
    
    switch(format) {
      /* simple */
    case SUUJI_THROUGH: /* sanyou suuji */
      code = thru;
      ADDWCODE(d, maxdst, count, code);
      break;
    case SUUJI_HANKAKU: /* sanyou suuji */
      code = dec + '0';
      if (code == thru) {
      return 0;
      }
      ADDWCODE(d, maxdst, count, code);
      break;
    case SUUJI_ZENKAKU: /* sanyou suuji */
      code = hiragana[dec + '0'];
      if (code == thru) {
      return 0;
      }
      ADDWCODE(d, maxdst, count, code);
      break;
      /* kanji kurai dori */
    case SUUJI_SIMPLEKANJI:   /* kanji suuji */
      code = suujinew[dec];
      ADDWCODE(d, maxdst, count, code);
      break;
    case SUUJI_FULLKANJI:
    case SUUJI_FULLKANJITRAD:
    case SUUJI_WITHKANJIUNIT: /* 12 O 3456 M 7890 */
      digit[pend++] = dec;
      if ( pend == 4 ) {
      while ( pend > 0 && digit[pend - 1] == 0 )
        pend--;
      if ( pend ) {
        /* kurai wo shuturyoku */
        code = kurai4[k/4];
        if (code)
          ADDWCODE(d, maxdst, count, code)
        else
          if ( k >= 4 )
            return 0;
        
        for ( i = 0; i < pend; i++ ) 
          switch(format) {
          case SUUJI_FULLKANJI:
            if ( digit[i] ) {
            code = kurai3new[i];
            if (code)
              ADDWCODE(d, maxdst, count, code);
            if ( i == 0 || (digit[i] > 1) ) {
              code = suujinew[digit[i]];
              ADDWCODE(d, maxdst, count, code);
            }
            }
            break;
          case SUUJI_FULLKANJITRAD:
            if ( digit[i] ) {
            code = kurai3old[i];
            if (code)
              ADDWCODE(d, maxdst, count, code);
            code = suujiold[digit[i]];
            ADDWCODE(d, maxdst, count, code);
            };
            break;
          case SUUJI_WITHKANJIUNIT:
            code = hiragana[digit[i]+'0'];
            ADDWCODE(d, maxdst, count, code);
            break;
          }
      }
      pend = 0;
      }
      break;
    case SUUJI_WITHCOMMA: /* 1,234,567,890 */
      if ( k && k%3 == 0 ) {
      code = hiragana[','];
      ADDWCODE(d, maxdst, count, code);
      }
      code = hiragana[dec + '0'];
      ADDWCODE(d, maxdst, count, code);
      break;
    default:
      return 0;
    };
  };
  
  if (format == SUUJI_FULLKANJI || format == SUUJI_FULLKANJITRAD ||
      format == SUUJI_WITHKANJIUNIT) {
    while ( pend > 0 && digit[pend - 1] == 0 )
      pend--;
    if ( pend ) {
      code = kurai4[k/4];
      if (code)
      ADDWCODE(d, maxdst, count, code)
      else
      if ( k >= 4 )
        return 0;
      for ( i = 0; i < pend; i++ ) 
      switch(format) {
      case SUUJI_FULLKANJI:
        if ( digit[i] ) {
          code = kurai3new[i];
          if (code)
            ADDWCODE(d, maxdst, count, code);
          if ( i == 0 || (digit[i] > 1) ) {
            code = suujinew[digit[i]];
            ADDWCODE(d, maxdst, count, code);
          };
        };
        break;
      case SUUJI_FULLKANJITRAD:
        if ( digit[i] ) {
          code = kurai3old[i];
          if (code)
            ADDWCODE(d, maxdst, count, code);
          code = suujiold[digit[i]];
          ADDWCODE(d, maxdst, count, code);
        };
        break;
      case SUUJI_WITHKANJIUNIT:
        code = hiragana[digit[i]+'0'];
        ADDWCODE(d, maxdst, count, code);
        break;
      }
    }
  }
  
  if ( dst ) {
    *d = 0;
    for ( i = 0, j = count - 1; i < j; i++, j-- ) {
      tmp = dst[i]; dst[i] = dst[j]; dst[j] = tmp;
    }
  }
  return count;
}

/* ワイドキャラクタ対応関数 */

#define CBUFSIZE     512
unsigned char     *ustoeuc();
Wchar       *euctous();

int RkwCvtHan pro((Wchar *, int, Wchar *, int));

int
RkwCvtHan(dst, maxdst, src, srclen)
     Wchar  *dst, *src;
     int    maxdst, srclen;
{
  int len;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  unsigned char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  unsigned char *cbuf, *cbuf2;
  cbuf = (unsigned char *)malloc(CBUFSIZE);
  cbuf2 = (unsigned char *)malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) (void)free((char *)cbuf);
    if (cbuf2) (void)free((char *)cbuf2);
    return 0;
  }
#endif

  len = ustoeuc(src, srclen, cbuf, CBUFSIZE) - cbuf;
  len = RkCvtHan(cbuf2, CBUFSIZE, cbuf, len);
  if (len > 0) {
    if (dst) {
      len = euctous(cbuf2, len, dst, maxdst) - dst;
    }
    else {
      len = euccharlen(cbuf2, len);
    }
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  (void)free((char *)cbuf);
  (void)free((char *)cbuf2);
#endif
  return len;
}

int RkwCvtHira pro((Wchar *, int, Wchar *, int));

int
RkwCvtHira(dst, maxdst, src, srclen)
     Wchar  *dst, *src;
     int    maxdst, srclen;
{
  int len;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  unsigned char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  unsigned char *cbuf, *cbuf2;
  cbuf = (unsigned char *)malloc(CBUFSIZE);
  cbuf2 = (unsigned char *)malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) (void)free((char *)cbuf);
    if (cbuf2) (void)free((char *)cbuf2);
    return 0;
  }
#endif

  len = ustoeuc(src, srclen, cbuf, CBUFSIZE) - cbuf;
  len = RkCvtHira(cbuf2, CBUFSIZE, cbuf, len);
  if (len > 0) {
    if (dst) {
      len = euctous(cbuf2, len, dst, maxdst) - dst;
    }
    else {
      len = euccharlen(cbuf2, len);
    }
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  (void)free((char *)cbuf);
  (void)free((char *)cbuf2);
#endif
  return len;
}

int RkwCvtKana pro((Wchar *, int, Wchar *, int));

int  
RkwCvtKana(dst, maxdst, src, srclen)
     Wchar  *dst, *src;
     int    maxdst, srclen;
{
  unsigned int    len;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  unsigned char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  unsigned char *cbuf, *cbuf2;
  cbuf = (unsigned char *)malloc(CBUFSIZE);
  cbuf2 = (unsigned char *)malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) (void)free((char *)cbuf);
    if (cbuf2) (void)free((char *)cbuf2);
    return 0;
  }
#endif

  len = ustoeuc(src, srclen, cbuf, CBUFSIZE) - cbuf;
  len = RkCvtKana(cbuf2, CBUFSIZE, cbuf, len);
  if (len > 0) {
    if (dst) {
      len = euctous(cbuf2, len, dst, maxdst) - dst;
    }
    else {
      len = euccharlen(cbuf2, len);
    }
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  (void)free((char *)cbuf);
  (void)free((char *)cbuf2);
#endif
  return len;
}

int RkwCvtZen pro((Wchar *, int, Wchar *, int));

int  
RkwCvtZen(dst, maxdst, src, srclen)
     Wchar  *dst, *src;
     int    maxdst, srclen;
{
  int len;
#ifndef USE_MALLOC_FOR_BIG_ARRAY
  unsigned char cbuf[CBUFSIZE], cbuf2[CBUFSIZE];
#else
  unsigned char *cbuf, *cbuf2;
  cbuf = (unsigned char *)malloc(CBUFSIZE);
  cbuf2 = (unsigned char *)malloc(CBUFSIZE);
  if (!cbuf || !cbuf2) {
    if (cbuf) (void)free((char *)cbuf);
    if (cbuf2) (void)free((char *)cbuf2);
    return 0;
  }
#endif

  len = ustoeuc(src, srclen, cbuf, CBUFSIZE) - cbuf;
  len = RkCvtZen(cbuf2, CBUFSIZE, cbuf, len);
  if (len > 0) {
    if (dst) {
      len = euctous(cbuf2, len, dst, maxdst) - dst;
    }
    else {
      len = euccharlen(cbuf2, len);
    }
  }
#ifdef USE_MALLOC_FOR_BIG_ARRAY
  (void)free((char *)cbuf);
  (void)free((char *)cbuf2);
#endif
  return len;
}

int RkwCvtNone pro((Wchar *, int, Wchar *, int));

int
RkwCvtNone(dst, maxdst, src, srclen)
     Wchar  *dst, *src;
     int    maxdst, srclen;
{
  int i;
  int len = (maxdst < srclen) ? maxdst : srclen;

  if (dst) {
    for (i = 0 ; i < len ; i++) {
      *dst++ = *src++;
    }
    *dst = *src;
  }
  return len;
}

Generated by  Doxygen 1.6.0   Back to index