LCOV - code coverage report
Current view: top level - src/backend/utils/mb/conversion_procs/euc2004_sjis2004 - euc2004_sjis2004.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 40.4 % 183 74
Test Date: 2026-07-25 22:15:46 Functions: 100.0 % 8 8
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 19.1 % 152 29

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

Generated by: LCOV version 2.0-1