tst-iconv5.c 3.8 KB

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