LCOV - code coverage report
Current view: top level - src/backend/utils/mb/conversion_procs/euc_jp_and_sjis - euc_jp_and_sjis.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 46.5 % 359 167
Test Date: 2026-02-28 21:15:15 Functions: 100.0 % 19 19
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  *    EUC_JP, SJIS and MULE_INTERNAL
       4              :  *
       5              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       6              :  * Portions Copyright (c) 1994, Regents of the University of California
       7              :  *
       8              :  * IDENTIFICATION
       9              :  *    src/backend/utils/mb/conversion_procs/euc_jp_and_sjis/euc_jp_and_sjis.c
      10              :  *
      11              :  *-------------------------------------------------------------------------
      12              :  */
      13              : 
      14              : #include "postgres.h"
      15              : #include "fmgr.h"
      16              : #include "mb/pg_wchar.h"
      17              : 
      18              : /*
      19              :  * SJIS alternative code.
      20              :  * this code is used if a mapping EUC -> SJIS is not defined.
      21              :  */
      22              : #define PGSJISALTCODE 0x81ac
      23              : #define PGEUCALTCODE 0xa2ae
      24              : 
      25              : /*
      26              :  * conversion table between SJIS UDC (IBM kanji) and EUC_JP
      27              :  */
      28              : #include "sjis.map"
      29              : 
      30            6 : PG_MODULE_MAGIC_EXT(
      31              :                     .name = "euc_jp_and_sjis",
      32              :                     .version = PG_VERSION
      33              : );
      34              : 
      35            3 : PG_FUNCTION_INFO_V1(euc_jp_to_sjis);
      36            3 : PG_FUNCTION_INFO_V1(sjis_to_euc_jp);
      37            3 : PG_FUNCTION_INFO_V1(euc_jp_to_mic);
      38            6 : PG_FUNCTION_INFO_V1(mic_to_euc_jp);
      39            3 : PG_FUNCTION_INFO_V1(sjis_to_mic);
      40            6 : PG_FUNCTION_INFO_V1(mic_to_sjis);
      41              : 
      42              : /* ----------
      43              :  * conv_proc(
      44              :  *      INTEGER,    -- source encoding id
      45              :  *      INTEGER,    -- destination encoding id
      46              :  *      CSTRING,    -- source string (null terminated C string)
      47              :  *      CSTRING,    -- destination string (null terminated C string)
      48              :  *      INTEGER,    -- source string length
      49              :  *      BOOL        -- if true, don't throw an error if conversion fails
      50              :  * ) returns INTEGER;
      51              :  *
      52              :  * Returns the number of bytes successfully converted.
      53              :  * ----------
      54              :  */
      55              : 
      56              : static int  sjis2mic(const unsigned char *sjis, unsigned char *p, int len, bool noError);
      57              : static int  mic2sjis(const unsigned char *mic, unsigned char *p, int len, bool noError);
      58              : static int  euc_jp2mic(const unsigned char *euc, unsigned char *p, int len, bool noError);
      59              : static int  mic2euc_jp(const unsigned char *mic, unsigned char *p, int len, bool noError);
      60              : static int  euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len, bool noError);
      61              : static int  sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len, bool noError);
      62              : 
      63              : Datum
      64            3 : euc_jp_to_sjis(PG_FUNCTION_ARGS)
      65              : {
      66            3 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
      67            3 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
      68            3 :     int         len = PG_GETARG_INT32(4);
      69            3 :     bool        noError = PG_GETARG_BOOL(5);
      70              :     int         converted;
      71              : 
      72            3 :     CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JP, PG_SJIS);
      73              : 
      74            3 :     converted = euc_jp2sjis(src, dest, len, noError);
      75              : 
      76            3 :     PG_RETURN_INT32(converted);
      77              : }
      78              : 
      79              : Datum
      80            3 : sjis_to_euc_jp(PG_FUNCTION_ARGS)
      81              : {
      82            3 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
      83            3 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
      84            3 :     int         len = PG_GETARG_INT32(4);
      85            3 :     bool        noError = PG_GETARG_BOOL(5);
      86              :     int         converted;
      87              : 
      88            3 :     CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_EUC_JP);
      89              : 
      90            3 :     converted = sjis2euc_jp(src, dest, len, noError);
      91              : 
      92            3 :     PG_RETURN_INT32(converted);
      93              : }
      94              : 
      95              : Datum
      96            3 : euc_jp_to_mic(PG_FUNCTION_ARGS)
      97              : {
      98            3 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
      99            3 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
     100            3 :     int         len = PG_GETARG_INT32(4);
     101            3 :     bool        noError = PG_GETARG_BOOL(5);
     102              :     int         converted;
     103              : 
     104            3 :     CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JP, PG_MULE_INTERNAL);
     105              : 
     106            3 :     converted = euc_jp2mic(src, dest, len, noError);
     107              : 
     108            3 :     PG_RETURN_INT32(converted);
     109              : }
     110              : 
     111              : Datum
     112          165 : mic_to_euc_jp(PG_FUNCTION_ARGS)
     113              : {
     114          165 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
     115          165 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
     116          165 :     int         len = PG_GETARG_INT32(4);
     117          165 :     bool        noError = PG_GETARG_BOOL(5);
     118              :     int         converted;
     119              : 
     120          165 :     CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_EUC_JP);
     121              : 
     122          165 :     converted = mic2euc_jp(src, dest, len, noError);
     123              : 
     124           93 :     PG_RETURN_INT32(converted);
     125              : }
     126              : 
     127              : Datum
     128            3 : sjis_to_mic(PG_FUNCTION_ARGS)
     129              : {
     130            3 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
     131            3 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
     132            3 :     int         len = PG_GETARG_INT32(4);
     133            3 :     bool        noError = PG_GETARG_BOOL(5);
     134              :     int         converted;
     135              : 
     136            3 :     CHECK_ENCODING_CONVERSION_ARGS(PG_SJIS, PG_MULE_INTERNAL);
     137              : 
     138            3 :     converted = sjis2mic(src, dest, len, noError);
     139              : 
     140            3 :     PG_RETURN_INT32(converted);
     141              : }
     142              : 
     143              : Datum
     144          165 : mic_to_sjis(PG_FUNCTION_ARGS)
     145              : {
     146          165 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
     147          165 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
     148          165 :     int         len = PG_GETARG_INT32(4);
     149          165 :     bool        noError = PG_GETARG_BOOL(5);
     150              :     int         converted;
     151              : 
     152          165 :     CHECK_ENCODING_CONVERSION_ARGS(PG_MULE_INTERNAL, PG_SJIS);
     153              : 
     154          165 :     converted = mic2sjis(src, dest, len, noError);
     155              : 
     156           93 :     PG_RETURN_INT32(converted);
     157              : }
     158              : 
     159              : /*
     160              :  * SJIS ---> MIC
     161              :  */
     162              : static int
     163            3 : sjis2mic(const unsigned char *sjis, unsigned char *p, int len, bool noError)
     164              : {
     165            3 :     const unsigned char *start = sjis;
     166              :     int         c1,
     167              :                 c2,
     168              :                 i,
     169              :                 k,
     170              :                 k2;
     171              : 
     172           12 :     while (len > 0)
     173              :     {
     174            9 :         c1 = *sjis;
     175            9 :         if (c1 >= 0xa1 && c1 <= 0xdf)
     176              :         {
     177              :             /* JIS X0201 (1 byte kana) */
     178            0 :             *p++ = LC_JISX0201K;
     179            0 :             *p++ = c1;
     180            0 :             sjis++;
     181            0 :             len--;
     182              :         }
     183            9 :         else if (IS_HIGHBIT_SET(c1))
     184              :         {
     185              :             /*
     186              :              * JIS X0208, X0212, user defined extended characters
     187              :              */
     188            0 :             if (len < 2 || !ISSJISHEAD(c1) || !ISSJISTAIL(sjis[1]))
     189              :             {
     190            0 :                 if (noError)
     191            0 :                     break;
     192            0 :                 report_invalid_encoding(PG_SJIS, (const char *) sjis, len);
     193              :             }
     194            0 :             c2 = sjis[1];
     195            0 :             k = (c1 << 8) + c2;
     196            0 :             if (k >= 0xed40 && k < 0xf040)
     197              :             {
     198              :                 /* NEC selection IBM kanji */
     199            0 :                 for (i = 0;; i++)
     200              :                 {
     201            0 :                     k2 = ibmkanji[i].nec;
     202            0 :                     if (k2 == 0xffff)
     203            0 :                         break;
     204            0 :                     if (k2 == k)
     205              :                     {
     206            0 :                         k = ibmkanji[i].sjis;
     207            0 :                         c1 = (k >> 8) & 0xff;
     208            0 :                         c2 = k & 0xff;
     209              :                     }
     210              :                 }
     211              :             }
     212              : 
     213            0 :             if (k < 0xeb3f)
     214              :             {
     215              :                 /* JIS X0208 */
     216            0 :                 *p++ = LC_JISX0208;
     217            0 :                 *p++ = ((c1 & 0x3f) << 1) + 0x9f + (c2 > 0x9e);
     218            0 :                 *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
     219              :             }
     220            0 :             else if ((k >= 0xeb40 && k < 0xf040) || (k >= 0xfc4c && k <= 0xfcfc))
     221              :             {
     222              :                 /* NEC selection IBM kanji - Other undecided justice */
     223            0 :                 *p++ = LC_JISX0208;
     224            0 :                 *p++ = PGEUCALTCODE >> 8;
     225            0 :                 *p++ = PGEUCALTCODE & 0xff;
     226              :             }
     227            0 :             else if (k >= 0xf040 && k < 0xf540)
     228              :             {
     229              :                 /*
     230              :                  * UDC1 mapping to X0208 85 ku - 94 ku JIS code 0x7521 -
     231              :                  * 0x7e7e EUC 0xf5a1 - 0xfefe
     232              :                  */
     233            0 :                 *p++ = LC_JISX0208;
     234            0 :                 c1 -= 0x6f;
     235            0 :                 *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
     236            0 :                 *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
     237              :             }
     238            0 :             else if (k >= 0xf540 && k < 0xfa40)
     239              :             {
     240              :                 /*
     241              :                  * UDC2 mapping to X0212 85 ku - 94 ku JIS code 0x7521 -
     242              :                  * 0x7e7e EUC 0x8ff5a1 - 0x8ffefe
     243              :                  */
     244            0 :                 *p++ = LC_JISX0212;
     245            0 :                 c1 -= 0x74;
     246            0 :                 *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
     247            0 :                 *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
     248              :             }
     249            0 :             else if (k >= 0xfa40)
     250              :             {
     251              :                 /*
     252              :                  * mapping IBM kanji to X0208 and X0212
     253              :                  */
     254            0 :                 for (i = 0;; i++)
     255              :                 {
     256            0 :                     k2 = ibmkanji[i].sjis;
     257            0 :                     if (k2 == 0xffff)
     258            0 :                         break;
     259            0 :                     if (k2 == k)
     260              :                     {
     261            0 :                         k = ibmkanji[i].euc;
     262            0 :                         if (k >= 0x8f0000)
     263              :                         {
     264            0 :                             *p++ = LC_JISX0212;
     265            0 :                             *p++ = 0x80 | ((k & 0xff00) >> 8);
     266            0 :                             *p++ = 0x80 | (k & 0xff);
     267              :                         }
     268              :                         else
     269              :                         {
     270            0 :                             *p++ = LC_JISX0208;
     271            0 :                             *p++ = 0x80 | (k >> 8);
     272            0 :                             *p++ = 0x80 | (k & 0xff);
     273              :                         }
     274              :                     }
     275              :                 }
     276              :             }
     277            0 :             sjis += 2;
     278            0 :             len -= 2;
     279              :         }
     280              :         else
     281              :         {                       /* should be ASCII */
     282            9 :             if (c1 == 0)
     283              :             {
     284            0 :                 if (noError)
     285            0 :                     break;
     286            0 :                 report_invalid_encoding(PG_SJIS, (const char *) sjis, len);
     287              :             }
     288            9 :             *p++ = c1;
     289            9 :             sjis++;
     290            9 :             len--;
     291              :         }
     292              :     }
     293            3 :     *p = '\0';
     294              : 
     295            3 :     return sjis - start;
     296              : }
     297              : 
     298              : /*
     299              :  * MIC ---> SJIS
     300              :  */
     301              : static int
     302          165 : mic2sjis(const unsigned char *mic, unsigned char *p, int len, bool noError)
     303              : {
     304          165 :     const unsigned char *start = mic;
     305              :     int         c1,
     306              :                 c2,
     307              :                 k,
     308              :                 l;
     309              : 
     310          336 :     while (len > 0)
     311              :     {
     312          315 :         c1 = *mic;
     313          315 :         if (!IS_HIGHBIT_SET(c1))
     314              :         {
     315              :             /* ASCII */
     316          162 :             if (c1 == 0)
     317              :             {
     318           18 :                 if (noError)
     319            9 :                     break;
     320            9 :                 report_invalid_encoding(PG_MULE_INTERNAL,
     321              :                                         (const char *) mic, len);
     322              :             }
     323          144 :             *p++ = c1;
     324          144 :             mic++;
     325          144 :             len--;
     326          144 :             continue;
     327              :         }
     328          153 :         l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len);
     329          153 :         if (l < 0)
     330              :         {
     331           72 :             if (noError)
     332           36 :                 break;
     333           36 :             report_invalid_encoding(PG_MULE_INTERNAL,
     334              :                                     (const char *) mic, len);
     335              :         }
     336           81 :         if (c1 == LC_JISX0201K)
     337            0 :             *p++ = mic[1];
     338           81 :         else if (c1 == LC_JISX0208)
     339              :         {
     340           27 :             c1 = mic[1];
     341           27 :             c2 = mic[2];
     342           27 :             k = (c1 << 8) | (c2 & 0xff);
     343           27 :             if (k >= 0xf5a1)
     344              :             {
     345              :                 /* UDC1 */
     346            0 :                 c1 -= 0x54;
     347            0 :                 *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x6f;
     348              :             }
     349              :             else
     350           27 :                 *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1);
     351           27 :             *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
     352              :         }
     353           54 :         else if (c1 == LC_JISX0212)
     354              :         {
     355              :             int         i,
     356              :                         k2;
     357              : 
     358            0 :             c1 = mic[1];
     359            0 :             c2 = mic[2];
     360            0 :             k = c1 << 8 | c2;
     361            0 :             if (k >= 0xf5a1)
     362              :             {
     363              :                 /* UDC2 */
     364            0 :                 c1 -= 0x54;
     365            0 :                 *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x74;
     366            0 :                 *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
     367              :             }
     368              :             else
     369              :             {
     370              :                 /* IBM kanji */
     371            0 :                 for (i = 0;; i++)
     372              :                 {
     373            0 :                     k2 = ibmkanji[i].euc & 0xffff;
     374            0 :                     if (k2 == 0xffff)
     375              :                     {
     376            0 :                         *p++ = PGSJISALTCODE >> 8;
     377            0 :                         *p++ = PGSJISALTCODE & 0xff;
     378            0 :                         break;
     379              :                     }
     380            0 :                     if (k2 == k)
     381              :                     {
     382            0 :                         k = ibmkanji[i].sjis;
     383            0 :                         *p++ = k >> 8;
     384            0 :                         *p++ = k & 0xff;
     385            0 :                         break;
     386              :                     }
     387              :                 }
     388              :             }
     389              :         }
     390              :         else
     391              :         {
     392           54 :             if (noError)
     393           27 :                 break;
     394           27 :             report_untranslatable_char(PG_MULE_INTERNAL, PG_SJIS,
     395              :                                        (const char *) mic, len);
     396              :         }
     397           27 :         mic += l;
     398           27 :         len -= l;
     399              :     }
     400           93 :     *p = '\0';
     401              : 
     402           93 :     return mic - start;
     403              : }
     404              : 
     405              : /*
     406              :  * EUC_JP ---> MIC
     407              :  */
     408              : static int
     409            3 : euc_jp2mic(const unsigned char *euc, unsigned char *p, int len, bool noError)
     410              : {
     411            3 :     const unsigned char *start = euc;
     412              :     int         c1;
     413              :     int         l;
     414              : 
     415           12 :     while (len > 0)
     416              :     {
     417            9 :         c1 = *euc;
     418            9 :         if (!IS_HIGHBIT_SET(c1))
     419              :         {
     420              :             /* ASCII */
     421            9 :             if (c1 == 0)
     422              :             {
     423            0 :                 if (noError)
     424            0 :                     break;
     425            0 :                 report_invalid_encoding(PG_EUC_JP,
     426              :                                         (const char *) euc, len);
     427              :             }
     428            9 :             *p++ = c1;
     429            9 :             euc++;
     430            9 :             len--;
     431            9 :             continue;
     432              :         }
     433            0 :         l = pg_encoding_verifymbchar(PG_EUC_JP, (const char *) euc, len);
     434            0 :         if (l < 0)
     435              :         {
     436            0 :             if (noError)
     437            0 :                 break;
     438            0 :             report_invalid_encoding(PG_EUC_JP,
     439              :                                     (const char *) euc, len);
     440              :         }
     441            0 :         if (c1 == SS2)
     442              :         {                       /* 1 byte kana? */
     443            0 :             *p++ = LC_JISX0201K;
     444            0 :             *p++ = euc[1];
     445              :         }
     446            0 :         else if (c1 == SS3)
     447              :         {                       /* JIS X0212 kanji? */
     448            0 :             *p++ = LC_JISX0212;
     449            0 :             *p++ = euc[1];
     450            0 :             *p++ = euc[2];
     451              :         }
     452              :         else
     453              :         {                       /* kanji? */
     454            0 :             *p++ = LC_JISX0208;
     455            0 :             *p++ = c1;
     456            0 :             *p++ = euc[1];
     457              :         }
     458            0 :         euc += l;
     459            0 :         len -= l;
     460              :     }
     461            3 :     *p = '\0';
     462              : 
     463            3 :     return euc - start;
     464              : }
     465              : 
     466              : /*
     467              :  * MIC ---> EUC_JP
     468              :  */
     469              : static int
     470          165 : mic2euc_jp(const unsigned char *mic, unsigned char *p, int len, bool noError)
     471              : {
     472          165 :     const unsigned char *start = mic;
     473              :     int         c1;
     474              :     int         l;
     475              : 
     476          336 :     while (len > 0)
     477              :     {
     478          315 :         c1 = *mic;
     479          315 :         if (!IS_HIGHBIT_SET(c1))
     480              :         {
     481              :             /* ASCII */
     482          162 :             if (c1 == 0)
     483              :             {
     484           18 :                 if (noError)
     485            9 :                     break;
     486            9 :                 report_invalid_encoding(PG_MULE_INTERNAL,
     487              :                                         (const char *) mic, len);
     488              :             }
     489          144 :             *p++ = c1;
     490          144 :             mic++;
     491          144 :             len--;
     492          144 :             continue;
     493              :         }
     494          153 :         l = pg_encoding_verifymbchar(PG_MULE_INTERNAL, (const char *) mic, len);
     495          153 :         if (l < 0)
     496              :         {
     497           72 :             if (noError)
     498           36 :                 break;
     499           36 :             report_invalid_encoding(PG_MULE_INTERNAL,
     500              :                                     (const char *) mic, len);
     501              :         }
     502           81 :         if (c1 == LC_JISX0201K)
     503              :         {
     504            0 :             *p++ = SS2;
     505            0 :             *p++ = mic[1];
     506              :         }
     507           81 :         else if (c1 == LC_JISX0212)
     508              :         {
     509            0 :             *p++ = SS3;
     510            0 :             *p++ = mic[1];
     511            0 :             *p++ = mic[2];
     512              :         }
     513           81 :         else if (c1 == LC_JISX0208)
     514              :         {
     515           27 :             *p++ = mic[1];
     516           27 :             *p++ = mic[2];
     517              :         }
     518              :         else
     519              :         {
     520           54 :             if (noError)
     521           27 :                 break;
     522           27 :             report_untranslatable_char(PG_MULE_INTERNAL, PG_EUC_JP,
     523              :                                        (const char *) mic, len);
     524              :         }
     525           27 :         mic += l;
     526           27 :         len -= l;
     527              :     }
     528           93 :     *p = '\0';
     529              : 
     530           93 :     return mic - start;
     531              : }
     532              : 
     533              : /*
     534              :  * EUC_JP -> SJIS
     535              :  */
     536              : static int
     537            3 : euc_jp2sjis(const unsigned char *euc, unsigned char *p, int len, bool noError)
     538              : {
     539            3 :     const unsigned char *start = euc;
     540              :     int         c1,
     541              :                 c2,
     542              :                 k;
     543              :     int         l;
     544              : 
     545           12 :     while (len > 0)
     546              :     {
     547            9 :         c1 = *euc;
     548            9 :         if (!IS_HIGHBIT_SET(c1))
     549              :         {
     550              :             /* ASCII */
     551            9 :             if (c1 == 0)
     552              :             {
     553            0 :                 if (noError)
     554            0 :                     break;
     555            0 :                 report_invalid_encoding(PG_EUC_JP,
     556              :                                         (const char *) euc, len);
     557              :             }
     558            9 :             *p++ = c1;
     559            9 :             euc++;
     560            9 :             len--;
     561            9 :             continue;
     562              :         }
     563            0 :         l = pg_encoding_verifymbchar(PG_EUC_JP, (const char *) euc, len);
     564            0 :         if (l < 0)
     565              :         {
     566            0 :             if (noError)
     567            0 :                 break;
     568            0 :             report_invalid_encoding(PG_EUC_JP,
     569              :                                     (const char *) euc, len);
     570              :         }
     571            0 :         if (c1 == SS2)
     572              :         {
     573              :             /* hankaku kana? */
     574            0 :             *p++ = euc[1];
     575              :         }
     576            0 :         else if (c1 == SS3)
     577              :         {
     578              :             /* JIS X0212 kanji? */
     579            0 :             c1 = euc[1];
     580            0 :             c2 = euc[2];
     581            0 :             k = c1 << 8 | c2;
     582            0 :             if (k >= 0xf5a1)
     583              :             {
     584              :                 /* UDC2 */
     585            0 :                 c1 -= 0x54;
     586            0 :                 *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x74;
     587            0 :                 *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
     588              :             }
     589              :             else
     590              :             {
     591              :                 int         i,
     592              :                             k2;
     593              : 
     594              :                 /* IBM kanji */
     595            0 :                 for (i = 0;; i++)
     596              :                 {
     597            0 :                     k2 = ibmkanji[i].euc & 0xffff;
     598            0 :                     if (k2 == 0xffff)
     599              :                     {
     600            0 :                         *p++ = PGSJISALTCODE >> 8;
     601            0 :                         *p++ = PGSJISALTCODE & 0xff;
     602            0 :                         break;
     603              :                     }
     604            0 :                     if (k2 == k)
     605              :                     {
     606            0 :                         k = ibmkanji[i].sjis;
     607            0 :                         *p++ = k >> 8;
     608            0 :                         *p++ = k & 0xff;
     609            0 :                         break;
     610              :                     }
     611              :                 }
     612              :             }
     613              :         }
     614              :         else
     615              :         {
     616              :             /* JIS X0208 kanji? */
     617            0 :             c2 = euc[1];
     618            0 :             k = (c1 << 8) | (c2 & 0xff);
     619            0 :             if (k >= 0xf5a1)
     620              :             {
     621              :                 /* UDC1 */
     622            0 :                 c1 -= 0x54;
     623            0 :                 *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1) + 0x6f;
     624              :             }
     625              :             else
     626            0 :                 *p++ = ((c1 - 0xa1) >> 1) + ((c1 < 0xdf) ? 0x81 : 0xc1);
     627            0 :             *p++ = c2 - ((c1 & 1) ? ((c2 < 0xe0) ? 0x61 : 0x60) : 2);
     628              :         }
     629            0 :         euc += l;
     630            0 :         len -= l;
     631              :     }
     632            3 :     *p = '\0';
     633              : 
     634            3 :     return euc - start;
     635              : }
     636              : 
     637              : /*
     638              :  * SJIS ---> EUC_JP
     639              :  */
     640              : static int
     641            3 : sjis2euc_jp(const unsigned char *sjis, unsigned char *p, int len, bool noError)
     642              : {
     643            3 :     const unsigned char *start = sjis;
     644              :     int         c1,
     645              :                 c2,
     646              :                 i,
     647              :                 k,
     648              :                 k2;
     649              :     int         l;
     650              : 
     651           12 :     while (len > 0)
     652              :     {
     653            9 :         c1 = *sjis;
     654            9 :         if (!IS_HIGHBIT_SET(c1))
     655              :         {
     656              :             /* ASCII */
     657            9 :             if (c1 == 0)
     658              :             {
     659            0 :                 if (noError)
     660            0 :                     break;
     661            0 :                 report_invalid_encoding(PG_SJIS,
     662              :                                         (const char *) sjis, len);
     663              :             }
     664            9 :             *p++ = c1;
     665            9 :             sjis++;
     666            9 :             len--;
     667            9 :             continue;
     668              :         }
     669            0 :         l = pg_encoding_verifymbchar(PG_SJIS, (const char *) sjis, len);
     670            0 :         if (l < 0)
     671              :         {
     672            0 :             if (noError)
     673            0 :                 break;
     674            0 :             report_invalid_encoding(PG_SJIS,
     675              :                                     (const char *) sjis, len);
     676              :         }
     677            0 :         if (c1 >= 0xa1 && c1 <= 0xdf)
     678              :         {
     679              :             /* JIS X0201 (1 byte kana) */
     680            0 :             *p++ = SS2;
     681            0 :             *p++ = c1;
     682              :         }
     683              :         else
     684              :         {
     685              :             /*
     686              :              * JIS X0208, X0212, user defined extended characters
     687              :              */
     688            0 :             c2 = sjis[1];
     689            0 :             k = (c1 << 8) + c2;
     690            0 :             if (k >= 0xed40 && k < 0xf040)
     691              :             {
     692              :                 /* NEC selection IBM kanji */
     693            0 :                 for (i = 0;; i++)
     694              :                 {
     695            0 :                     k2 = ibmkanji[i].nec;
     696            0 :                     if (k2 == 0xffff)
     697            0 :                         break;
     698            0 :                     if (k2 == k)
     699              :                     {
     700            0 :                         k = ibmkanji[i].sjis;
     701            0 :                         c1 = (k >> 8) & 0xff;
     702            0 :                         c2 = k & 0xff;
     703              :                     }
     704              :                 }
     705              :             }
     706              : 
     707            0 :             if (k < 0xeb3f)
     708              :             {
     709              :                 /* JIS X0208 */
     710            0 :                 *p++ = ((c1 & 0x3f) << 1) + 0x9f + (c2 > 0x9e);
     711            0 :                 *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
     712              :             }
     713            0 :             else if ((k >= 0xeb40 && k < 0xf040) || (k >= 0xfc4c && k <= 0xfcfc))
     714              :             {
     715              :                 /* NEC selection IBM kanji - Other undecided justice */
     716            0 :                 *p++ = PGEUCALTCODE >> 8;
     717            0 :                 *p++ = PGEUCALTCODE & 0xff;
     718              :             }
     719            0 :             else if (k >= 0xf040 && k < 0xf540)
     720              :             {
     721              :                 /*
     722              :                  * UDC1 mapping to X0208 85 ku - 94 ku JIS code 0x7521 -
     723              :                  * 0x7e7e EUC 0xf5a1 - 0xfefe
     724              :                  */
     725            0 :                 c1 -= 0x6f;
     726            0 :                 *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
     727            0 :                 *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
     728              :             }
     729            0 :             else if (k >= 0xf540 && k < 0xfa40)
     730              :             {
     731              :                 /*
     732              :                  * UDC2 mapping to X0212 85 ku - 94 ku JIS code 0x7521 -
     733              :                  * 0x7e7e EUC 0x8ff5a1 - 0x8ffefe
     734              :                  */
     735            0 :                 *p++ = SS3;
     736            0 :                 c1 -= 0x74;
     737            0 :                 *p++ = ((c1 & 0x3f) << 1) + 0xf3 + (c2 > 0x9e);
     738            0 :                 *p++ = c2 + ((c2 > 0x9e) ? 2 : 0x60) + (c2 < 0x80);
     739              :             }
     740            0 :             else if (k >= 0xfa40)
     741              :             {
     742              :                 /*
     743              :                  * mapping IBM kanji to X0208 and X0212
     744              :                  *
     745              :                  */
     746            0 :                 for (i = 0;; i++)
     747              :                 {
     748            0 :                     k2 = ibmkanji[i].sjis;
     749            0 :                     if (k2 == 0xffff)
     750            0 :                         break;
     751            0 :                     if (k2 == k)
     752              :                     {
     753            0 :                         k = ibmkanji[i].euc;
     754            0 :                         if (k >= 0x8f0000)
     755              :                         {
     756            0 :                             *p++ = SS3;
     757            0 :                             *p++ = 0x80 | ((k & 0xff00) >> 8);
     758            0 :                             *p++ = 0x80 | (k & 0xff);
     759              :                         }
     760              :                         else
     761              :                         {
     762            0 :                             *p++ = 0x80 | (k >> 8);
     763            0 :                             *p++ = 0x80 | (k & 0xff);
     764              :                         }
     765              :                     }
     766              :                 }
     767              :             }
     768              :         }
     769            0 :         sjis += l;
     770            0 :         len -= l;
     771              :     }
     772            3 :     *p = '\0';
     773              : 
     774            3 :     return sjis - start;
     775              : }
        

Generated by: LCOV version 2.0-1