Coverage Report

Created: 2026-01-10 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/vlc/src/extras/libc.c
Line
Count
Source
1
/*****************************************************************************
2
 * libc.c: Extra libc function for some systems.
3
 *****************************************************************************
4
 * Copyright (C) 2002-2006 VLC authors and VideoLAN
5
 *
6
 * Authors: Gildas Bazin <gbazin@videolan.org>
7
 *
8
 * This program is free software; you can redistribute it and/or modify it
9
 * under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation; either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program; if not, write to the Free Software Foundation,
20
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21
 *****************************************************************************/
22
#ifdef HAVE_CONFIG_H
23
# include "config.h"
24
#endif
25
26
#include <vlc_common.h>
27
#include <vlc_charset.h>
28
29
#include <errno.h>
30
31
#undef iconv_t
32
#undef iconv_open
33
#undef iconv
34
#undef iconv_close
35
36
#if defined(HAVE_ICONV)
37
#   include <iconv.h>
38
#endif
39
40
#if defined(__OS2__) && defined(__INNOTEK_LIBC__)
41
#   include <uconv.h>
42
43
typedef struct os2_iconv_t
44
{
45
    UconvObject from;
46
} os2_iconv_t;
47
#endif
48
49
/*****************************************************************************
50
 * Conversion table from ISO_6937 to UCS-4 charset. The table adds Euro sign
51
 * (0xA4) as per ETSI EN 300 468 Annex A
52
 *****************************************************************************/
53
#ifndef __linux__
54
static const uint16_t ISO6937toUCS4[256] =
55
{
56
  /* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
57
  /* 0x08 */ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
58
  /* 0x10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
59
  /* 0x18 */ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
60
  /* 0x20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
61
  /* 0x28 */ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
62
  /* 0x30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
63
  /* 0x38 */ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
64
  /* 0x40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
65
  /* 0x48 */ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
66
  /* 0x50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
67
  /* 0x58 */ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
68
  /* 0x60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
69
  /* 0x68 */ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
70
  /* 0x70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
71
  /* 0x78 */ 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
72
  /* 0x80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
73
  /* 0x88 */ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
74
  /* 0x90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
75
  /* 0x98 */ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
76
  /* 0xa0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0000, 0x00a7,
77
  /* 0xa8 */ 0x00a4, 0x2018, 0x201c, 0x00ab, 0x2190, 0x2191, 0x2192, 0x2193,
78
  /* 0xb0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7,
79
  /* 0xb8 */ 0x00f7, 0x2019, 0x201d, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
80
  /* 0xc0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
81
  /* 0xc8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
82
  /* 0xd0 */ 0x2014, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x266a, 0x00ac, 0x00a6,
83
  /* 0xd8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e,
84
  /* 0xe0 */ 0x2126, 0x00c6, 0x00d0, 0x00aa, 0x0126, 0x0000, 0x0132, 0x013f,
85
  /* 0xe8 */ 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0x0149,
86
  /* 0xf0 */ 0x0138, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0140,
87
  /* 0xf8 */ 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x00ad
88
};
89
90
/*****************************************************************************
91
 * Conversion table from ISO_6937-2 (6937_2:1983/Add.1:1989) to UCS-4 charset.
92
 * Based on glibc's iso_6937-2.c with the following additions:
93
 * U+00A0 (0xa0), U+00AC (0xd6), U+00A6 (0xd7), U+00AD (0xff)
94
 *****************************************************************************/
95
static const uint16_t ISO6937_2toUCS4[256] =
96
{
97
  /* 0x00 */ 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
98
  /* 0x08 */ 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
99
  /* 0x10 */ 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
100
  /* 0x18 */ 0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
101
  /* 0x20 */ 0x0020, 0x0021, 0x0022, 0x0023, 0x00a4, 0x0025, 0x0026, 0x0027,
102
  /* 0x28 */ 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
103
  /* 0x30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
104
  /* 0x38 */ 0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
105
  /* 0x40 */ 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
106
  /* 0x48 */ 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
107
  /* 0x50 */ 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
108
  /* 0x58 */ 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
109
  /* 0x60 */ 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
110
  /* 0x68 */ 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
111
  /* 0x70 */ 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
112
  /* 0x78 */ 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
113
  /* 0x80 */ 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
114
  /* 0x88 */ 0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
115
  /* 0x90 */ 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
116
  /* 0x98 */ 0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
117
  /* 0xa0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x0024, 0x00a5, 0x0023, 0x00a7,
118
  /* 0xa8 */ 0x00a4, 0x2018, 0x201c, 0x00ab, 0x2190, 0x2191, 0x2192, 0x2193,
119
  /* 0xb0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7,
120
  /* 0xb8 */ 0x00f7, 0x2019, 0x201d, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
121
  /* 0xc0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
122
  /* 0xc8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
123
  /* 0xd0 */ 0x2014, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x266a, 0x00ac, 0x00a6,
124
  /* 0xd8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e,
125
  /* 0xe0 */ 0x2126, 0x00c6, 0x00d0, 0x00aa, 0x0126, 0x0000, 0x0132, 0x013f,
126
  /* 0xe8 */ 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0x0149,
127
  /* 0xf0 */ 0x0138, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0140,
128
  /* 0xf8 */ 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x00ad
129
};
130
131
/* The outer array range runs from 0xc1 to 0xcf, the inner range from 0x40
132
   to 0x7f.  */
133
static const uint16_t to_ucs4_comb[15][64] =
134
{
135
  /* 0xc1 */
136
  {
137
    /* 0x40 */ 0x0000, 0x00c0, 0x0000, 0x0000, 0x0000, 0x00c8, 0x0000, 0x0000,
138
    /* 0x48 */ 0x0000, 0x00cc, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d2,
139
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d9, 0x0000, 0x0000,
140
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
141
    /* 0x60 */ 0x0000, 0x00e0, 0x0000, 0x0000, 0x0000, 0x00e8, 0x0000, 0x0000,
142
    /* 0x68 */ 0x0000, 0x00ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f2,
143
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f9, 0x0000, 0x0000,
144
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
145
  },
146
  /* 0xc2 */
147
  {
148
    /* 0x40 */ 0x0000, 0x00c1, 0x0000, 0x0106, 0x0000, 0x00c9, 0x0000, 0x0000,
149
    /* 0x48 */ 0x0000, 0x00cd, 0x0000, 0x0000, 0x0139, 0x0000, 0x0143, 0x00d3,
150
    /* 0x50 */ 0x0000, 0x0000, 0x0154, 0x015a, 0x0000, 0x00da, 0x0000, 0x0000,
151
    /* 0x58 */ 0x0000, 0x00dd, 0x0179, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
152
    /* 0x60 */ 0x0000, 0x00e1, 0x0000, 0x0107, 0x0000, 0x00e9, 0x0000, 0x0123,
153
    /* 0x68 */ 0x0000, 0x00ed, 0x0000, 0x0000, 0x013a, 0x0000, 0x0144, 0x00f3,
154
    /* 0x70 */ 0x0000, 0x0000, 0x0155, 0x015b, 0x0000, 0x00fa, 0x0000, 0x0000,
155
    /* 0x78 */ 0x0000, 0x00fd, 0x017a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
156
  },
157
  /* 0xc3 */
158
  {
159
    /* 0x40 */ 0x0000, 0x00c2, 0x0000, 0x0108, 0x0000, 0x00ca, 0x0000, 0x011c,
160
    /* 0x48 */ 0x0124, 0x00ce, 0x0134, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d4,
161
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x015c, 0x0000, 0x00db, 0x0000, 0x0174,
162
    /* 0x58 */ 0x0000, 0x0176, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
163
    /* 0x60 */ 0x0000, 0x00e2, 0x0000, 0x0109, 0x0000, 0x00ea, 0x0000, 0x011d,
164
    /* 0x68 */ 0x0125, 0x00ee, 0x0135, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f4,
165
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x015d, 0x0000, 0x00fb, 0x0000, 0x0175,
166
    /* 0x78 */ 0x0000, 0x0177, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
167
  },
168
  /* 0xc4 */
169
  {
170
    /* 0x40 */ 0x0000, 0x00c3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
171
    /* 0x48 */ 0x0000, 0x0128, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d1, 0x00d5,
172
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0168, 0x0000, 0x0000,
173
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
174
    /* 0x60 */ 0x0000, 0x00e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
175
    /* 0x68 */ 0x0000, 0x0129, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f1, 0x00f5,
176
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0169, 0x0000, 0x0000,
177
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
178
  },
179
  /* 0xc5 */
180
  {
181
    /* 0x40 */ 0x0000, 0x0100, 0x0000, 0x0000, 0x0000, 0x0112, 0x0000, 0x0000,
182
    /* 0x48 */ 0x0000, 0x012a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014c,
183
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016a, 0x0000, 0x0000,
184
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
185
    /* 0x60 */ 0x0000, 0x0101, 0x0000, 0x0000, 0x0000, 0x0113, 0x0000, 0x0000,
186
    /* 0x68 */ 0x0000, 0x012b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x014d,
187
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016b, 0x0000, 0x0000,
188
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
189
  },
190
  /* 0xc6 */
191
  {
192
    /* 0x40 */ 0x0000, 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011e,
193
    /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
194
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x0000, 0x0000,
195
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
196
    /* 0x60 */ 0x0000, 0x0103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011f,
197
    /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
198
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x0000, 0x0000,
199
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
200
  },
201
  /* 0xc7 */
202
  {
203
    /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x010a, 0x0000, 0x0116, 0x0000, 0x0120,
204
    /* 0x48 */ 0x0000, 0x0130, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
205
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
206
    /* 0x58 */ 0x0000, 0x0000, 0x017b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
207
    /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x010b, 0x0000, 0x0117, 0x0000, 0x0121,
208
    /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
209
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
210
    /* 0x78 */ 0x0000, 0x0000, 0x017c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
211
  },
212
  /* 0xc8 */
213
  {
214
    /* 0x40 */ 0x0000, 0x00c4, 0x0000, 0x0000, 0x0000, 0x00cb, 0x0000, 0x0000,
215
    /* 0x48 */ 0x0000, 0x00cf, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d6,
216
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00dc, 0x0000, 0x0000,
217
    /* 0x58 */ 0x0000, 0x0178, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
218
    /* 0x60 */ 0x0000, 0x00e4, 0x0000, 0x0000, 0x0000, 0x00eb, 0x0000, 0x0000,
219
    /* 0x68 */ 0x0000, 0x00ef, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f6,
220
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00fc, 0x0000, 0x0000,
221
    /* 0x78 */ 0x0000, 0x00ff, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
222
  },
223
  /* 0xc9 */
224
  {
225
    0x0000,
226
  },
227
  /* 0xca */
228
  {
229
    /* 0x40 */ 0x0000, 0x00c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
230
    /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
231
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016e, 0x0000, 0x0000,
232
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
233
    /* 0x60 */ 0x0000, 0x00e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
234
    /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
235
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016f, 0x0000, 0x0000,
236
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
237
  },
238
  /* 0xcb */
239
  {
240
    /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x00c7, 0x0000, 0x0000, 0x0000, 0x0122,
241
    /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0136, 0x013b, 0x0000, 0x0145, 0x0000,
242
    /* 0x50 */ 0x0000, 0x0000, 0x0156, 0x015e, 0x0162, 0x0000, 0x0000, 0x0000,
243
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
244
    /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x00e7, 0x0000, 0x0000, 0x0000, 0x0123,
245
    /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0137, 0x013c, 0x0000, 0x0146, 0x0000,
246
    /* 0x70 */ 0x0000, 0x0000, 0x0157, 0x015f, 0x0163, 0x0000, 0x0000, 0x0000,
247
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
248
  },
249
  /* 0xcc */
250
  {
251
    0x0000,
252
  },
253
  /* 0xcd */
254
  {
255
    /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
256
    /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0150,
257
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0170, 0x0000, 0x0000,
258
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
259
    /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
260
    /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0151,
261
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0171, 0x0000, 0x0000,
262
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
263
  },
264
  /* 0xce */
265
  {
266
    /* 0x40 */ 0x0000, 0x0104, 0x0000, 0x0000, 0x0000, 0x0118, 0x0000, 0x0000,
267
    /* 0x48 */ 0x0000, 0x012e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
268
    /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0172, 0x0000, 0x0000,
269
    /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
270
    /* 0x60 */ 0x0000, 0x0105, 0x0000, 0x0000, 0x0000, 0x0119, 0x0000, 0x0000,
271
    /* 0x68 */ 0x0000, 0x012f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
272
    /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0173, 0x0000, 0x0000,
273
    /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
274
  },
275
  /* 0xcf */
276
  {
277
    /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x010c, 0x010e, 0x011a, 0x0000, 0x0000,
278
    /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013d, 0x0000, 0x0147, 0x0000,
279
    /* 0x50 */ 0x0000, 0x0000, 0x0158, 0x0160, 0x0164, 0x0000, 0x0000, 0x0000,
280
    /* 0x58 */ 0x0000, 0x0000, 0x017d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
281
    /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x010d, 0x010f, 0x011b, 0x0000, 0x0000,
282
    /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x013e, 0x0000, 0x0148, 0x0000,
283
    /* 0x70 */ 0x0000, 0x0000, 0x0159, 0x0161, 0x0165, 0x0000, 0x0000, 0x0000,
284
    /* 0x78 */ 0x0000, 0x0000, 0x017e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
285
  }
286
};
287
288
/*****************************************************************************
289
 * Local conversion routine from ISO_6937 and ISO_6937-2 to UTF-8 charset.
290
 * Support for this is still missing in libiconv.
291
 *****************************************************************************/
292
static size_t ISO6937toUTF8( const char **inbuf, size_t *inbytesleft,
293
                             unsigned char **outbuf, size_t *outbytesleft,
294
                             const uint16_t *ucs4_table )
295
296
297
{
298
    if( !inbuf || !(*inbuf) )
299
        return (size_t)(0);    /* Reset state requested */
300
301
    const char *iptr = *inbuf;
302
    const char *iend = iptr + *inbytesleft;
303
    unsigned char *optr = *outbuf;
304
    unsigned char *oend = optr + *outbytesleft;
305
    int err = 0;
306
307
    while ( iptr < iend )
308
    {
309
        unsigned char c1 = *iptr;
310
        uint_fast16_t ch = ucs4_table[c1];
311
312
        if( c1 >= 0xc1 && c1 <= 0xcf )
313
        {
314
            /* Composed character */
315
            if ( iptr + 1 >= iend )
316
            {
317
                err = EINVAL;
318
                break;    /* No next character */
319
            }
320
321
            unsigned char c2 = iptr[1];
322
            if ( c2 < 0x40 || c2 >= 0x80 ||
323
                 !(ch = to_ucs4_comb[c1 - 0xc1][c2 - 0x40]) )
324
            {
325
                err = EILSEQ;
326
                break;   /* Illegal combination */
327
            }
328
            iptr += 2;
329
330
        }
331
        else
332
        {
333
            if ( !ch )
334
            {
335
                err = EILSEQ;
336
                break;
337
            }
338
            iptr++;
339
        }
340
341
        if( ch < 0x80 )
342
        {
343
            if( optr >= oend )
344
            {
345
                err = E2BIG;
346
                break;    /* No space in outbuf */
347
            }
348
            *optr++ = ch;
349
        }
350
        else if ( ch < 0x800 )
351
        {
352
            if ( optr + 1 >= oend )
353
            {
354
                err = E2BIG;
355
                break;
356
            }
357
358
            optr[1] = 0x80 | (ch & 0x3f);
359
            optr[0] = 0xc0 | (ch >> 6);
360
            optr +=2;
361
        }
362
        else
363
        {
364
            if ( optr + 2 >= oend )
365
            {
366
                err = E2BIG;
367
                break;
368
            }
369
370
            optr[2] = 0x80 | (ch & 0x3f);
371
            ch >>= 6;
372
            optr[1] = 0x80 | (ch & 0x3f);
373
            optr[0] = 0xe0 | (ch >> 6);
374
            optr += 3;
375
        }
376
377
    }
378
    *inbuf = iptr;
379
    *outbuf = optr;
380
    *inbytesleft = iend - iptr;
381
    *outbytesleft = oend - optr;
382
383
    if( err )
384
    {
385
        errno = err;
386
        return (size_t)(-1);
387
    }
388
389
    return (size_t)(0);
390
391
}
392
#endif
393
394
/*****************************************************************************
395
 * iconv wrapper
396
 *****************************************************************************/
397
vlc_iconv_t vlc_iconv_open( const char *tocode, const char *fromcode )
398
251k
{
399
#ifndef __linux__
400
    if( !strcasecmp(tocode, "UTF-8") && !strcasecmp(fromcode, "ISO_6937") )
401
        return (vlc_iconv_t)(-2);
402
    else if( !strcasecmp(tocode, "UTF-8") && !strcasecmp(fromcode, "ISO_6937-2") )
403
        return (vlc_iconv_t)(-3);
404
#endif
405
251k
#if defined(HAVE_ICONV)
406
# if defined(__OS2__) && defined(__INNOTEK_LIBC__)
407
    char tocode_ucs2[] = "UCS-2LE";
408
    char fromcode_ucs2[] = "UCS-2LE";
409
    os2_iconv_t *p_os2_iconv;
410
411
    /* Workaround for UTF-16 because OS/2 supports UCS-2 only not UTF-16 */
412
    if( !strncmp( tocode, "UTF-16", 6 ))
413
    {
414
        strncpy( tocode_ucs2 + 5, tocode + 6, 2 );
415
        tocode = tocode_ucs2;
416
    }
417
418
    if( !strncmp( fromcode, "UTF-16", 6 ))
419
    {
420
        strncpy( fromcode_ucs2 + 5, fromcode + 6, 2 );
421
        fromcode = fromcode_ucs2;
422
    }
423
424
    p_os2_iconv = ( os2_iconv_t * )iconv_open( tocode, fromcode );
425
426
    if( p_os2_iconv != ( iconv_t )(-1))
427
    {
428
        /* Mimic a behavior of GNU libiconv */
429
        uconv_attribute_t attr;
430
431
        UniQueryUconvObject( p_os2_iconv->from, &attr,
432
                             sizeof( uconv_attribute_t ),
433
                             NULL, NULL, NULL );
434
        attr.converttype |= CVTTYPE_PATH;
435
        UniSetUconvObject( p_os2_iconv->from, &attr );
436
    }
437
438
    return ( vlc_iconv_t )p_os2_iconv;
439
# else
440
251k
    return iconv_open( tocode, fromcode );
441
251k
# endif
442
#else
443
    return (vlc_iconv_t)(-1);
444
#endif
445
251k
}
446
447
size_t vlc_iconv( vlc_iconv_t cd, const char **inbuf, size_t *inbytesleft,
448
                  char **outbuf, size_t *outbytesleft )
449
411k
{
450
411k
    size_t ret;
451
452
#ifndef __linux__
453
    if ( cd == (vlc_iconv_t)(-2) || cd == (vlc_iconv_t)(-3) )
454
    {
455
        unsigned char *out = NULL;
456
        if (outbuf != NULL)
457
            out = (unsigned char *)*outbuf;
458
459
        const uint16_t *ucs4_table = ( cd == (vlc_iconv_t)(-2) ? ISO6937toUCS4 : ISO6937_2toUCS4 );
460
461
        ret = ISO6937toUTF8( inbuf, inbytesleft, &out, outbytesleft, ucs4_table );
462
        if (outbuf != NULL)
463
            *outbuf = (char *)out;
464
    }
465
    else
466
#endif
467
411k
#if defined(HAVE_ICONV)
468
411k
    {
469
411k
        ICONV_CONST char *cin = NULL;
470
411k
        if (inbuf != NULL)
471
409k
            cin = (ICONV_CONST char *)*inbuf;
472
473
411k
        ret = iconv( cd, &cin, inbytesleft, outbuf, outbytesleft );
474
411k
        if (inbuf != NULL)
475
409k
            *inbuf = cin;
476
411k
    }
477
#else
478
        abort ();
479
#endif
480
411k
    return ret;
481
411k
}
482
483
int vlc_iconv_close( vlc_iconv_t cd )
484
251k
{
485
#ifndef __linux__
486
    if ( cd == (vlc_iconv_t)(-2) || cd == (vlc_iconv_t)(-3) )
487
        return 0;
488
#endif
489
251k
#if defined(HAVE_ICONV)
490
251k
    return iconv_close( cd );
491
#else
492
    abort ();
493
#endif
494
251k
}
495
496
/*****************************************************************************
497
 * reduce a fraction
498
 *   (adapted from libavcodec, author Michael Niedermayer <michaelni@gmx.at>)
499
 *****************************************************************************/
500
bool vlc_ureduce( unsigned *pi_dst_nom, unsigned *pi_dst_den,
501
                        uint64_t i_nom, uint64_t i_den, uint64_t i_max )
502
41.0k
{
503
41.0k
    bool b_exact = 1;
504
41.0k
    uint64_t i_gcd;
505
506
41.0k
    if( i_den == 0 )
507
13.2k
    {
508
13.2k
        *pi_dst_nom = 0;
509
13.2k
        *pi_dst_den = 1;
510
13.2k
        return 1;
511
13.2k
    }
512
513
27.7k
    i_gcd = GCD( i_nom, i_den );
514
27.7k
    i_nom /= i_gcd;
515
27.7k
    i_den /= i_gcd;
516
517
27.7k
    if( i_max == 0 ) i_max = INT64_C(0xFFFFFFFF);
518
519
27.7k
    if( i_nom > i_max || i_den > i_max )
520
204
    {
521
204
        uint64_t i_a0_num = 0, i_a0_den = 1, i_a1_num = 1, i_a1_den = 0;
522
204
        b_exact = 0;
523
524
204
        for( ; ; )
525
1.21k
        {
526
1.21k
            uint64_t i_x = i_nom / i_den;
527
1.21k
            uint64_t i_a2n = i_x * i_a1_num + i_a0_num;
528
1.21k
            uint64_t i_a2d = i_x * i_a1_den + i_a0_den;
529
530
1.21k
            if( i_a2n > i_max || i_a2d > i_max ) break;
531
532
1.01k
            i_nom %= i_den;
533
534
1.01k
            i_a0_num = i_a1_num; i_a0_den = i_a1_den;
535
1.01k
            i_a1_num = i_a2n; i_a1_den = i_a2d;
536
1.01k
            if( i_nom == 0 ) break;
537
1.01k
            i_x = i_nom; i_nom = i_den; i_den = i_x;
538
1.01k
        }
539
204
        i_nom = i_a1_num;
540
204
        i_den = i_a1_den;
541
204
    }
542
543
27.7k
    *pi_dst_nom = i_nom;
544
27.7k
    *pi_dst_den = i_den;
545
546
27.7k
    return b_exact;
547
41.0k
}