Back to index

php5  5.3.10
Defines | Functions
gdkanji.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gd.h"
#include "gdhelpers.h"
#include <stdarg.h>

Go to the source code of this file.

Defines

#define LIBNAME   "any2eucjp()"
#define TRUE   1
#define FALSE   0
#define NEW   1
#define OLD   2
#define ESCI   3
#define NEC   4
#define EUC   5
#define SJIS   6
#define EUCORSJIS   7
#define ASCII   8
#define NEWJISSTR   "JIS7"
#define OLDJISSTR   "jis"
#define EUCSTR   "eucJP"
#define SJISSTR   "SJIS"
#define ESC   27
#define SS2   142
#define IS_DAKU(c)   ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))
#define IS_HANDAKU(c)   (c >= 202 && c <= 206)
#define ustrcpy(A, B)   (strcpy((char*)(A),(const char*)(B)))

Functions

static void debug (const char *format,...)
static void error (const char *format,...)
static int DetectKanjiCode (unsigned char *str)
static void SJIStoJIS (int *p1, int *p2)
static void han2zen (int *p1, int *p2)
static void do_convert (unsigned char *to, unsigned char *from, const char *code)
static int do_check_and_conv (unsigned char *to, unsigned char *from)
int any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max)

Define Documentation

#define ASCII   8

Definition at line 48 of file gdkanji.c.

#define ESC   27

Definition at line 55 of file gdkanji.c.

#define ESCI   3

Definition at line 43 of file gdkanji.c.

#define EUC   5

Definition at line 45 of file gdkanji.c.

#define EUCORSJIS   7

Definition at line 47 of file gdkanji.c.

#define EUCSTR   "eucJP"

Definition at line 52 of file gdkanji.c.

#define FALSE   0

Definition at line 39 of file gdkanji.c.

#define IS_DAKU (   c)    ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))

Definition at line 245 of file gdkanji.c.

#define IS_HANDAKU (   c)    (c >= 202 && c <= 206)

Definition at line 246 of file gdkanji.c.

#define LIBNAME   "any2eucjp()"

Definition at line 23 of file gdkanji.c.

#define NEC   4

Definition at line 44 of file gdkanji.c.

#define NEW   1

Definition at line 41 of file gdkanji.c.

#define NEWJISSTR   "JIS7"

Definition at line 50 of file gdkanji.c.

#define OLD   2

Definition at line 42 of file gdkanji.c.

#define OLDJISSTR   "jis"

Definition at line 51 of file gdkanji.c.

#define SJIS   6

Definition at line 46 of file gdkanji.c.

#define SJISSTR   "SJIS"

Definition at line 53 of file gdkanji.c.

#define SS2   142

Definition at line 56 of file gdkanji.c.

#define TRUE   1

Definition at line 38 of file gdkanji.c.

#define ustrcpy (   A,
 
)    (strcpy((char*)(A),(const char*)(B)))

Definition at line 341 of file gdkanji.c.


Function Documentation

int any2eucjp ( unsigned char *  dest,
unsigned char *  src,
unsigned int  dest_max 
)

Definition at line 560 of file gdkanji.c.

{
  static unsigned char tmp_dest[BUFSIZ];
  int ret;

  if (strlen ((const char *) src) >= BUFSIZ)
    {
      error ("input string too large");
      return -1;
    }
  if (dest_max > BUFSIZ)
    {
      error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);
      return -1;
    }
  ret = do_check_and_conv (tmp_dest, src);
  if (strlen ((const char *) tmp_dest) >= dest_max)
    {
      error ("output buffer overflow");
      ustrcpy (dest, src);
      return -1;
    }
  ustrcpy (dest, tmp_dest);
  return ret;
}

Here is the call graph for this function:

static void debug ( const char *  format,
  ... 
) [static]

Definition at line 59 of file gdkanji.c.

{
#ifdef DEBUG
  va_list args;

  va_start (args, format);
  fprintf (stdout, "%s: ", LIBNAME);
  vfprintf (stdout, format, args);
  fprintf (stdout, "\n");
  va_end (args);
#endif
}
static int DetectKanjiCode ( unsigned char *  str) [static]

Definition at line 89 of file gdkanji.c.

{
  static int whatcode = ASCII;
  int oldcode = ASCII;
  int c, i;
  char *lang = NULL;

  c = '\1';
  i = 0;

  if (whatcode != EUCORSJIS && whatcode != ASCII)
    {
      oldcode = whatcode;
      whatcode = ASCII;
    }

  while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0')
    {
      if ((c = str[i++]) != '\0')
       {
         if (c == ESC)
           {
             c = str[i++];
             if (c == '$')
              {
                c = str[i++];
                if (c == 'B')
                  whatcode = NEW;
                else if (c == '@')
                  whatcode = OLD;
              }
             else if (c == '(')
              {
                c = str[i++];
                if (c == 'I')
                  whatcode = ESCI;
              }
             else if (c == 'K')
              whatcode = NEC;
           }
         else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
           whatcode = SJIS;
         else if (c == SS2)
           {
             c = str[i++];
             if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
              whatcode = SJIS;
             else if (c >= 161 && c <= 223)
              whatcode = EUCORSJIS;
           }
         else if (c >= 161 && c <= 223)
           {
             c = str[i++];
             if (c >= 240 && c <= 254)
              whatcode = EUC;
             else if (c >= 161 && c <= 223)
              whatcode = EUCORSJIS;
             else if (c >= 224 && c <= 239)
              {
                whatcode = EUCORSJIS;
                while (c >= 64 && c != '\0' && whatcode == EUCORSJIS)
                  {
                    if (c >= 129)
                     {
                       if (c <= 141 || (c >= 143 && c <= 159))
                         whatcode = SJIS;
                       else if (c >= 253 && c <= 254)
                         whatcode = EUC;
                     }
                    c = str[i++];
                  }
              }
             else if (c <= 159)
              whatcode = SJIS;
           }
         else if (c >= 240 && c <= 254)
           whatcode = EUC;
         else if (c >= 224 && c <= 239)
           {
             c = str[i++];
             if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
              whatcode = SJIS;
             else if (c >= 253 && c <= 254)
              whatcode = EUC;
             else if (c >= 161 && c <= 252)
              whatcode = EUCORSJIS;
           }
       }
    }

#ifdef DEBUG
  if (whatcode == ASCII)
    debug ("Kanji code not included.");
  else if (whatcode == EUCORSJIS)
    debug ("Kanji code not detected.");
  else
    debug ("Kanji code detected at %d byte.", i);
#endif

  if (whatcode == EUCORSJIS && oldcode != ASCII)
    whatcode = oldcode;

  if (whatcode == EUCORSJIS)
    {
      if (getenv ("LC_ALL"))
       lang = getenv ("LC_ALL");
      else if (getenv ("LC_CTYPE"))
       lang = getenv ("LC_CTYPE");
      else if (getenv ("LANG"))
       lang = getenv ("LANG");

      if (lang)
       {
         if (strcmp (lang, "ja_JP.SJIS") == 0 ||
#ifdef hpux
             strcmp (lang, "japanese") == 0 ||
#endif
             strcmp (lang, "ja_JP.mscode") == 0 ||
             strcmp (lang, "ja_JP.PCK") == 0)
           whatcode = SJIS;
         else if (strncmp (lang, "ja", 2) == 0)
#ifdef SJISPRE
           whatcode = SJIS;
#else
           whatcode = EUC;
#endif
       }
    }

  if (whatcode == EUCORSJIS)
#ifdef SJISPRE
    whatcode = SJIS;
#else
    whatcode = EUC;
#endif

  return whatcode;
}

Here is the caller graph for this function:

static int do_check_and_conv ( unsigned char *  to,
unsigned char *  from 
) [static]

Definition at line 466 of file gdkanji.c.

{
  static unsigned char tmp[BUFSIZ];
  int p1, p2, i, j;
  int kanji = TRUE;

  switch (DetectKanjiCode (from))
    {
    case NEW:
      debug ("Kanji code is New JIS.");
      do_convert (tmp, from, NEWJISSTR);
      break;
    case OLD:
      debug ("Kanji code is Old JIS.");
      do_convert (tmp, from, OLDJISSTR);
      break;
    case ESCI:
      debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
      do_convert (tmp, from, NEWJISSTR);
      break;
    case NEC:
      debug ("Kanji code is NEC Kanji.");
      error ("cannot convert NEC Kanji.");
      ustrcpy (tmp, from);
      kanji = FALSE;
      break;
    case EUC:
      debug ("Kanji code is EUC.");
      ustrcpy (tmp, from);
      break;
    case SJIS:
      debug ("Kanji code is SJIS.");
      do_convert (tmp, from, SJISSTR);
      break;
    case EUCORSJIS:
      debug ("Kanji code is EUC or SJIS.");
      ustrcpy (tmp, from);
      kanji = FALSE;
      break;
    case ASCII:
      debug ("This is ASCII string.");
      ustrcpy (tmp, from);
      kanji = FALSE;
      break;
    default:
      debug ("This string includes unknown code.");
      ustrcpy (tmp, from);
      kanji = FALSE;
      break;
    }

  /* Hankaku Kana ---> Zenkaku Kana */
  if (kanji)
    {
      j = 0;
      for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++)
       {
         if (tmp[i] == SS2)
           {
             p1 = tmp[++i];
             if (tmp[i + 1] == SS2)
              {
                p2 = tmp[i + 2];
                if (p2 == 222 || p2 == 223)
                  i += 2;
                else
                  p2 = 0;
              }
             else
              p2 = 0;
             han2zen (&p1, &p2);
             SJIStoJIS (&p1, &p2);
             to[j++] = p1 + 128;
             to[j++] = p2 + 128;
           }
         else
           to[j++] = tmp[i];
       }

      if (j >= BUFSIZ)
       {
         error ("output buffer overflow at Hankaku --> Zenkaku");
         ustrcpy (to, tmp);
       }
      else
       to[j] = '\0';
    }
  else
    ustrcpy (to, tmp);

  return kanji;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void do_convert ( unsigned char *  to,
unsigned char *  from,
const char *  code 
) [static]

Definition at line 344 of file gdkanji.c.

{
#ifdef HAVE_ICONV
  iconv_t cd;
  size_t from_len, to_len;

  if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1)
    {
      error ("iconv_open() error");
#ifdef HAVE_ERRNO_H
      if (errno == EINVAL)
       error ("invalid code specification: \"%s\" or \"%s\"",
              EUCSTR, code);
#endif
      strcpy ((char *) to, (const char *) from);
      return;
    }

  from_len = strlen ((const char *) from) + 1;
  to_len = BUFSIZ;

  if ((int) iconv(cd, (char **) &from, &from_len, (char **) &to, &to_len) == -1)
    {
#ifdef HAVE_ERRNO_H
      if (errno == EINVAL)
       error ("invalid end of input string");
      else if (errno == EILSEQ)
       error ("invalid code in input string");
      else if (errno == E2BIG)
       error ("output buffer overflow at do_convert()");
      else
#endif
       error ("something happen");
      strcpy ((char *) to, (const char *) from);
      return;
    }

  if (iconv_close (cd) != 0)
    {
      error ("iconv_close() error");
    }
#else
  int p1, p2, i, j;
  int jisx0208 = FALSE;
  int hankaku = FALSE;

  j = 0;
  if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0)
    {
      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
       {
         if (from[i] == ESC)
           {
             i++;
             if (from[i] == '$')
              {
                jisx0208 = TRUE;
                hankaku = FALSE;
                i++;
              }
             else if (from[i] == '(')
              {
                jisx0208 = FALSE;
                i++;
                if (from[i] == 'I')       /* Hankaku Kana */
                  hankaku = TRUE;
                else
                  hankaku = FALSE;
              }
           }
         else
           {
             if (jisx0208)
              to[j++] = from[i] + 128;
             else if (hankaku)
              {
                to[j++] = SS2;
                to[j++] = from[i] + 128;
              }
             else
              to[j++] = from[i];
           }
       }
    }
  else if (strcmp (code, SJISSTR) == 0)
    {
      for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
       {
         p1 = from[i];
         if (p1 < 127)
           to[j++] = p1;
         else if ((p1 >= 161) && (p1 <= 223))
           {                /* Hankaku Kana */
             to[j++] = SS2;
             to[j++] = p1;
           }
         else
           {
             p2 = from[++i];
             SJIStoJIS (&p1, &p2);
             to[j++] = p1 + 128;
             to[j++] = p2 + 128;
           }
       }
    }
  else
    {
      error ("invalid code specification: \"%s\"", code);
      return;
    }

  if (j >= BUFSIZ)
    {
      error ("output buffer overflow at do_convert()");
      ustrcpy (to, from);
    }
  else
    to[j] = '\0';
#endif /* HAVE_ICONV */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void error ( const char *  format,
  ... 
) [static]

Definition at line 73 of file gdkanji.c.

{
       va_list args;
       char *tmp;
       TSRMLS_FETCH();

       va_start(args, format);
       vspprintf(&tmp, 0, format, args);
       va_end(args);
       php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", LIBNAME, tmp);
       efree(tmp);
}

Here is the call graph for this function:

static void han2zen ( int p1,
int p2 
) [static]

Definition at line 249 of file gdkanji.c.

{
  int c = *p1;
  int daku = FALSE;
  int handaku = FALSE;
  int mtable[][2] =
  {
    {129, 66},
    {129, 117},
    {129, 118},
    {129, 65},
    {129, 69},
    {131, 146},
    {131, 64},
    {131, 66},
    {131, 68},
    {131, 70},
    {131, 72},
    {131, 131},
    {131, 133},
    {131, 135},
    {131, 98},
    {129, 91},
    {131, 65},
    {131, 67},
    {131, 69},
    {131, 71},
    {131, 73},
    {131, 74},
    {131, 76},
    {131, 78},
    {131, 80},
    {131, 82},
    {131, 84},
    {131, 86},
    {131, 88},
    {131, 90},
    {131, 92},
    {131, 94},
    {131, 96},
    {131, 99},
    {131, 101},
    {131, 103},
    {131, 105},
    {131, 106},
    {131, 107},
    {131, 108},
    {131, 109},
    {131, 110},
    {131, 113},
    {131, 116},
    {131, 119},
    {131, 122},
    {131, 125},
    {131, 126},
    {131, 128},
    {131, 129},
    {131, 130},
    {131, 132},
    {131, 134},
    {131, 136},
    {131, 137},
    {131, 138},
    {131, 139},
    {131, 140},
    {131, 141},
    {131, 143},
    {131, 147},
    {129, 74},
    {129, 75}
  };

  if (*p2 == 222 && IS_DAKU (*p1))
    daku = TRUE;            /* Daku-ten */
  else if (*p2 == 223 && IS_HANDAKU (*p1))
    handaku = TRUE;         /* Han-daku-ten */

  *p1 = mtable[c - 161][0];
  *p2 = mtable[c - 161][1];

  if (daku)
    {
      if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
       (*p2)++;
      else if (*p2 == 131 && *p2 == 69)
       *p2 = 148;
    }
  else if (handaku && *p2 >= 110 && *p2 <= 122)
    (*p2) += 2;
}

Here is the caller graph for this function:

static void SJIStoJIS ( int p1,
int p2 
) [static]

Definition at line 231 of file gdkanji.c.

{
  register unsigned char c1 = *p1;
  register unsigned char c2 = *p2;
  register int adjust = c2 < 159;
  register int rowOffset = c1 < 160 ? 112 : 176;
  register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;

  *p1 = ((c1 - rowOffset) << 1) - adjust;
  *p2 -= cellOffset;
}

Here is the caller graph for this function: