LCOV - differential code coverage report
Current view: top level - src/backend/utils/mb/conversion_procs/euc2004_sjis2004 - euc2004_sjis2004.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 40.4 % 183 74 109 74
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 8 8 8
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /*-------------------------------------------------------------------------
       2                 :  *
       3                 :  *    EUC_JIS_2004, SHIFT_JIS_2004
       4                 :  *
       5                 :  * Copyright (c) 2007-2023, PostgreSQL Global Development Group
       6                 :  *
       7                 :  * IDENTIFICATION
       8                 :  *    src/backend/utils/mb/conversion_procs/euc2004_sjis2004/euc2004_sjis2004.c
       9                 :  *
      10                 :  *-------------------------------------------------------------------------
      11                 :  */
      12                 : 
      13                 : #include "postgres.h"
      14                 : #include "fmgr.h"
      15                 : #include "mb/pg_wchar.h"
      16                 : 
      17 CBC           6 : PG_MODULE_MAGIC;
      18                 : 
      19               3 : PG_FUNCTION_INFO_V1(euc_jis_2004_to_shift_jis_2004);
      20               6 : PG_FUNCTION_INFO_V1(shift_jis_2004_to_euc_jis_2004);
      21                 : 
      22                 : static int  euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len, bool noError);
      23                 : static int  shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len, bool noError);
      24                 : 
      25                 : /* ----------
      26                 :  * conv_proc(
      27                 :  *      INTEGER,    -- source encoding id
      28                 :  *      INTEGER,    -- destination encoding id
      29                 :  *      CSTRING,    -- source string (null terminated C string)
      30                 :  *      CSTRING,    -- destination string (null terminated C string)
      31                 :  *      INTEGER,    -- source string length
      32                 :  *      BOOL        -- if true, don't throw an error if conversion fails
      33                 :  * ) returns INTEGER;
      34                 :  *
      35                 :  * Returns the number of bytes successfully converted.
      36                 :  * ----------
      37                 :  */
      38                 : 
      39                 : Datum
      40               3 : euc_jis_2004_to_shift_jis_2004(PG_FUNCTION_ARGS)
      41                 : {
      42               3 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
      43               3 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
      44               3 :     int         len = PG_GETARG_INT32(4);
      45               3 :     bool        noError = PG_GETARG_BOOL(5);
      46                 :     int         converted;
      47                 : 
      48               3 :     CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JIS_2004, PG_SHIFT_JIS_2004);
      49                 : 
      50               3 :     converted = euc_jis_20042shift_jis_2004(src, dest, len, noError);
      51                 : 
      52               3 :     PG_RETURN_INT32(converted);
      53                 : }
      54                 : 
      55                 : Datum
      56             129 : shift_jis_2004_to_euc_jis_2004(PG_FUNCTION_ARGS)
      57                 : {
      58             129 :     unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
      59             129 :     unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
      60             129 :     int         len = PG_GETARG_INT32(4);
      61             129 :     bool        noError = PG_GETARG_BOOL(5);
      62                 :     int         converted;
      63                 : 
      64             129 :     CHECK_ENCODING_CONVERSION_ARGS(PG_SHIFT_JIS_2004, PG_EUC_JIS_2004);
      65                 : 
      66             129 :     converted = shift_jis_20042euc_jis_2004(src, dest, len, noError);
      67                 : 
      68              84 :     PG_RETURN_INT32(converted);
      69                 : }
      70                 : 
      71                 : /*
      72                 :  * EUC_JIS_2004 -> SHIFT_JIS_2004
      73                 :  */
      74                 : static int
      75               3 : euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len, bool noError)
      76                 : {
      77               3 :     const unsigned char *start = euc;
      78                 :     int         c1,
      79                 :                 ku,
      80                 :                 ten;
      81                 :     int         l;
      82                 : 
      83              12 :     while (len > 0)
      84                 :     {
      85               9 :         c1 = *euc;
      86               9 :         if (!IS_HIGHBIT_SET(c1))
      87                 :         {
      88                 :             /* ASCII */
      89               9 :             if (c1 == 0)
      90                 :             {
      91 UBC           0 :                 if (noError)
      92               0 :                     break;
      93               0 :                 report_invalid_encoding(PG_EUC_JIS_2004,
      94                 :                                         (const char *) euc, len);
      95                 :             }
      96 CBC           9 :             *p++ = c1;
      97               9 :             euc++;
      98               9 :             len--;
      99               9 :             continue;
     100                 :         }
     101                 : 
     102 UBC           0 :         l = pg_encoding_verifymbchar(PG_EUC_JIS_2004, (const char *) euc, len);
     103                 : 
     104               0 :         if (l < 0)
     105                 :         {
     106               0 :             if (noError)
     107               0 :                 break;
     108               0 :             report_invalid_encoding(PG_EUC_JIS_2004,
     109                 :                                     (const char *) euc, len);
     110                 :         }
     111                 : 
     112               0 :         if (c1 == SS2 && l == 2)    /* JIS X 0201 kana? */
     113                 :         {
     114               0 :             *p++ = euc[1];
     115                 :         }
     116               0 :         else if (c1 == SS3 && l == 3)   /* JIS X 0213 plane 2? */
     117                 :         {
     118               0 :             ku = euc[1] - 0xa0;
     119               0 :             ten = euc[2] - 0xa0;
     120                 : 
     121               0 :             switch (ku)
     122                 :             {
     123               0 :                 case 1:
     124                 :                 case 3:
     125                 :                 case 4:
     126                 :                 case 5:
     127                 :                 case 8:
     128                 :                 case 12:
     129                 :                 case 13:
     130                 :                 case 14:
     131                 :                 case 15:
     132               0 :                     *p++ = ((ku + 0x1df) >> 1) - (ku >> 3) * 3;
     133               0 :                     break;
     134               0 :                 default:
     135               0 :                     if (ku >= 78 && ku <= 94)
     136                 :                     {
     137               0 :                         *p++ = (ku + 0x19b) >> 1;
     138                 :                     }
     139                 :                     else
     140                 :                     {
     141               0 :                         if (noError)
     142               0 :                             break;
     143               0 :                         report_invalid_encoding(PG_EUC_JIS_2004,
     144                 :                                                 (const char *) euc, len);
     145                 :                     }
     146                 :             }
     147                 : 
     148               0 :             if (ku % 2)
     149                 :             {
     150               0 :                 if (ten >= 1 && ten <= 63)
     151               0 :                     *p++ = ten + 0x3f;
     152               0 :                 else if (ten >= 64 && ten <= 94)
     153               0 :                     *p++ = ten + 0x40;
     154                 :                 else
     155                 :                 {
     156               0 :                     if (noError)
     157               0 :                         break;
     158               0 :                     report_invalid_encoding(PG_EUC_JIS_2004,
     159                 :                                             (const char *) euc, len);
     160                 :                 }
     161                 :             }
     162                 :             else
     163               0 :                 *p++ = ten + 0x9e;
     164                 :         }
     165                 : 
     166               0 :         else if (l == 2)        /* JIS X 0213 plane 1? */
     167                 :         {
     168               0 :             ku = c1 - 0xa0;
     169               0 :             ten = euc[1] - 0xa0;
     170                 : 
     171               0 :             if (ku >= 1 && ku <= 62)
     172               0 :                 *p++ = (ku + 0x101) >> 1;
     173               0 :             else if (ku >= 63 && ku <= 94)
     174               0 :                 *p++ = (ku + 0x181) >> 1;
     175                 :             else
     176                 :             {
     177               0 :                 if (noError)
     178               0 :                     break;
     179               0 :                 report_invalid_encoding(PG_EUC_JIS_2004,
     180                 :                                         (const char *) euc, len);
     181                 :             }
     182                 : 
     183               0 :             if (ku % 2)
     184                 :             {
     185               0 :                 if (ten >= 1 && ten <= 63)
     186               0 :                     *p++ = ten + 0x3f;
     187               0 :                 else if (ten >= 64 && ten <= 94)
     188               0 :                     *p++ = ten + 0x40;
     189                 :                 else
     190                 :                 {
     191               0 :                     if (noError)
     192               0 :                         break;
     193               0 :                     report_invalid_encoding(PG_EUC_JIS_2004,
     194                 :                                             (const char *) euc, len);
     195                 :                 }
     196                 :             }
     197                 :             else
     198               0 :                 *p++ = ten + 0x9e;
     199                 :         }
     200                 :         else
     201                 :         {
     202               0 :             if (noError)
     203               0 :                 break;
     204               0 :             report_invalid_encoding(PG_EUC_JIS_2004,
     205                 :                                     (const char *) euc, len);
     206                 :         }
     207                 : 
     208               0 :         euc += l;
     209               0 :         len -= l;
     210                 :     }
     211 CBC           3 :     *p = '\0';
     212                 : 
     213               3 :     return euc - start;
     214                 : }
     215                 : 
     216                 : /*
     217                 :  * returns SHIFT_JIS_2004 "ku" code indicated by second byte
     218                 :  * *ku = 0: "ku" = even
     219                 :  * *ku = 1: "ku" = odd
     220                 :  */
     221                 : static int
     222              63 : get_ten(int b, int *ku)
     223                 : {
     224                 :     int         ten;
     225                 : 
     226              63 :     if (b >= 0x40 && b <= 0x7e)
     227                 :     {
     228 UBC           0 :         ten = b - 0x3f;
     229               0 :         *ku = 1;
     230                 :     }
     231 CBC          63 :     else if (b >= 0x80 && b <= 0x9e)
     232                 :     {
     233 UBC           0 :         ten = b - 0x40;
     234               0 :         *ku = 1;
     235                 :     }
     236 CBC          63 :     else if (b >= 0x9f && b <= 0xfc)
     237                 :     {
     238              63 :         ten = b - 0x9e;
     239              63 :         *ku = 0;
     240                 :     }
     241                 :     else
     242                 :     {
     243 UBC           0 :         ten = -1;               /* error */
     244               0 :         *ku = 0;                /* keep compiler quiet */
     245                 :     }
     246 CBC          63 :     return ten;
     247                 : }
     248                 : 
     249                 : /*
     250                 :  * SHIFT_JIS_2004 ---> EUC_JIS_2004
     251                 :  */
     252                 : 
     253                 : static int
     254             129 : shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len, bool noError)
     255                 : {
     256             129 :     const unsigned char *start = sjis;
     257                 :     int         c1;
     258                 :     int         ku,
     259                 :                 ten,
     260                 :                 kubun;
     261                 :     int         plane;
     262                 :     int         l;
     263                 : 
     264             579 :     while (len > 0)
     265                 :     {
     266             540 :         c1 = *sjis;
     267                 : 
     268             540 :         if (!IS_HIGHBIT_SET(c1))
     269                 :         {
     270                 :             /* ASCII */
     271             423 :             if (c1 == 0)
     272                 :             {
     273              36 :                 if (noError)
     274              18 :                     break;
     275              18 :                 report_invalid_encoding(PG_SHIFT_JIS_2004,
     276                 :                                         (const char *) sjis, len);
     277                 :             }
     278             387 :             *p++ = c1;
     279             387 :             sjis++;
     280             387 :             len--;
     281             387 :             continue;
     282                 :         }
     283                 : 
     284             117 :         l = pg_encoding_verifymbchar(PG_SHIFT_JIS_2004, (const char *) sjis, len);
     285                 : 
     286             117 :         if (l < 0 || l > len)
     287                 :         {
     288              54 :             if (noError)
     289              27 :                 break;
     290              27 :             report_invalid_encoding(PG_SHIFT_JIS_2004,
     291                 :                                     (const char *) sjis, len);
     292                 :         }
     293                 : 
     294              63 :         if (c1 >= 0xa1 && c1 <= 0xdf && l == 1)
     295                 :         {
     296                 :             /* JIS X0201 (1 byte kana) */
     297 UBC           0 :             *p++ = SS2;
     298               0 :             *p++ = c1;
     299                 :         }
     300 CBC          63 :         else if (l == 2)
     301                 :         {
     302              63 :             int         c2 = sjis[1];
     303                 : 
     304              63 :             plane = 1;
     305              63 :             ku = 1;
     306              63 :             ten = 1;
     307                 : 
     308                 :             /*
     309                 :              * JIS X 0213
     310                 :              */
     311              63 :             if (c1 >= 0x81 && c1 <= 0x9f) /* plane 1 1ku-62ku */
     312                 :             {
     313              63 :                 ku = (c1 << 1) - 0x100;
     314              63 :                 ten = get_ten(c2, &kubun);
     315              63 :                 if (ten < 0)
     316                 :                 {
     317 UBC           0 :                     if (noError)
     318               0 :                         break;
     319               0 :                     report_invalid_encoding(PG_SHIFT_JIS_2004,
     320                 :                                             (const char *) sjis, len);
     321                 :                 }
     322 CBC          63 :                 ku -= kubun;
     323                 :             }
     324 UBC           0 :             else if (c1 >= 0xe0 && c1 <= 0xef)    /* plane 1 62ku-94ku */
     325                 :             {
     326               0 :                 ku = (c1 << 1) - 0x180;
     327               0 :                 ten = get_ten(c2, &kubun);
     328               0 :                 if (ten < 0)
     329                 :                 {
     330               0 :                     if (noError)
     331               0 :                         break;
     332               0 :                     report_invalid_encoding(PG_SHIFT_JIS_2004,
     333                 :                                             (const char *) sjis, len);
     334                 :                 }
     335               0 :                 ku -= kubun;
     336                 :             }
     337               0 :             else if (c1 >= 0xf0 && c1 <= 0xf3)    /* plane 2
     338                 :                                                  * 1,3,4,5,8,12,13,14,15 ku */
     339                 :             {
     340               0 :                 plane = 2;
     341               0 :                 ten = get_ten(c2, &kubun);
     342               0 :                 if (ten < 0)
     343                 :                 {
     344               0 :                     if (noError)
     345               0 :                         break;
     346               0 :                     report_invalid_encoding(PG_SHIFT_JIS_2004,
     347                 :                                             (const char *) sjis, len);
     348                 :                 }
     349               0 :                 switch (c1)
     350                 :                 {
     351               0 :                     case 0xf0:
     352               0 :                         ku = kubun == 0 ? 8 : 1;
     353               0 :                         break;
     354               0 :                     case 0xf1:
     355               0 :                         ku = kubun == 0 ? 4 : 3;
     356               0 :                         break;
     357               0 :                     case 0xf2:
     358               0 :                         ku = kubun == 0 ? 12 : 5;
     359               0 :                         break;
     360               0 :                     default:
     361               0 :                         ku = kubun == 0 ? 14 : 13;
     362               0 :                         break;
     363                 :                 }
     364                 :             }
     365               0 :             else if (c1 >= 0xf4 && c1 <= 0xfc)    /* plane 2 78-94ku */
     366                 :             {
     367               0 :                 plane = 2;
     368               0 :                 ten = get_ten(c2, &kubun);
     369               0 :                 if (ten < 0)
     370                 :                 {
     371               0 :                     if (noError)
     372               0 :                         break;
     373               0 :                     report_invalid_encoding(PG_SHIFT_JIS_2004,
     374                 :                                             (const char *) sjis, len);
     375                 :                 }
     376               0 :                 if (c1 == 0xf4 && kubun == 1)
     377               0 :                     ku = 15;
     378                 :                 else
     379               0 :                     ku = (c1 << 1) - 0x19a - kubun;
     380                 :             }
     381                 :             else
     382                 :             {
     383               0 :                 if (noError)
     384               0 :                     break;
     385               0 :                 report_invalid_encoding(PG_SHIFT_JIS_2004,
     386                 :                                         (const char *) sjis, len);
     387                 :             }
     388                 : 
     389 CBC          63 :             if (plane == 2)
     390 UBC           0 :                 *p++ = SS3;
     391                 : 
     392 CBC          63 :             *p++ = ku + 0xa0;
     393              63 :             *p++ = ten + 0xa0;
     394                 :         }
     395              63 :         sjis += l;
     396              63 :         len -= l;
     397                 :     }
     398              84 :     *p = '\0';
     399                 : 
     400              84 :     return sjis - start;
     401                 : }
        

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