(root)/
glibc-2.38/
iconv/
tst-iconv5.c
       1  /* Copyright (C) 2004-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <iconv.h>
      19  #include <string.h>
      20  #include <stdlib.h>
      21  #include <stdio.h>
      22  #include <errno.h>
      23  
      24  #define SIZE 256		/* enough room for conversion */
      25  #define SAMPLESTR "abc"
      26  
      27  struct unalign
      28  {
      29    char str1[1];
      30    char str2[SIZE];
      31  };
      32  
      33  struct convcode
      34  {
      35    const char *tocode;
      36    const char *fromcode;
      37  };
      38  
      39  /* test builtin transformation */
      40  static const struct convcode testcode[] = {
      41    {"ASCII", "ASCII"},
      42    {"UTF-8", "ASCII"},
      43    {"UCS-2BE", "ASCII"},
      44    {"UCS-2LE", "ASCII"},
      45    {"UCS-4BE", "ASCII"},
      46    {"UCS-4LE", "ASCII"},
      47  };
      48  
      49  static const int number = (int) sizeof (testcode) / sizeof (struct convcode);
      50  
      51  static int
      52  convert (const char *tocode, const char *fromcode, char *inbufp,
      53  	 size_t inbytesleft, char *outbufp, size_t outbytesleft)
      54  {
      55    iconv_t *ic;
      56    size_t outbytes = outbytesleft;
      57    int ret;
      58  
      59    ic = iconv_open (tocode, fromcode);
      60    if (ic == (iconv_t *) - 1)
      61      {
      62        printf ("iconv_open failed: from: %s, to: %s: %s",
      63  	      fromcode, tocode, strerror (errno));
      64        return -1;
      65      }
      66  
      67    while (inbytesleft > 0)
      68      {
      69        ret = iconv (ic, &inbufp, &inbytesleft, &outbufp, &outbytes);
      70        if (ret == -1)
      71  	{
      72  	  printf ("iconv failed: from: %s, to: %s: %s",
      73  		  fromcode, tocode, strerror (errno));
      74  	  iconv_close (ic);
      75  	  return -1;
      76  	}
      77      }
      78  
      79    ret = iconv_close (ic);
      80    if (ret == -1)
      81      {
      82        printf ("iconv_close failed: from: %s, to: %s: %s",
      83  	      fromcode, tocode, strerror (errno));
      84        return -1;
      85      }
      86  
      87    return outbytesleft - outbytes;
      88  }
      89  
      90  
      91  static int
      92  test_unalign (const struct convcode *codes, const char *str, int len)
      93  {
      94    struct unalign *inbufp, *outbufp;
      95    char *inbuf, *outbuf;
      96    size_t inbytesleft, outbytesleft;
      97    int retlen;
      98  
      99    /* allocating unaligned buffer for both inbuf and outbuf */
     100    inbufp = (struct unalign *) malloc (sizeof (struct unalign));
     101    if (!inbufp)
     102      {
     103        printf ("no memory available\n");
     104        exit (1);
     105      }
     106    inbuf = inbufp->str2;
     107  
     108    outbufp = (struct unalign *) malloc (sizeof (struct unalign));
     109    if (!outbufp)
     110      {
     111        printf ("no memory available\n");
     112        exit (1);
     113      }
     114    outbuf = outbufp->str2;
     115  
     116    /* first iconv phase */
     117    memcpy (inbuf, str, len);
     118    inbytesleft = len;
     119    outbytesleft = sizeof (struct unalign);
     120    retlen = convert (codes->tocode, codes->fromcode, inbuf, inbytesleft,
     121  		    outbuf, outbytesleft);
     122    if (retlen == -1)	/* failed */
     123      return 1;
     124  
     125    /* second round trip iconv phase */
     126    memcpy (inbuf, outbuf, retlen);
     127    inbytesleft = retlen;
     128    outbytesleft = sizeof (struct unalign);
     129    retlen = convert (codes->fromcode, codes->tocode, inbuf, inbytesleft,
     130  		    outbuf, outbytesleft);
     131    if (retlen == -1)	/* failed */
     132      return 1;
     133  
     134    free (inbufp);
     135    free (outbufp);
     136  
     137    return 0;
     138  }
     139  
     140  static int
     141  do_test (void)
     142  {
     143    int i;
     144    int ret = 0;
     145  
     146    for (i = 0; i < number; i++)
     147      {
     148        ret = test_unalign (&testcode[i], (char *) SAMPLESTR, sizeof (SAMPLESTR));
     149        if (ret)
     150  	break;
     151        printf ("iconv: %s <-> %s: ok\n",
     152  	      testcode[i].fromcode, testcode[i].tocode);
     153      }
     154    if (ret == 0)
     155      printf ("Succeeded.\n");
     156  
     157    return ret;
     158  }
     159  
     160  #define TEST_FUNCTION do_test ()
     161  #include "../test-skeleton.c"