1 /*
2     libzint - the open source barcode library
3     Copyright (C) 2019 - 2021 Robin Stuart <rstuart114@gmail.com>
4 
5     Redistribution and use in source and binary forms, with or without
6     modification, are permitted provided that the following conditions
7     are met:
8 
9     1. Redistributions of source code must retain the above copyright
10        notice, this list of conditions and the following disclaimer.
11     2. Redistributions in binary form must reproduce the above copyright
12        notice, this list of conditions and the following disclaimer in the
13        documentation and/or other materials provided with the distribution.
14     3. Neither the name of the project nor the names of its contributors
15        may be used to endorse or promote products derived from this software
16        without specific prior written permission.
17 
18     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20     IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21     ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22     FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23     DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24     OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25     HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27     OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28     SUCH DAMAGE.
29  */
30 /* vim: set ts=4 sw=4 et norl : */
31 
32 #include "testcommon.h"
33 #include "../eci.h"
34 
test_bom(int debug)35 static void test_bom(int debug) {
36 
37     char data[] = "\xEF\xBB\xBF‹"; // U+FEFF BOM, with U+2039 (only in Windows pages)
38 
39     char expected[] =
40         "111111100001001111111"
41         "100000101110101000001"
42         "101110100000101011101"
43         "101110100111101011101"
44         "101110100110101011101"
45         "100000101011001000001"
46         "111111101010101111111"
47         "000000001100100000000"
48         "000011110110101100010"
49         "010011011100000100001"
50         "111110110001011111000"
51         "000110000110001011100"
52         "000111110111100001011"
53         "000000001011001000111"
54         "111111101010111001010"
55         "100000101110101101010"
56         "101110101110001110101"
57         "101110100001100101001"
58         "101110100111111111100"
59         "100000100010011010111"
60         "111111100101101000101";
61 
62     int length, ret;
63     struct zint_symbol *symbol;
64 
65     int width, height;
66 
67     testStart("test_bom");
68 
69     symbol = ZBarcode_Create();
70     assert_nonnull(symbol, "Symbol not created\n");
71 
72     symbol->symbology = BARCODE_QRCODE;
73     symbol->input_mode = UNICODE_MODE;
74     symbol->option_1 = 4;
75     symbol->option_2 = 1;
76     symbol->option_3 = 5 << 8; // Mask 100 (instead of automatic 010)
77     symbol->debug |= debug;
78 
79     length = (int) strlen(data);
80 
81     ret = ZBarcode_Encode(symbol, (unsigned char *) data, length);
82     assert_equal(ret, ZINT_WARN_USES_ECI, "ZBarcode_Encode ret %d != ZINT_WARN_USES_ECI\n", ret);
83     assert_equal(symbol->eci, 21, "eci %d != 21\n", symbol->eci); // ECI 21 == Windows-1250
84 
85     ret = testUtilModulesCmp(symbol, expected, &width, &height);
86     assert_equal(ret, 0, "testUtilModulesEqual ret %d != 0, width %d, height %d\n", ret, width, height);
87 
88     ZBarcode_Delete(symbol);
89 
90     testFinish();
91 }
92 
test_iso_8859_16(int debug)93 static void test_iso_8859_16(int debug) {
94 
95     char data[] = "Ț"; // U+021A only in ISO 8859-16
96     int length, ret;
97     struct zint_symbol *symbol;
98 
99     testStart("test_iso_8859_16");
100 
101     symbol = ZBarcode_Create();
102     assert_nonnull(symbol, "Symbol not created\n");
103 
104     symbol->symbology = BARCODE_QRCODE;
105     symbol->input_mode = UNICODE_MODE;
106     symbol->debug |= debug;
107 
108     length = (int) strlen(data);
109 
110     ret = ZBarcode_Encode(symbol, (unsigned char *) data, length);
111     assert_equal(ret, ZINT_WARN_USES_ECI, "ZBarcode_Encode ret %d != ZINT_WARN_USES_ECI\n", ret);
112     assert_equal(symbol->eci, 18, "eci %d != 18\n", symbol->eci); // ECI 18 == ISO 8859-16
113 
114     ZBarcode_Delete(symbol);
115 
116     testFinish();
117 }
118 
119 // Only testing standard non-extended barcodes here, ie not QRCODE, MICROQR, GRIDMATRIX, HANXIN or UPNQR
test_reduced_charset_input(int index,int debug)120 static void test_reduced_charset_input(int index, int debug) {
121 
122     struct item {
123         int symbology;
124         int input_mode;
125         int eci;
126         char *data;
127         int ret;
128         int expected_eci;
129         char *comment;
130     };
131     // é U+00E9 in ISO 8859-1 plus other ISO 8859 (but not in ISO 8859-7 or ISO 8859-11), Win 1250 plus other Win, not in Shift JIS
132     // β U+03B2 in ISO 8859-7 Greek (but not other ISO 8859 or Win page), in Shift JIS
133     // ก U+0E01 in ISO 8859-11 Thai (but not other ISO 8859 or Win page), not in Shift JIS
134     // Ж U+0416 in ISO 8859-5 Cyrillic (but not other ISO 8859), Win 1251, in Shift JIS
135     // ກ U+0E81 Lao not in any ISO 8859 (or Win page) or Shift JIS
136     // … U+2026 in Win pages (but not in any ISO 8859)
137     // テ U+30C6 katakana, in Shift JIS
138     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
139     struct item data[] = {
140         /*  0*/ { BARCODE_CODE11, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
141         /*  1*/ { BARCODE_C25STANDARD, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
142         /*  2*/ { BARCODE_CODE39, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
143         /*  3*/ { BARCODE_EXCODE39, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII only" },
144         /*  4*/ { BARCODE_EANX, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
145         /*  5*/ { BARCODE_CODABAR, UNICODE_MODE, 0, "AéB", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
146         /*  6*/ { BARCODE_CODE128, UNICODE_MODE, 0, "é", 0, 0, "" },
147         /*  7*/ { BARCODE_CODE128, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
148         /*  8*/ { BARCODE_CODE128, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
149         /*  9*/ { BARCODE_DPLEIT, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
150         /* 10*/ { BARCODE_CODE16K, UNICODE_MODE, 0, "é", 0, 0, "" },
151         /* 11*/ { BARCODE_CODE16K, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
152         /* 12*/ { BARCODE_CODE16K, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
153         /* 13*/ { BARCODE_CODE49, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII only" },
154         /* 14*/ { BARCODE_CODE93, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
155         /* 15*/ { BARCODE_FLAT, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
156         /* 16*/ { BARCODE_DBAR_OMN, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
157         /* 17*/ { BARCODE_DBAR_EXP, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
158         /* 18*/ { BARCODE_LOGMARS, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "ASCII subset only" },
159         /* 19*/ { BARCODE_PDF417, UNICODE_MODE, 0, "é", 0, 0, "" },
160         /* 20*/ { BARCODE_PDF417, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
161         /* 21*/ { BARCODE_PDF417, UNICODE_MODE, 3, "\302\200", ZINT_ERROR_INVALID_DATA, -1, "U+0080" },
162         /* 22*/ { BARCODE_PDF417, UNICODE_MODE, 3, "\302\237", ZINT_ERROR_INVALID_DATA, -1, "U+009F" },
163         /* 23*/ { BARCODE_PDF417, UNICODE_MODE, 0, "˘", ZINT_WARN_USES_ECI, 4, "In ISO 8859-2 and ISO 8859-3 only of single-byte pages" },
164         /* 24*/ { BARCODE_PDF417, UNICODE_MODE, 4, "˘", 0, 4, "" },
165         /* 25*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ħ", ZINT_WARN_USES_ECI, 5, "In ISO 8859-3 only of single-byte pages" },
166         /* 26*/ { BARCODE_PDF417, UNICODE_MODE, 5, "Ħ", 0, 5, "" },
167         /* 27*/ { BARCODE_PDF417, UNICODE_MODE, 0, "ĸ", ZINT_WARN_USES_ECI, 6, "In ISO 8859-4 and ISO 8859-6 only of single-byte pages" },
168         /* 28*/ { BARCODE_PDF417, UNICODE_MODE, 6, "ĸ", 0, 6, "" },
169         /* 29*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ж", ZINT_WARN_USES_ECI, 7, "In ISO 8859-5 and Win 1251 only of single-byte pages" },
170         /* 30*/ { BARCODE_PDF417, UNICODE_MODE, 7, "Ж", 0, 7, "" },
171         /* 31*/ { BARCODE_PDF417, UNICODE_MODE, 0, "غ", ZINT_WARN_USES_ECI, 8, "In ISO 8859-6 and Win 1256 only of single-byte pages" },
172         /* 32*/ { BARCODE_PDF417, UNICODE_MODE, 8, "غ", 0, 8, "" },
173         /* 33*/ { BARCODE_PDF417, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "In ISO 8859-7 only of single-byte pages" },
174         /* 34*/ { BARCODE_PDF417, UNICODE_MODE, 9, "β", 0, 9, "" },
175         /* 35*/ { BARCODE_PDF417, UNICODE_MODE, 0, "‗", ZINT_WARN_USES_ECI, 10, "In ISO 8859-8 only of single-byte pages" },
176         /* 36*/ { BARCODE_PDF417, UNICODE_MODE, 10, "‗", 0, 10, "" },
177         /* 37*/ { BARCODE_PDF417, UNICODE_MODE, 11, "Ğ", 0, 11, "In ISO 8859-9; Note no characters in ISO 8859-9 that aren't also in earlier ISO pages" },
178         /* 38*/ { BARCODE_PDF417, UNICODE_MODE, 12, "Ĩ", 0, 12, "In ISO 8859-10; Note no characters in ISO 8859-10 that aren't also in earlier ISO pages" },
179         /* 39*/ { BARCODE_PDF417, UNICODE_MODE, 0, "ก", ZINT_WARN_USES_ECI, 13, "" },
180         /* 40*/ { BARCODE_PDF417, UNICODE_MODE, 13, "ก", 0, 13, "" },
181         /* 41*/ { BARCODE_PDF417, UNICODE_MODE, 14, "A", ZINT_ERROR_INVALID_DATA, -1, "Reserved ECI" },
182         /* 42*/ { BARCODE_PDF417, UNICODE_MODE, 0, "„", ZINT_WARN_USES_ECI, 15, "" },
183         /* 43*/ { BARCODE_PDF417, UNICODE_MODE, 15, "„", 0, 15, "In ISO 8859-13 and ISO 8859-16 and Win 125x pages" },
184         /* 44*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ḃ", ZINT_WARN_USES_ECI, 16, "In ISO 8859-14 only of single-byte pages" },
185         /* 45*/ { BARCODE_PDF417, UNICODE_MODE, 16, "Ḃ", 0, 16, "" },
186         /* 46*/ { BARCODE_PDF417, UNICODE_MODE, 17, "Ž", 0, 17, "In ISO 8859-15; Note no characters in ISO 8859-15 that aren't also in earlier ISO pages" },
187         /* 47*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ș", ZINT_WARN_USES_ECI, 18, "In ISO 8859-16 only of single-byte pages" },
188         /* 48*/ { BARCODE_PDF417, UNICODE_MODE, 18, "Ș", 0, 18, "" },
189         /* 49*/ { BARCODE_PDF417, UNICODE_MODE, 0, "テ", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" },
190         /* 50*/ { BARCODE_PDF417, UNICODE_MODE, 19, "A", ZINT_ERROR_INVALID_DATA, -1, "Reserved ECI" },
191         /* 51*/ { BARCODE_PDF417, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
192         /* 52*/ { BARCODE_PDF417, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
193         /* 53*/ { BARCODE_PDF417, UNICODE_MODE, 20, "\\\\", 0, 20, "In Shift JIS" },
194         /* 54*/ { BARCODE_PDF417, UNICODE_MODE, 0, "…", ZINT_WARN_USES_ECI, 21, "In Win 1250 and other Win pages but not in ISO pages" },
195         /* 55*/ { BARCODE_PDF417, UNICODE_MODE, 21, "…", 0, 21, "" },
196         /* 56*/ { BARCODE_PDF417, UNICODE_MODE, 0, "Ґ", ZINT_WARN_USES_ECI, 22, "In Win 1251 only of single-byte pages" },
197         /* 57*/ { BARCODE_PDF417, UNICODE_MODE, 22, "Ґ", 0, 22, "" },
198         /* 58*/ { BARCODE_PDF417, UNICODE_MODE, 0, "˜", ZINT_WARN_USES_ECI, 23, "In Win 1252 only of single-byte pages" },
199         /* 59*/ { BARCODE_PDF417, UNICODE_MODE, 23, "˜", 0, 23, "" },
200         /* 60*/ { BARCODE_PDF417, UNICODE_MODE, 0, "پ", ZINT_WARN_USES_ECI, 24, "In Win 1256 only of single-byte pages" },
201         /* 61*/ { BARCODE_PDF417, UNICODE_MODE, 24, "پ", 0, 24, "" },
202         /* 62*/ { BARCODE_PDF417, UNICODE_MODE, 0, "က", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" },
203         /* 63*/ { BARCODE_PDF417, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
204         /* 64*/ { BARCODE_PDF417, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
205         /* 65*/ { BARCODE_PDF417, UNICODE_MODE, 25, "12", 0, 25, "UCS-2BE ASCII" },
206         /* 66*/ { BARCODE_PDF417, UNICODE_MODE, 0, "��", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" },
207         /* 67*/ { BARCODE_PDF417, UNICODE_MODE, 25, "��", ZINT_ERROR_INVALID_DATA, -1, "Not in UCS-2BE (in Supplementary Plane)" },
208         /* 68*/ { BARCODE_PDF417, UNICODE_MODE, 0, "テ", ZINT_WARN_USES_ECI, 26, "Defaults to UTF-8 if not in any ISO 8859 or Win page" },
209         /* 69*/ { BARCODE_PDF417, UNICODE_MODE, 26, "テ", 0, 26, "" },
210         /* 70*/ { BARCODE_PDF417, UNICODE_MODE, 26, "テテ", 0, 26, "" },
211         /* 71*/ { BARCODE_PDF417, UNICODE_MODE, 27, "@", 0, 27, "ASCII" },
212         /* 72*/ { BARCODE_PDF417, UNICODE_MODE, 0, "龘", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" },
213         /* 73*/ { BARCODE_PDF417, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
214         /* 74*/ { BARCODE_PDF417, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
215         /* 75*/ { BARCODE_PDF417, UNICODE_MODE, 0, "齄", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" },
216         /* 76*/ { BARCODE_PDF417, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
217         /* 77*/ { BARCODE_PDF417, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
218         /* 78*/ { BARCODE_PDF417, UNICODE_MODE, 0, "가", ZINT_WARN_USES_ECI, 26, "Not in any single-byte page" },
219         /* 79*/ { BARCODE_PDF417, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
220         /* 80*/ { BARCODE_PDF417, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
221         /* 81*/ { BARCODE_PDF417, UNICODE_MODE, 31, "A", 0, 31, "Undefined character set ECI - ignored for character set conversion" },
222         /* 82*/ { BARCODE_PDF417, UNICODE_MODE, 170, "?", 0, 170, "ASCII invariant" },
223         /* 83*/ { BARCODE_PDF417, UNICODE_MODE, 170, "@", ZINT_ERROR_INVALID_DATA, -1, "Not in ASCII invariant" },
224         /* 84*/ { BARCODE_PDF417, UNICODE_MODE, 0, "\200", ZINT_ERROR_INVALID_DATA, -1, "Not UTF-8" },
225         /* 85*/ { BARCODE_PDF417, DATA_MODE, 899, "\200", 0, 899, "8-bit binary" },
226         /* 86*/ { BARCODE_PDF417, UNICODE_MODE, 900, "é", 0, 900, "Non-character set ECIs > 899 ignored for character set conversion" },
227         /* 87*/ { BARCODE_PDF417, UNICODE_MODE, 900, "β", 0, 900, "Non-character set ECIs > 899 ignored for character set conversion" },
228         /* 88*/ { BARCODE_PDF417COMP, UNICODE_MODE, 0, "é", 0, 0, "" },
229         /* 89*/ { BARCODE_PDF417COMP, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
230         /* 90*/ { BARCODE_PDF417COMP, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
231         /* 91*/ { BARCODE_PDF417COMP, UNICODE_MODE, 9, "β", 0, 9, "" },
232         /* 92*/ { BARCODE_PDF417COMP, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
233         /* 93*/ { BARCODE_PDF417COMP, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
234         /* 94*/ { BARCODE_PDF417COMP, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
235         /* 95*/ { BARCODE_PDF417COMP, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
236         /* 96*/ { BARCODE_PDF417COMP, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
237         /* 97*/ { BARCODE_PDF417COMP, UNICODE_MODE, 26, "テ", 0, 26, "" },
238         /* 98*/ { BARCODE_PDF417COMP, UNICODE_MODE, 26, "テテ", 0, 26, "" },
239         /* 99*/ { BARCODE_PDF417COMP, UNICODE_MODE, 27, "@", 0, 27, "ASCII" },
240         /*100*/ { BARCODE_PDF417COMP, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
241         /*101*/ { BARCODE_PDF417COMP, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
242         /*102*/ { BARCODE_PDF417COMP, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
243         /*103*/ { BARCODE_PDF417COMP, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
244         /*104*/ { BARCODE_PDF417COMP, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
245         /*105*/ { BARCODE_PDF417COMP, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
246         /*106*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "é", 0, 0, "" },
247         /*107*/ { BARCODE_MAXICODE, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
248         /*108*/ { BARCODE_MAXICODE, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
249         /*109*/ { BARCODE_MAXICODE, UNICODE_MODE, 9, "β", 0, 9, "" },
250         /*110*/ { BARCODE_MAXICODE, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
251         /*111*/ { BARCODE_MAXICODE, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
252         /*112*/ { BARCODE_MAXICODE, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
253         /*113*/ { BARCODE_MAXICODE, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
254         /*114*/ { BARCODE_MAXICODE, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
255         /*115*/ { BARCODE_MAXICODE, UNICODE_MODE, 26, "テ", 0, 26, "" },
256         /*116*/ { BARCODE_MAXICODE, UNICODE_MODE, 26, "テテ", 0, 26, "" },
257         /*117*/ { BARCODE_MAXICODE, UNICODE_MODE, 27, "@", 0, 27, "ASCII" },
258         /*118*/ { BARCODE_MAXICODE, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
259         /*119*/ { BARCODE_MAXICODE, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
260         /*120*/ { BARCODE_MAXICODE, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
261         /*121*/ { BARCODE_MAXICODE, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
262         /*122*/ { BARCODE_MAXICODE, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
263         /*123*/ { BARCODE_MAXICODE, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
264         /*124*/ { BARCODE_CODE128B, UNICODE_MODE, 0, "é", 0, 0, "" },
265         /*125*/ { BARCODE_CODE128B, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
266         /*126*/ { BARCODE_CODE128B, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
267         /*127*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "é", 0, 0, "" },
268         /*128*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
269         /*129*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
270         /*130*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 9, "β", 0, 9, "" },
271         /*131*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
272         /*132*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
273         /*133*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
274         /*134*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
275         /*135*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
276         /*136*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 26, "テ", 0, 26, "" },
277         /*137*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 26, "テテ", 0, 26, "" },
278         /*138*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
279         /*139*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
280         /*140*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
281         /*141*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
282         /*142*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
283         /*143*/ { BARCODE_DATAMATRIX, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
284         /*144*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 0, "é", 0, 0, "" },
285         /*145*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 3, "é", ZINT_ERROR_INVALID_OPTION, -1, "Does not support ECI" },
286         /*146*/ { BARCODE_CODABLOCKF, UNICODE_MODE, 0, "β", ZINT_ERROR_INVALID_DATA, -1, "β not in ISO 8859-1" },
287         /*147*/ { BARCODE_NVE18, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
288         /*148*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "é", 0, 0, "" },
289         /*149*/ { BARCODE_MICROPDF417, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
290         /*150*/ { BARCODE_MICROPDF417, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
291         /*151*/ { BARCODE_MICROPDF417, UNICODE_MODE, 9, "β", 0, 9, "" },
292         /*152*/ { BARCODE_MICROPDF417, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
293         /*153*/ { BARCODE_MICROPDF417, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
294         /*154*/ { BARCODE_MICROPDF417, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
295         /*155*/ { BARCODE_MICROPDF417, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
296         /*156*/ { BARCODE_MICROPDF417, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
297         /*157*/ { BARCODE_MICROPDF417, UNICODE_MODE, 26, "テ", 0, 26, "" },
298         /*158*/ { BARCODE_MICROPDF417, UNICODE_MODE, 26, "テテ", 0, 26, "" },
299         /*159*/ { BARCODE_MICROPDF417, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
300         /*160*/ { BARCODE_MICROPDF417, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
301         /*161*/ { BARCODE_MICROPDF417, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
302         /*162*/ { BARCODE_MICROPDF417, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
303         /*163*/ { BARCODE_MICROPDF417, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
304         /*164*/ { BARCODE_MICROPDF417, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
305         /*165*/ { BARCODE_USPS_IMAIL, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers/dash only" },
306         /*166*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "é", 0, 0, "" },
307         /*167*/ { BARCODE_AZTEC, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
308         /*168*/ { BARCODE_AZTEC, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
309         /*169*/ { BARCODE_AZTEC, UNICODE_MODE, 9, "β", 0, 9, "" },
310         /*170*/ { BARCODE_AZTEC, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
311         /*171*/ { BARCODE_AZTEC, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
312         /*172*/ { BARCODE_AZTEC, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
313         /*173*/ { BARCODE_AZTEC, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
314         /*174*/ { BARCODE_AZTEC, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
315         /*175*/ { BARCODE_AZTEC, UNICODE_MODE, 26, "テ", 0, 26, "" },
316         /*176*/ { BARCODE_AZTEC, UNICODE_MODE, 26, "テテ", 0, 26, "" },
317         /*177*/ { BARCODE_AZTEC, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
318         /*178*/ { BARCODE_AZTEC, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
319         /*179*/ { BARCODE_AZTEC, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
320         /*180*/ { BARCODE_AZTEC, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
321         /*181*/ { BARCODE_AZTEC, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
322         /*182*/ { BARCODE_AZTEC, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
323         /*183*/ { BARCODE_HIBC_128, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "HIBC ASCII subset only" },
324         /*184*/ { BARCODE_HIBC_AZTEC, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "HIBC ASCII subset only" },
325         /*185*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "é", 0, 0, "" },
326         /*186*/ { BARCODE_DOTCODE, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
327         /*187*/ { BARCODE_DOTCODE, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
328         /*188*/ { BARCODE_DOTCODE, UNICODE_MODE, 9, "β", 0, 9, "" },
329         /*189*/ { BARCODE_DOTCODE, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
330         /*190*/ { BARCODE_DOTCODE, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
331         /*191*/ { BARCODE_DOTCODE, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
332         /*192*/ { BARCODE_DOTCODE, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
333         /*193*/ { BARCODE_DOTCODE, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
334         /*194*/ { BARCODE_DOTCODE, UNICODE_MODE, 26, "テ", 0, 26, "" },
335         /*195*/ { BARCODE_DOTCODE, UNICODE_MODE, 26, "テテ", 0, 26, "" },
336         /*196*/ { BARCODE_DOTCODE, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
337         /*197*/ { BARCODE_DOTCODE, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
338         /*198*/ { BARCODE_DOTCODE, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
339         /*199*/ { BARCODE_DOTCODE, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
340         /*200*/ { BARCODE_DOTCODE, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
341         /*201*/ { BARCODE_DOTCODE, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
342         /*202*/ { BARCODE_AZRUNE, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers <= 255 only" },
343         /*203*/ { BARCODE_CODE32, UNICODE_MODE, 0, "é", ZINT_ERROR_INVALID_DATA, -1, "Numbers only" },
344         /*204*/ { BARCODE_CODEONE, UNICODE_MODE, 0, "é", 0, 0, "" },
345         /*205*/ { BARCODE_CODEONE, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
346         /*206*/ { BARCODE_CODEONE, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
347         /*207*/ { BARCODE_CODEONE, UNICODE_MODE, 9, "β", 0, 9, "" },
348         /*208*/ { BARCODE_CODEONE, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
349         /*209*/ { BARCODE_CODEONE, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
350         /*210*/ { BARCODE_CODEONE, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
351         /*211*/ { BARCODE_CODEONE, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
352         /*212*/ { BARCODE_CODEONE, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
353         /*213*/ { BARCODE_CODEONE, UNICODE_MODE, 26, "テ", 0, 26, "" },
354         /*214*/ { BARCODE_CODEONE, UNICODE_MODE, 26, "テテ", 0, 26, "" },
355         /*215*/ { BARCODE_CODEONE, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
356         /*216*/ { BARCODE_CODEONE, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
357         /*217*/ { BARCODE_CODEONE, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
358         /*218*/ { BARCODE_CODEONE, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
359         /*219*/ { BARCODE_CODEONE, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
360         /*220*/ { BARCODE_CODEONE, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
361         /*221*/ { BARCODE_ULTRA, UNICODE_MODE, 0, "é", 0, 0, "" },
362         /*222*/ { BARCODE_ULTRA, UNICODE_MODE, 3, "é", 0, 3, "Supports ECI" },
363         /*223*/ { BARCODE_ULTRA, UNICODE_MODE, 0, "β", ZINT_WARN_USES_ECI, 9, "" },
364         /*224*/ { BARCODE_ULTRA, UNICODE_MODE, 9, "β", 0, 9, "" },
365         /*225*/ { BARCODE_ULTRA, UNICODE_MODE, 20, "テ", 0, 20, "In Shift JIS" },
366         /*226*/ { BARCODE_ULTRA, UNICODE_MODE, 20, "テテ", 0, 20, "In Shift JIS" },
367         /*227*/ { BARCODE_ULTRA, UNICODE_MODE, 25, "က", 0, 25, "In UCS-2BE" },
368         /*228*/ { BARCODE_ULTRA, UNICODE_MODE, 25, "ကက", 0, 25, "In UCS-2BE" },
369         /*229*/ { BARCODE_ULTRA, UNICODE_MODE, 25, "12", 0, 25, "ASCII" },
370         /*230*/ { BARCODE_ULTRA, UNICODE_MODE, 26, "テ", 0, 26, "" },
371         /*231*/ { BARCODE_ULTRA, UNICODE_MODE, 26, "テテ", 0, 26, "" },
372         /*232*/ { BARCODE_ULTRA, UNICODE_MODE, 28, "龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
373         /*233*/ { BARCODE_ULTRA, UNICODE_MODE, 28, "龘龘", 0, 28, "U+9F98 in Big5 but not in GB2312" },
374         /*234*/ { BARCODE_ULTRA, UNICODE_MODE, 29, "齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
375         /*235*/ { BARCODE_ULTRA, UNICODE_MODE, 29, "齄齄", 0, 29, "U+9F44 in GB2312 but not in Big5" },
376         /*236*/ { BARCODE_ULTRA, UNICODE_MODE, 30, "가", 0, 30, "U+AC00 in EUC-KR" },
377         /*237*/ { BARCODE_ULTRA, UNICODE_MODE, 30, "가가", 0, 30, "U+AC00 in EUC-KR" },
378     };
379     int data_size = ARRAY_SIZE(data);
380     int i, length, ret;
381     struct zint_symbol *symbol;
382 
383     testStart("test_reduced_charset_input");
384 
385     for (i = 0; i < data_size; i++) {
386 
387         if (index != -1 && i != index) continue;
388 
389         symbol = ZBarcode_Create();
390         assert_nonnull(symbol, "Symbol not created\n");
391 
392         length = testUtilSetSymbol(symbol, data[i].symbology, data[i].input_mode, data[i].eci, -1 /*option_1*/, -1, -1, -1 /*output_options*/, data[i].data, -1, debug);
393 
394         ret = ZBarcode_Encode(symbol, (unsigned char *) data[i].data, length);
395         assert_equal(ret, data[i].ret, "i:%d ZBarcode_Encode ret %d != %d (%s)\n", i, ret, data[i].ret, symbol->errtxt);
396 
397         if (data[i].expected_eci != -1) {
398             assert_equal(symbol->eci, data[i].expected_eci, "i:%d eci %d != %d\n", i, symbol->eci, data[i].expected_eci);
399         }
400 
401         ZBarcode_Delete(symbol);
402     }
403 
404     testFinish();
405 }
406 
to_utf8(const unsigned int codepoint,unsigned char * buf)407 static int to_utf8(const unsigned int codepoint, unsigned char *buf) {
408     int length = 0;
409 
410     if (codepoint < 0x80) {
411         buf[0] = (unsigned char) codepoint;
412         length = 1;
413     } else if (codepoint < 0x800) {
414         buf[0] = (unsigned char) (0xC0 | (codepoint >> 6));
415         buf[1] = (unsigned char) (0x80 | (codepoint & 0x3F));
416         length = 2;
417     } else if (codepoint < 0x10000) {
418         buf[0] = (unsigned char) (0xE0 | (codepoint >> 12));
419         buf[1] = (unsigned char) (0x80 | ((codepoint >> 6) & 0x3F));
420         buf[2] = (unsigned char) (0x80 | (codepoint & 0x3F));
421         length = 3;
422     } else {
423         buf[0] = (unsigned char) (0xF0 | (codepoint >> 18));
424         buf[1] = (unsigned char) (0x80 | ((codepoint >> 12) & 0x3F));
425         buf[2] = (unsigned char) (0x80 | ((codepoint >> 6) & 0x3F));
426         buf[3] = (unsigned char) (0x80 | (codepoint & 0x3F));
427         length = 4;
428     }
429     buf[length] = '\0';
430 
431     return length;
432 }
433 
434 // Original eci.h tables
435 
436 static const unsigned short int iso_8859_1[] = {// Latin alphabet No. 1
437     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
438     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
439     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
440     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
441     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
442     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
443     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
444     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
445 };
446 
447 static const unsigned short int iso_8859_2[] = {// Latin alphabet No. 2
448     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
449     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
450     0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b,
451     0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c,
452     0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
453     0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
454     0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
455     0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
456 };
457 
458 static const unsigned short int iso_8859_3[] = {// Latin alphabet No. 3
459     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
460     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
461     0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0x0000, 0x0124, 0x00a7, 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0x0000, 0x017b,
462     0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0x0000, 0x017c,
463     0x00c0, 0x00c1, 0x00c2, 0x0000, 0x00c4, 0x010a, 0x0108, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
464     0x0000, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df,
465     0x00e0, 0x00e1, 0x00e2, 0x0000, 0x00e4, 0x010b, 0x0109, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
466     0x0000, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9
467 };
468 
469 static const unsigned short int iso_8859_4[] = {// Latin alphabet No. 4
470     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
471     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
472     0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, // A5 0x012b -> 0x0128
473     0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b,
474     0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a,
475     0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df,
476     0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b,
477     0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9
478 };
479 
480 static const unsigned short int iso_8859_5[] = {// Latin/Cyrillic alphabet
481     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
482     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
483     0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f,
484     0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
485     0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
486     0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
487     0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f,
488     0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f
489 };
490 
491 static const unsigned short int iso_8859_6[] = {// Latin/Arabic alphabet
492     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
493     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
494     0x00a0, 0x0000, 0x0000, 0x0000, 0x00a4, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x060c, 0x00ad, 0x0000, 0x0000,
495     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x061b, 0x0000, 0x0000, 0x0000, 0x061f,
496     0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
497     0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, 0x0639, 0x063a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
498     0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f,
499     0x0650, 0x0651, 0x0652, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
500 };
501 
502 static const unsigned short int iso_8859_7[] = {// Latin/Greek alphabet
503     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
504     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
505     0x00a0, 0x2018, 0x2019, 0x00a3, 0x20ac, 0x20af, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x037a, 0x00ab, 0x00ac, 0x00ad, 0x0000, 0x2015,
506     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f,
507     0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f,
508     0x03a0, 0x03a1, 0x0000, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af,
509     0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf,
510     0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0x0000
511 };
512 
513 static const unsigned short int iso_8859_8[] = {// Latin/Hebrew alphabet
514     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
515     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
516     0x00a0, 0x0000, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
517     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x0000,
518     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
519     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017,
520     0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df,
521     0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, 0x0000, 0x0000, 0x200e, 0x200f, 0x0000
522 };
523 
524 static const unsigned short int iso_8859_9[] = {// Latin alphabet No. 5
525     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
526     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
527     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
528     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
529     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
530     0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
531     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
532     0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff
533 };
534 
535 static const unsigned short int iso_8859_10[] = {// Latin alphabet No. 6
536     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
537     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
538     0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, // A5 0x012b -> 0x0128
539     0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b,
540     0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf,
541     0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
542     0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef,
543     0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138
544 };
545 
546 static const unsigned short int iso_8859_11[] = {// Latin/Thai alphabet
547     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
548     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
549     0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f,
550     0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f,
551     0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f,
552     0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, 0x0e38, 0x0e39, 0x0e3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0e3f, // D5 0x0e36 -> 0x0e35
553     0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f,
554     0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x0000, 0x0000, 0x0000, 0x0000
555 };
556 
557 static const unsigned short int iso_8859_13[] = {// Latin alphabet No. 7
558     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
559     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
560     0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6,
561     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6,
562     0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b,
563     0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df,
564     0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c,
565     0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019
566 };
567 
568 static const unsigned short int iso_8859_14[] = {// Latin alphabet No. 8 (Celtic)
569     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
570     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
571     0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178,
572     0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61,
573     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
574     0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df,
575     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
576     0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff
577 };
578 
579 static const unsigned short int iso_8859_15[] = {// Latin alphabet No. 9
580     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
581     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
582     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
583     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf,
584     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
585     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
586     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
587     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
588 };
589 
590 static const unsigned short int iso_8859_16[] = {// Latin alphabet No. 10
591     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
592     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
593     0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b,
594     0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c,
595     0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
596     0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a, 0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df,
597     0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
598     0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff
599 };
600 
601 static const unsigned short int windows_1250[] = {
602     0x20ac, 0x0000, 0x201a, 0x0000, 0x201e, 0x2026, 0x2020, 0x2021, 0x0000, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179,
603     0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a,
604     0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, // A2 0x02db -> 0x02d8
605     0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c,
606     0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e,
607     0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df,
608     0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f,
609     0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9
610 };
611 
612 static const unsigned short int windows_1251[] = {
613     0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f,
614     0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x0000, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f,
615     0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407,
616     0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457,
617     0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f,
618     0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f,
619     0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f,
620     0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f
621 };
622 
623 static const unsigned short int windows_1252[] = {
624     0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x017d, 0x0000,
625     0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x017e, 0x0178,
626     0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
627     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
628     0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
629     0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
630     0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
631     0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
632 };
633 
634 static const unsigned short int windows_1256[] = {
635     0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688,
636     0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba,
637     0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
638     0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f,
639     0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f,
640     0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643,
641     0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef,
642     0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2
643 };
644 
test_utf8_to_eci_sb(int index)645 static void test_utf8_to_eci_sb(int index) {
646 
647     struct item {
648         int eci;
649         const unsigned short *tab;
650     };
651     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
652     struct item data[] = {
653         /*  0*/ { 3, iso_8859_1 },
654         /*  1*/ { 4, iso_8859_2 },
655         /*  2*/ { 5, iso_8859_3 },
656         /*  3*/ { 6, iso_8859_4 },
657         /*  4*/ { 7, iso_8859_5 },
658         /*  5*/ { 8, iso_8859_6 },
659         /*  6*/ { 9, iso_8859_7 },
660         /*  7*/ { 10, iso_8859_8 },
661         /*  8*/ { 11, iso_8859_9 },
662         /*  9*/ { 12, iso_8859_10 },
663         /* 10*/ { 13, iso_8859_11 },
664         /* 11*/ { 15, iso_8859_13 },
665         /* 12*/ { 16, iso_8859_14 },
666         /* 13*/ { 17, iso_8859_15 },
667         /* 14*/ { 18, iso_8859_16 },
668         /* 15*/ { 21, windows_1250 },
669         /* 16*/ { 22, windows_1251 },
670         /* 17*/ { 23, windows_1252 },
671         /* 18*/ { 24, windows_1256 },
672     };
673     int data_size = ARRAY_SIZE(data);
674     int i, length, ret;
675 
676     unsigned char source[5];
677     unsigned char dest[2] = {0};
678 
679     testStart("test_utf8_to_eci_sb");
680 
681     for (i = 0; i < data_size; i++) {
682         int j;
683 
684         if (index != -1 && i != index) continue;
685 
686         for (j = 0; j < 128; j++) {
687             int k = j + 128;
688             if (data[i].tab[j]) {
689                 length = to_utf8(data[i].tab[j], source);
690                 assert_nonzero(length, "i:%d to_utf8 length %d == 0\n", i, length);
691                 ret = utf8_to_eci(data[i].eci, source, dest, &length);
692                 assert_zero(ret, "i:%d utf8_to_eci ret %d != 0\n", i, ret);
693                 assert_equal(*dest, k, "i:%d j:%d eci:%d codepoint:0x%x *dest 0x%X (%d) != 0x%X (%d)\n", i, j, data[i].eci, data[i].tab[j], *dest, *dest, k, k);
694             } else {
695                 length = to_utf8(k, source);
696                 assert_nonzero(length, "i:%d to_utf8 length %d == 0\n", i, length);
697                 ret = utf8_to_eci(data[i].eci, source, dest, &length);
698                 if (ret == 0) { // Should be mapping for this codepoint in another entry
699                     int found = 0;
700                     int m;
701                     for (m = 0; m < 128; m++) {
702                         if (data[i].tab[m] == k) {
703                             found = 1;
704                             break;
705                         }
706                     }
707                     assert_nonzero(found, "i:%d j:%d eci:%d codepoint:0x%x source:%s not found utf8_to_eci ret %d == 0\n", i, j, data[i].eci, k, source, ret);
708                 } else {
709                     assert_equal(ret, ZINT_ERROR_INVALID_DATA, "i:%d j:%d eci:%d codepoint:0x%x source:%s utf8_to_eci ret %d != ZINT_ERROR_INVALID_DATA\n", i, j, data[i].eci, k, source, ret);
710                 }
711             }
712         }
713     }
714 
715     testFinish();
716 }
717 
test_utf8_to_eci_ascii(void)718 static void test_utf8_to_eci_ascii(void) {
719 
720     struct item {
721         int eci;
722         char *data;
723         int length;
724         int ret;
725     };
726     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
727     struct item data[] = {
728         /*  0*/ { 27, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0 },
729         /*  1*/ { 27, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177", 96, 0 },
730         /*  2*/ { 27, "\302\200", -1, ZINT_ERROR_INVALID_DATA },
731         /*  3*/ { 170, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0 },
732         /*  4*/ { 170, " !\"  %&'()*+,-./0123456789:;<=>? ABCDEFGHIJKLMNOPQRSTUVWXYZ    _ abcdefghijklmnopqrstuvwxyz    \177", 96, 0 },
733         /*  5*/ { 170, "#", -1, ZINT_ERROR_INVALID_DATA },
734         /*  6*/ { 170, "$", -1, ZINT_ERROR_INVALID_DATA },
735         /*  7*/ { 170, "@", -1, ZINT_ERROR_INVALID_DATA },
736         /*  8*/ { 170, "[", -1, ZINT_ERROR_INVALID_DATA },
737         /*  9*/ { 170, "\\", -1, ZINT_ERROR_INVALID_DATA },
738         /* 10*/ { 170, "]", -1, ZINT_ERROR_INVALID_DATA },
739         /* 11*/ { 170, "^", -1, ZINT_ERROR_INVALID_DATA },
740         /* 12*/ { 170, "`", -1, ZINT_ERROR_INVALID_DATA },
741         /* 13*/ { 170, "{", -1, ZINT_ERROR_INVALID_DATA },
742         /* 14*/ { 170, "|", -1, ZINT_ERROR_INVALID_DATA },
743         /* 15*/ { 170, "}", -1, ZINT_ERROR_INVALID_DATA },
744         /* 16*/ { 170, "~", -1, ZINT_ERROR_INVALID_DATA },
745         /* 17*/ { 170, "\302\200", -1, ZINT_ERROR_INVALID_DATA },
746     };
747     int data_size = ARRAY_SIZE(data);
748     int i, length, ret;
749 
750     char dest[128];
751 
752     testStart("test_utf8_to_eci_ascii");
753 
754     for (i = 0; i < data_size; i++) {
755         int out_length;
756         length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
757         out_length = length;
758         ret = utf8_to_eci(data[i].eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
759         assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
760         if (ret == 0) {
761             assert_equal(length, out_length, "i:%d length %d != %d\n", i, length, out_length);
762             assert_zero(memcmp(data[i].data, dest, length), "i:%d memcmp != 0\n", i);
763         }
764     }
765 };
766 
test_utf8_to_eci_ucs2be(void)767 static void test_utf8_to_eci_ucs2be(void) {
768 
769     struct item {
770         int eci;
771         char *data;
772         int length;
773         int ret;
774         int expected_length;
775     };
776     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
777     struct item data[] = {
778         /*  0*/ { 25, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0, 32 * 2 },
779         /*  1*/ { 25, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177", 96, 0, 96 * 2 },
780         /*  2*/ { 25, "\302\200\357\277\277", -1, 0, 4 }, // U+0080 U+FFFF
781         /*  3*/ { 25, "\357\277\276", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+FFFE (reversed BOM) not allowed
782         /*  4*/ { 25, "\355\240\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+D800 surrogate not allowed
783     };
784     int data_size = ARRAY_SIZE(data);
785     int i, length, ret;
786 
787     testStart("test_utf8_to_eci_ucs2be");
788 
789     for (i = 0; i < data_size; i++) {
790         int out_length, eci_length;
791         char dest[1024];
792 
793         length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
794         out_length = length;
795         eci_length = get_eci_length(data[i].eci, (const unsigned char *) data[i].data, length);
796 
797         assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length);
798         ret = utf8_to_eci(data[i].eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
799         assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
800         if (ret == 0) {
801             assert_equal(out_length, data[i].expected_length, "i:%d length %d != %d\n", i, out_length, data[i].expected_length);
802             assert_nonzero(out_length <= eci_length, "i:%d out_length %d > eci_length %d\n", i, out_length, eci_length);
803         }
804     }
805 };
806 
test_utf8_to_eci_sjis(void)807 static void test_utf8_to_eci_sjis(void) {
808 
809     struct item {
810         int eci;
811         char *data;
812         int length;
813         int ret;
814         int expected_length;
815     };
816     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
817     struct item data[] = {
818         /*  0*/ { 20, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0, 32 },
819         /*  1*/ { 20, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}\177", 95, 0, 95 + 1 }, // Backslash goes to 2 byte
820         /*  2*/ { 20, "~", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for tilde
821         /*  3*/ { 20, "\302\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+0080
822         /*  4*/ { 20, "\302\241", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+00A1 Inverted exclaimation mark
823         /*  5*/ { 20, "\302\245", -1, 0, 1 }, // U+00A5 Yen goes to backslash
824         /*  6*/ { 20, "\302\277", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+00BF Inverted question mark
825         /*  7*/ { 20, "\303\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+00C0 À
826         /*  8*/ { 20, "\303\251", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+00E9 é
827         /*  9*/ { 20, "\312\262", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+03B2 β
828         /* 10*/ { 20, "\342\272\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+2E80 CJK RADICAL REPEAT
829         /* 11*/ { 20, "\343\200\200", -1, 0, 2 }, // U+3000 IDEOGRAPHIC SPACE
830         /* 12*/ { 20, "\343\200\204", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+3004 JAPANESE INDUSTRIAL STANDARD SYMBOL
831         /* 13*/ { 20, "\343\201\201", -1, 0, 2 }, //U+3041 HIRAGANA LETTER SMALL A
832         /* 14*/ { 20, "\357\277\277", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+FFFF
833         /* 15*/ { 20, "\357\277\276", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+FFFE (reversed BOM) not allowed
834         /* 16*/ { 20, "\355\240\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+D800 surrogate not allowed
835     };
836     int data_size = ARRAY_SIZE(data);
837     int i, length, ret;
838 
839     testStart("test_utf8_to_eci_sjis");
840 
841     for (i = 0; i < data_size; i++) {
842         int out_length, eci_length;
843         char dest[1024];
844 
845         length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
846         out_length = length;
847         eci_length = get_eci_length(data[i].eci, (const unsigned char *) data[i].data, length);
848 
849         assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length);
850         ret = utf8_to_eci(data[i].eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
851         assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
852         if (ret == 0) {
853             assert_equal(out_length, data[i].expected_length, "i:%d length %d != %d\n", i, out_length, data[i].expected_length);
854             assert_nonzero(out_length <= eci_length, "i:%d out_length %d > eci_length %d\n", i, out_length, eci_length);
855         }
856     }
857 };
858 
test_utf8_to_eci_big5(void)859 static void test_utf8_to_eci_big5(void) {
860 
861     struct item {
862         int eci;
863         char *data;
864         int length;
865         int ret;
866         int expected_length;
867     };
868     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
869     struct item data[] = {
870         /*  0*/ { 28, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0, 32 },
871         /*  1*/ { 28, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177", 96, 0, 96 },
872         /*  2*/ { 28, "\302\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+0080
873         /*  3*/ { 28, "\343\200\200", -1, 0, 2 }, // U+3000 IDEOGRAPHIC SPACE
874         /*  4*/ { 28, "\357\277\277", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+FFFF
875         /*  5*/ { 28, "\357\277\276", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+FFFE (reversed BOM) not allowed
876         /*  6*/ { 28, "\355\240\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+D800 surrogate not allowed
877     };
878     int data_size = ARRAY_SIZE(data);
879     int i, length, ret;
880 
881     testStart("test_utf8_to_eci_big5");
882 
883     for (i = 0; i < data_size; i++) {
884         int out_length, eci_length;
885         char dest[1024];
886 
887         length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
888         out_length = length;
889         eci_length = get_eci_length(data[i].eci, (const unsigned char *) data[i].data, length);
890 
891         assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length);
892         ret = utf8_to_eci(data[i].eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
893         assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
894         if (ret == 0) {
895             assert_equal(out_length, data[i].expected_length, "i:%d length %d != %d\n", i, out_length, data[i].expected_length);
896             assert_nonzero(out_length <= eci_length, "i:%d out_length %d > eci_length %d\n", i, out_length, eci_length);
897         }
898     }
899 };
900 
test_utf8_to_eci_gb2312(void)901 static void test_utf8_to_eci_gb2312(void) {
902 
903     struct item {
904         int eci;
905         char *data;
906         int length;
907         int ret;
908         int expected_length;
909     };
910     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
911     struct item data[] = {
912         /*  0*/ { 29, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0, 32 },
913         /*  1*/ { 29, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177", 96, 0, 96 },
914         /*  2*/ { 29, "\302\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+0080
915         /*  3*/ { 29, "\343\200\200", -1, 0, 2 }, // U+3000 IDEOGRAPHIC SPACE
916         /*  4*/ { 29, "\357\277\277", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+FFFF
917         /*  5*/ { 29, "\357\277\276", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+FFFE (reversed BOM) not allowed
918         /*  6*/ { 29, "\355\240\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+D800 surrogate not allowed
919     };
920     int data_size = ARRAY_SIZE(data);
921     int i, length, ret;
922 
923     testStart("test_utf8_to_eci_gb2312");
924 
925     for (i = 0; i < data_size; i++) {
926         int out_length, eci_length;
927         char dest[1024];
928 
929         length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
930         out_length = length;
931         eci_length = get_eci_length(data[i].eci, (const unsigned char *) data[i].data, length);
932 
933         assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length);
934         ret = utf8_to_eci(data[i].eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
935         assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
936         if (ret == 0) {
937             assert_equal(out_length, data[i].expected_length, "i:%d length %d != %d\n", i, out_length, data[i].expected_length);
938             assert_nonzero(out_length <= eci_length, "i:%d out_length %d > eci_length %d\n", i, out_length, eci_length);
939         }
940     }
941 };
942 
test_utf8_to_eci_euc_kr(void)943 static void test_utf8_to_eci_euc_kr(void) {
944 
945     struct item {
946         int eci;
947         char *data;
948         int length;
949         int ret;
950         int expected_length;
951     };
952     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
953     struct item data[] = {
954         /*  0*/ { 30, "\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037", 32, 0, 32 },
955         /*  1*/ { 30, " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177", 96, 0, 96 },
956         /*  2*/ { 30, "\302\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+0080
957         /*  3*/ { 30, "\343\200\200", -1, 0, 2 }, // U+3000 IDEOGRAPHIC SPACE
958         /*  4*/ { 30, "\357\277\277", -1, ZINT_ERROR_INVALID_DATA, -1 }, // No mapping for U+FFFF
959         /*  5*/ { 30, "\357\277\276", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+FFFE (reversed BOM) not allowed
960         /*  6*/ { 30, "\355\240\200", -1, ZINT_ERROR_INVALID_DATA, -1 }, // U+D800 surrogate not allowed
961     };
962     int data_size = ARRAY_SIZE(data);
963     int i, length, ret;
964 
965     testStart("test_utf8_to_eci_euc_kr");
966 
967     for (i = 0; i < data_size; i++) {
968         int out_length, eci_length;
969         char dest[1024];
970 
971         length = data[i].length != -1 ? data[i].length : (int) strlen(data[i].data);
972         out_length = length;
973         eci_length = get_eci_length(data[i].eci, (const unsigned char *) data[i].data, length);
974 
975         assert_nonzero(eci_length + 1 <= 1024, "i:%d eci_length %d + 1 > 1024\n", i, eci_length);
976         ret = utf8_to_eci(data[i].eci, (const unsigned char *) data[i].data, (unsigned char *) dest, &out_length);
977         assert_equal(ret, data[i].ret, "i:%d utf8_to_eci ret %d != %d\n", i, ret, data[i].ret);
978         if (ret == 0) {
979             assert_equal(out_length, data[i].expected_length, "i:%d length %d != %d\n", i, out_length, data[i].expected_length);
980             assert_nonzero(out_length <= eci_length, "i:%d out_length %d > eci_length %d\n", i, out_length, eci_length);
981         }
982     }
983 };
984 
test_get_best_eci(int index)985 static void test_get_best_eci(int index) {
986 
987     struct item {
988         const char *data;
989         int length;
990         int ret;
991     };
992     // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<"))
993     struct item data[] = {
994         /*  0*/ { "\300\301", -1, 0 },
995         /*  1*/ { "ÀÁ", -1, 3 },
996         /*  2*/ { "Ђ", -1, 7 },
997         /*  3*/ { "Ѐ", -1, 26 }, // Cyrillic U+0400 not in single-byte code pages
998         /*  4*/ { "β", -1, 9 },
999         /*  5*/ { "˜", -1, 23 },
1000         /*  6*/ { "βЂ", -1, 26 },
1001         /*  7*/ { "AB\200", -1, 0 },
1002     };
1003     int data_size = ARRAY_SIZE(data);
1004     int i, length, ret;
1005 
1006     testStart("test_get_best_eci");
1007 
1008     for (i = 0; i < data_size; i++) {
1009 
1010         if (index != -1 && i != index) continue;
1011 
1012         length = data[i].length == -1 ? (int) strlen(data[i].data) : data[i].length;
1013 
1014         ret = get_best_eci((const unsigned char *) data[i].data, length);
1015         assert_equal(ret, data[i].ret, "i:%d get_best_eci ret %d != %d\n", i, ret, data[i].ret);
1016     }
1017 
1018     testFinish();
1019 }
1020 
main(int argc,char * argv[])1021 int main(int argc, char *argv[]) {
1022 
1023     testFunction funcs[] = { /* name, func, has_index, has_generate, has_debug */
1024         { "test_bom", test_bom, 0, 0, 1 },
1025         { "test_iso_8859_16", test_iso_8859_16, 0, 0, 1 },
1026         { "test_reduced_charset_input", test_reduced_charset_input, 1, 0, 1 },
1027         { "test_utf8_to_eci_sb", test_utf8_to_eci_sb, 1, 0, 0 },
1028         { "test_utf8_to_eci_ascii", test_utf8_to_eci_ascii, 0, 0, 0 },
1029         { "test_utf8_to_eci_ucs2be", test_utf8_to_eci_ucs2be, 0, 0, 0 },
1030         { "test_utf8_to_eci_sjis", test_utf8_to_eci_sjis, 0, 0, 0 },
1031         { "test_utf8_to_eci_big5", test_utf8_to_eci_big5, 0, 0, 0 },
1032         { "test_utf8_to_eci_gb2312", test_utf8_to_eci_gb2312, 0, 0, 0 },
1033         { "test_utf8_to_eci_euc_kr", test_utf8_to_eci_euc_kr, 0, 0, 0 },
1034         { "test_get_best_eci", test_get_best_eci, 1, 0, 0 },
1035     };
1036 
1037     testRun(argc, argv, funcs, ARRAY_SIZE(funcs));
1038 
1039     testReport();
1040 
1041     return 0;
1042 }
1043