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) Hit Total Coverage
Test: PostgreSQL Lines: 115 325 35.4 %
Date: 2017-09-29 15:12:54 Functions: 19 19 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11