LCOV - differential 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 UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 46.5 % 359 167 192 167
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 19 19 19
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

Generated by: LCOV version v1.16-55-g56c0a2a