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: Code coverage Lines: 42.1 % 221 93
Test Date: 2026-01-26 10:56:24 Functions: 100.0 % 8 8
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 20.4 % 147 30

             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                 :           2 : PG_MODULE_MAGIC_EXT(
      18                 :             :                                         .name = "euc2004_sjis2004",
      19                 :             :                                         .version = PG_VERSION
      20                 :             : );
      21                 :             : 
      22                 :           1 : PG_FUNCTION_INFO_V1(euc_jis_2004_to_shift_jis_2004);
      23                 :           2 : 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                 :           1 : euc_jis_2004_to_shift_jis_2004(PG_FUNCTION_ARGS)
      44                 :             : {
      45                 :           1 :         unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
      46                 :           1 :         unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
      47                 :           1 :         int                     len = PG_GETARG_INT32(4);
      48                 :           1 :         bool            noError = PG_GETARG_BOOL(5);
      49                 :           1 :         int                     converted;
      50                 :             : 
      51                 :           1 :         CHECK_ENCODING_CONVERSION_ARGS(PG_EUC_JIS_2004, PG_SHIFT_JIS_2004);
      52                 :             : 
      53                 :           1 :         converted = euc_jis_20042shift_jis_2004(src, dest, len, noError);
      54                 :             : 
      55                 :           2 :         PG_RETURN_INT32(converted);
      56                 :           1 : }
      57                 :             : 
      58                 :             : Datum
      59                 :          43 : shift_jis_2004_to_euc_jis_2004(PG_FUNCTION_ARGS)
      60                 :             : {
      61                 :          43 :         unsigned char *src = (unsigned char *) PG_GETARG_CSTRING(2);
      62                 :          43 :         unsigned char *dest = (unsigned char *) PG_GETARG_CSTRING(3);
      63                 :          43 :         int                     len = PG_GETARG_INT32(4);
      64                 :          43 :         bool            noError = PG_GETARG_BOOL(5);
      65                 :          43 :         int                     converted;
      66                 :             : 
      67                 :          43 :         CHECK_ENCODING_CONVERSION_ARGS(PG_SHIFT_JIS_2004, PG_EUC_JIS_2004);
      68                 :             : 
      69                 :          43 :         converted = shift_jis_20042euc_jis_2004(src, dest, len, noError);
      70                 :             : 
      71                 :          86 :         PG_RETURN_INT32(converted);
      72                 :          43 : }
      73                 :             : 
      74                 :             : /*
      75                 :             :  * EUC_JIS_2004 -> SHIFT_JIS_2004
      76                 :             :  */
      77                 :             : static int
      78                 :           1 : euc_jis_20042shift_jis_2004(const unsigned char *euc, unsigned char *p, int len, bool noError)
      79                 :             : {
      80                 :           1 :         const unsigned char *start = euc;
      81                 :           1 :         int                     c1,
      82                 :             :                                 ku,
      83                 :             :                                 ten;
      84                 :           1 :         int                     l;
      85                 :             : 
      86         [ +  + ]:           4 :         while (len > 0)
      87                 :             :         {
      88                 :           3 :                 c1 = *euc;
      89         [ -  + ]:           3 :                 if (!IS_HIGHBIT_SET(c1))
      90                 :             :                 {
      91                 :             :                         /* ASCII */
      92         [ +  - ]:           3 :                         if (c1 == 0)
      93                 :             :                         {
      94         [ #  # ]:           0 :                                 if (noError)
      95                 :           0 :                                         break;
      96                 :           0 :                                 report_invalid_encoding(PG_EUC_JIS_2004,
      97                 :           0 :                                                                                 (const char *) euc, len);
      98                 :             :                         }
      99                 :           3 :                         *p++ = c1;
     100                 :           3 :                         euc++;
     101                 :           3 :                         len--;
     102                 :           3 :                         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                 :           0 :                                                                         (const char *) euc, len);
     113                 :             :                 }
     114                 :             : 
     115   [ #  #  #  # ]:           0 :                 if (c1 == SS2 && l == 2)        /* JIS X 0201 kana? */
     116                 :             :                 {
     117                 :           0 :                         *p++ = euc[1];
     118                 :           0 :                 }
     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                 :             :                                 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                 :             :                                 default:
     138   [ #  #  #  # ]:           0 :                                         if (ku >= 78 && ku <= 94)
     139                 :             :                                         {
     140                 :           0 :                                                 *p++ = (ku + 0x19b) >> 1;
     141                 :           0 :                                         }
     142                 :             :                                         else
     143                 :             :                                         {
     144         [ #  # ]:           0 :                                                 if (noError)
     145                 :           0 :                                                         break;
     146                 :           0 :                                                 report_invalid_encoding(PG_EUC_JIS_2004,
     147                 :           0 :                                                                                                 (const char *) euc, len);
     148                 :             :                                         }
     149                 :           0 :                         }
     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                 :           0 :                                                                                         (const char *) euc, len);
     163                 :             :                                 }
     164                 :           0 :                         }
     165                 :             :                         else
     166                 :           0 :                                 *p++ = ten + 0x9e;
     167                 :           0 :                 }
     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                 :           0 :                                                                                 (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                 :           0 :                                                                                         (const char *) euc, len);
     198                 :             :                                 }
     199                 :           0 :                         }
     200                 :             :                         else
     201                 :           0 :                                 *p++ = ten + 0x9e;
     202                 :           0 :                 }
     203                 :             :                 else
     204                 :             :                 {
     205         [ #  # ]:           0 :                         if (noError)
     206                 :           0 :                                 break;
     207                 :           0 :                         report_invalid_encoding(PG_EUC_JIS_2004,
     208                 :           0 :                                                                         (const char *) euc, len);
     209                 :             :                 }
     210                 :             : 
     211                 :           0 :                 euc += l;
     212                 :           0 :                 len -= l;
     213                 :             :         }
     214                 :           1 :         *p = '\0';
     215                 :             : 
     216                 :           2 :         return euc - start;
     217                 :           1 : }
     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                 :          21 : get_ten(int b, int *ku)
     226                 :             : {
     227                 :          21 :         int                     ten;
     228                 :             : 
     229   [ +  -  +  - ]:          21 :         if (b >= 0x40 && b <= 0x7e)
     230                 :             :         {
     231                 :           0 :                 ten = b - 0x3f;
     232                 :           0 :                 *ku = 1;
     233                 :           0 :         }
     234   [ +  -  +  - ]:          21 :         else if (b >= 0x80 && b <= 0x9e)
     235                 :             :         {
     236                 :           0 :                 ten = b - 0x40;
     237                 :           0 :                 *ku = 1;
     238                 :           0 :         }
     239   [ +  -  -  + ]:          21 :         else if (b >= 0x9f && b <= 0xfc)
     240                 :             :         {
     241                 :          21 :                 ten = b - 0x9e;
     242                 :          21 :                 *ku = 0;
     243                 :          21 :         }
     244                 :             :         else
     245                 :             :         {
     246                 :           0 :                 ten = -1;                               /* error */
     247                 :           0 :                 *ku = 0;                                /* keep compiler quiet */
     248                 :             :         }
     249                 :          42 :         return ten;
     250                 :          21 : }
     251                 :             : 
     252                 :             : /*
     253                 :             :  * SHIFT_JIS_2004 ---> EUC_JIS_2004
     254                 :             :  */
     255                 :             : 
     256                 :             : static int
     257                 :          43 : shift_jis_20042euc_jis_2004(const unsigned char *sjis, unsigned char *p, int len, bool noError)
     258                 :             : {
     259                 :          43 :         const unsigned char *start = sjis;
     260                 :          43 :         int                     c1;
     261                 :          43 :         int                     ku,
     262                 :             :                                 ten,
     263                 :             :                                 kubun;
     264                 :          43 :         int                     plane;
     265                 :          43 :         int                     l;
     266                 :             : 
     267         [ +  + ]:         193 :         while (len > 0)
     268                 :             :         {
     269                 :         180 :                 c1 = *sjis;
     270                 :             : 
     271         [ +  + ]:         180 :                 if (!IS_HIGHBIT_SET(c1))
     272                 :             :                 {
     273                 :             :                         /* ASCII */
     274         [ +  + ]:         141 :                         if (c1 == 0)
     275                 :             :                         {
     276         [ +  + ]:          12 :                                 if (noError)
     277                 :           6 :                                         break;
     278                 :           6 :                                 report_invalid_encoding(PG_SHIFT_JIS_2004,
     279                 :           6 :                                                                                 (const char *) sjis, len);
     280                 :             :                         }
     281                 :         129 :                         *p++ = c1;
     282                 :         129 :                         sjis++;
     283                 :         129 :                         len--;
     284                 :         129 :                         continue;
     285                 :             :                 }
     286                 :             : 
     287                 :          39 :                 l = pg_encoding_verifymbchar(PG_SHIFT_JIS_2004, (const char *) sjis, len);
     288                 :             : 
     289   [ +  +  -  + ]:          39 :                 if (l < 0 || l > len)
     290                 :             :                 {
     291         [ +  + ]:          18 :                         if (noError)
     292                 :           9 :                                 break;
     293                 :           9 :                         report_invalid_encoding(PG_SHIFT_JIS_2004,
     294                 :           9 :                                                                         (const char *) sjis, len);
     295                 :             :                 }
     296                 :             : 
     297   [ -  +  #  #  :          21 :                 if (c1 >= 0xa1 && c1 <= 0xdf && l == 1)
                   #  # ]
     298                 :             :                 {
     299                 :             :                         /* JIS X0201 (1 byte kana) */
     300                 :           0 :                         *p++ = SS2;
     301                 :           0 :                         *p++ = c1;
     302                 :           0 :                 }
     303         [ -  + ]:          21 :                 else if (l == 2)
     304                 :             :                 {
     305                 :          21 :                         int                     c2 = sjis[1];
     306                 :             : 
     307                 :          21 :                         plane = 1;
     308                 :          21 :                         ku = 1;
     309                 :          21 :                         ten = 1;
     310                 :             : 
     311                 :             :                         /*
     312                 :             :                          * JIS X 0213
     313                 :             :                          */
     314   [ +  -  -  + ]:          21 :                         if (c1 >= 0x81 && c1 <= 0x9f)     /* plane 1 1ku-62ku */
     315                 :             :                         {
     316                 :          21 :                                 ku = (c1 << 1) - 0x100;
     317                 :          21 :                                 ten = get_ten(c2, &kubun);
     318         [ +  - ]:          21 :                                 if (ten < 0)
     319                 :             :                                 {
     320         [ #  # ]:           0 :                                         if (noError)
     321                 :           0 :                                                 break;
     322                 :           0 :                                         report_invalid_encoding(PG_SHIFT_JIS_2004,
     323                 :           0 :                                                                                         (const char *) sjis, len);
     324                 :             :                                 }
     325                 :          21 :                                 ku -= kubun;
     326                 :          21 :                         }
     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                 :           0 :                                                                                         (const char *) sjis, len);
     337                 :             :                                 }
     338                 :           0 :                                 ku -= kubun;
     339                 :           0 :                         }
     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                 :           0 :                                                                                         (const char *) sjis, len);
     351                 :             :                                 }
     352   [ #  #  #  # ]:           0 :                                 switch (c1)
     353                 :             :                                 {
     354                 :             :                                         case 0xf0:
     355                 :           0 :                                                 ku = kubun == 0 ? 8 : 1;
     356                 :           0 :                                                 break;
     357                 :             :                                         case 0xf1:
     358                 :           0 :                                                 ku = kubun == 0 ? 4 : 3;
     359                 :           0 :                                                 break;
     360                 :             :                                         case 0xf2:
     361                 :           0 :                                                 ku = kubun == 0 ? 12 : 5;
     362                 :           0 :                                                 break;
     363                 :             :                                         default:
     364                 :           0 :                                                 ku = kubun == 0 ? 14 : 13;
     365                 :           0 :                                                 break;
     366                 :             :                                 }
     367                 :           0 :                         }
     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                 :           0 :                                                                                         (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                 :           0 :                         }
     384                 :             :                         else
     385                 :             :                         {
     386         [ #  # ]:           0 :                                 if (noError)
     387                 :           0 :                                         break;
     388                 :           0 :                                 report_invalid_encoding(PG_SHIFT_JIS_2004,
     389                 :           0 :                                                                                 (const char *) sjis, len);
     390                 :             :                         }
     391                 :             : 
     392         [ +  - ]:          21 :                         if (plane == 2)
     393                 :           0 :                                 *p++ = SS3;
     394                 :             : 
     395                 :          21 :                         *p++ = ku + 0xa0;
     396                 :          21 :                         *p++ = ten + 0xa0;
     397      [ -  -  + ]:          21 :                 }
     398                 :          21 :                 sjis += l;
     399                 :          21 :                 len -= l;
     400                 :             :         }
     401                 :          28 :         *p = '\0';
     402                 :             : 
     403                 :          56 :         return sjis - start;
     404                 :          28 : }
        

Generated by: LCOV version 2.3.2-1