Add a note about casting the results of g_new() and g_new0().
[platform/upstream/glib.git] / tests / convert-test.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 #undef G_DISABLE_ASSERT
28 #undef G_LOG_DOMAIN
29
30 #include <string.h>
31
32 #include <glib.h>
33
34 /* Bug 311337 */
35 static void
36 test_iconv_state (void)
37 {
38   gchar *in = "\xf4\xe5\xf8\xe5\xed";
39   gchar *expected = "\xd7\xa4\xd7\x95\xd7\xa8\xd7\x95\xd7\x9d";
40   gchar *out;
41   gsize bytes_read = 0;
42   gsize bytes_written = 0;
43   GError *error = NULL;
44
45   out = g_convert (in, -1, "UTF-8", "CP1255", 
46                    &bytes_read, &bytes_written, &error);
47   
48   g_assert (error == NULL);
49   g_assert (bytes_read == 5);
50   g_assert (bytes_written == 10);
51   g_assert (strcmp (out, expected) == 0);
52 }
53
54 /* some tests involving "vulgar fraction one half" */
55 static void 
56 test_one_half (void)
57 {
58   gchar *in = "\xc2\xbd";
59   gchar *out;
60   gsize bytes_read = 0;
61   gsize bytes_written = 0;
62   GError *error = NULL;  
63
64   out = g_convert (in, -1, 
65                    "ISO8859-1", "UTF-8",
66                    &bytes_read, &bytes_written,
67                    &error);
68
69   g_assert (error == NULL);
70   g_assert (bytes_read == 2);
71   g_assert (bytes_written == 1);
72   g_assert (strcmp (out, "\xbd") == 0);
73   g_free (out);
74
75   out = g_convert (in, -1, 
76                    "ISO8859-15", "UTF-8",
77                    &bytes_read, &bytes_written,
78                    &error);
79
80   g_assert (error && error->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE);
81   g_assert (bytes_read == 0);
82   g_assert (bytes_written == 0);
83   g_assert (out == NULL);
84   g_clear_error (&error);
85
86   out = g_convert_with_fallback (in, -1, 
87                                  "ISO8859-15", "UTF-8",
88                                  "a",
89                                  &bytes_read, &bytes_written,
90                                  &error);
91
92   g_assert (error == NULL);
93   g_assert (bytes_read == 2);
94   g_assert (bytes_written == 1);
95   g_assert (strcmp (out, "a") == 0);
96   g_free (out);
97 }
98
99 static void
100 test_byte_order (void)
101 {
102   gchar in_be[4] = { 0xfe, 0xff, 0x03, 0x93}; /* capital gamma */
103   gchar in_le[4] = { 0xff, 0xfe, 0x93, 0x03};
104   gchar *expected = "\xce\x93";
105   gchar *out;
106   gsize bytes_read = 0;
107   gsize bytes_written = 0;
108   GError *error = NULL;  
109
110   out = g_convert (in_be, sizeof (in_be), 
111                    "UTF-8", "UTF-16",
112                    &bytes_read, &bytes_written,
113                    &error);
114
115   g_assert (error == NULL);
116   g_assert (bytes_read == 4);
117   g_assert (bytes_written == 2);
118   g_assert (strcmp (out, expected) == 0);
119   g_free (out);
120
121   out = g_convert (in_le, sizeof (in_le), 
122                    "UTF-8", "UTF-16",
123                    &bytes_read, &bytes_written,
124                    &error);
125
126   g_assert (error == NULL);
127   g_assert (bytes_read == 4);
128   g_assert (bytes_written == 2);
129   g_assert (strcmp (out, expected) == 0);
130   g_free (out);
131 }
132
133 static void
134 check_utf8_to_ucs4 (const char     *utf8,
135                     glong           utf8_len,
136                     const gunichar *ucs4,
137                     glong           ucs4_len,
138                     glong           error_pos)
139 {
140   gunichar *result, *result2, *result3;
141   glong items_read, items_read2;
142   glong items_written, items_written2;
143   GError *error, *error2, *error3;
144   gint i;
145
146   if (!error_pos)
147     {
148       /* check the fast conversion */
149       result = g_utf8_to_ucs4_fast (utf8, utf8_len, &items_written);
150
151       g_assert (items_written == ucs4_len);
152       g_assert (result);
153       for (i = 0; i <= items_written; i++)
154         g_assert (result[i] == ucs4[i]);      
155
156       g_free (result);
157     }
158
159   error = NULL;
160   result = g_utf8_to_ucs4 (utf8, utf8_len, &items_read, &items_written, &error);
161   
162   if (utf8_len == strlen (utf8))
163     {
164       /* check that len == -1 yields identical results */
165       error2 = NULL;
166       result2 = g_utf8_to_ucs4 (utf8, -1, &items_read2, &items_written2, &error2);
167       g_assert (error || items_read2 == items_read);
168       g_assert (error || items_written2 == items_written2);
169       g_assert (!!result == !!result2);
170       g_assert (!!error == !!error2);
171       if (result)
172         for (i = 0; i <= items_written; i++)
173           g_assert (result[i] == result2[i]);
174
175       g_free (result2);
176       if (error2)
177         g_error_free (error2);
178     }
179
180   error3 = NULL;
181   result3 = g_utf8_to_ucs4 (utf8, utf8_len, NULL, NULL, &error3);
182       
183   if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
184     {
185       g_assert (error == NULL);
186       g_assert (items_read == error_pos);
187       g_assert (items_written == ucs4_len);
188       g_assert (result);
189       for (i = 0; i <= items_written; i++)
190         g_assert (result[i] == ucs4[i]);
191     }
192   else if (error_pos)
193     {
194       g_assert (error != NULL);
195       g_assert (result == NULL);
196       g_assert (items_read == error_pos);
197       g_error_free (error);
198
199       g_assert (error3 != NULL);
200       g_assert (result3 == NULL);
201       g_error_free (error3);
202     }
203   else
204     {
205       g_assert (error == NULL);
206       g_assert (items_read == utf8_len);
207       g_assert (items_written == ucs4_len);
208       g_assert (result);
209       for (i = 0; i <= items_written; i++)
210         g_assert (result[i] == ucs4[i]);
211
212       g_assert (error3 == NULL);
213       g_assert (result3);
214       for (i = 0; i <= ucs4_len; i++)
215         g_assert (result3[i] == ucs4[i]);
216     }
217
218   g_free (result);
219   g_free (result3);
220 }
221
222 static void
223 check_ucs4_to_utf8 (const gunichar *ucs4,
224                     glong           ucs4_len,
225                     const char     *utf8,
226                     glong           utf8_len,
227                     glong           error_pos)
228 {
229   gchar *result, *result2, *result3;
230   glong items_read, items_read2;
231   glong items_written, items_written2;
232   GError *error, *error2, *error3;
233
234   error = NULL;
235   result = g_ucs4_to_utf8 (ucs4, ucs4_len, &items_read, &items_written, &error);
236
237   if (ucs4[ucs4_len] == 0)
238     {
239       /* check that len == -1 yields identical results */
240       error2 = NULL;
241       result2 = g_ucs4_to_utf8 (ucs4, -1, &items_read2, &items_written2, &error2);
242       
243       g_assert (error || items_read2 == items_read);
244       g_assert (error || items_written2 == items_written);
245       g_assert (!!result == !!result2);
246       g_assert (!!error == !!error2);
247       if (result)
248         g_assert (strcmp (result, result2) == 0);
249
250       g_free (result2);
251       if (error2)
252         g_error_free (error2);
253     }
254
255   error3 = NULL;
256   result3 = g_ucs4_to_utf8 (ucs4, ucs4_len, NULL, NULL, &error3);
257       
258   if (error_pos)
259     {
260       g_assert (error != NULL);
261       g_assert (result == NULL);
262       g_assert (items_read == error_pos);
263       g_error_free (error);
264
265       g_assert (error3 != NULL);
266       g_assert (result3 == NULL);
267       g_error_free (error3);
268     }
269   else
270     {
271       g_assert (error == NULL);
272       g_assert (items_read == ucs4_len);
273       g_assert (items_written == utf8_len);
274       g_assert (result);
275       g_assert (strcmp (result, utf8) == 0);
276
277       g_assert (error3 == NULL);
278       g_assert (result3);
279       g_assert (strcmp (result3, utf8) == 0);
280     }
281
282   g_free (result);
283   g_free (result3);
284 }
285
286 static void
287 check_utf8_to_utf16 (const char      *utf8,
288                      glong            utf8_len,
289                      const gunichar2 *utf16,
290                      glong            utf16_len,
291                      glong            error_pos)
292 {
293   gunichar2 *result, *result2, *result3;
294   glong items_read, items_read2;
295   glong items_written, items_written2;
296   GError *error, *error2, *error3;
297   gint i;
298
299   error = NULL;
300   result = g_utf8_to_utf16 (utf8, utf8_len, &items_read, &items_written, &error);
301
302   if (utf8_len == strlen (utf8))
303     {
304       /* check that len == -1 yields identical results */
305       error2 = NULL;
306       result2 = g_utf8_to_utf16 (utf8, -1, &items_read2, &items_written2, &error2);
307       g_assert (error || items_read2 == items_read);
308       g_assert (error || items_written2 == items_written2);
309       g_assert (!!result == !!result2);
310       g_assert (!!error == !!error2);
311       if (result)
312         for (i = 0; i <= items_written; i++)
313           g_assert (result[i] == result2[i]);
314       
315       g_free (result2);
316       if (error2)
317         g_error_free (error2);
318     }
319
320   error3 = NULL;
321   result3 = g_utf8_to_utf16 (utf8, utf8_len, NULL, NULL, &error3);
322       
323   if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
324     {
325       g_assert (error == NULL);
326       g_assert (items_read == error_pos);
327       g_assert (items_written == utf16_len);
328       g_assert (result);
329       for (i = 0; i <= items_written; i++)
330         g_assert (result[i] == utf16[i]);
331     }
332   else if (error_pos)
333     {
334       g_assert (error != NULL);
335       g_assert (result == NULL);
336       g_assert (items_read == error_pos);
337       g_error_free (error);
338
339       g_assert (error3 != NULL);
340       g_assert (result3 == NULL);
341       g_error_free (error3);
342     }
343   else
344     {
345       g_assert (error == NULL);
346       g_assert (items_read == utf8_len);
347       g_assert (items_written == utf16_len);
348       g_assert (result);
349       for (i = 0; i <= items_written; i++)
350         g_assert (result[i] == utf16[i]);
351
352       g_assert (error3 == NULL);
353       g_assert (result3);
354       for (i = 0; i <= utf16_len; i++)
355         g_assert (result3[i] == utf16[i]);
356     }
357
358   g_free (result);
359   g_free (result3);
360 }
361
362 static void
363 check_utf16_to_utf8 (const gunichar2 *utf16,
364                      glong            utf16_len,
365                      const char      *utf8,
366                      glong            utf8_len,
367                      glong            error_pos)
368 {
369   gchar *result, *result2, *result3;
370   glong items_read, items_read2;
371   glong items_written, items_written2;
372   GError *error, *error2, *error3;
373
374   error = NULL;
375   result = g_utf16_to_utf8 (utf16, utf16_len, &items_read, &items_written, &error);
376   if (utf16[utf16_len] == 0)
377     {
378       /* check that len == -1 yields identical results */
379       error2 = NULL;
380       result2 = g_utf16_to_utf8 (utf16, -1, &items_read2, &items_written2, &error2);
381       
382       g_assert (error || items_read2 == items_read);
383       g_assert (error || items_written2 == items_written);
384       g_assert (!!result == !!result2);
385       g_assert (!!error == !!error2);
386       if (result)
387         g_assert (strcmp (result, result2) == 0);
388
389       g_free (result2);
390       if (error2)
391         g_error_free (error2);
392     }
393
394   error3 = NULL;
395   result3 = g_utf16_to_utf8 (utf16, utf16_len, NULL, NULL, &error3);
396   
397   if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
398     {
399       g_assert (error == NULL);
400       g_assert (items_read == error_pos);
401       g_assert (items_read + 1 == utf16_len);
402       g_assert (items_written == utf8_len);
403       g_assert (result);
404       g_assert (strcmp (result, utf8) == 0);
405     }
406   else if (error_pos)
407     {
408       g_assert (error != NULL);
409       g_assert (result == NULL);
410       g_assert (items_read == error_pos);
411       g_error_free (error);
412
413       g_assert (error3 != NULL);
414       g_assert (result3 == NULL);
415       g_error_free (error3);
416     }
417   else
418     {
419       g_assert (error == NULL);
420       g_assert (items_read == utf16_len);
421       g_assert (items_written == utf8_len);
422       g_assert (result);
423       g_assert (strcmp (result, utf8) == 0);
424
425       g_assert (error3 == NULL);
426       g_assert (result3);
427       g_assert (strcmp (result3, utf8) == 0);
428     }
429
430   g_free (result);
431   g_free (result3);
432 }
433
434 static void
435 check_ucs4_to_utf16 (const gunichar  *ucs4,
436                      glong            ucs4_len,
437                      const gunichar2 *utf16,
438                      glong            utf16_len,
439                      glong            error_pos)
440 {
441   gunichar2 *result, *result2, *result3;
442   glong items_read, items_read2;
443   glong items_written, items_written2;
444   GError *error, *error2, *error3;
445   gint i;
446
447   error = NULL;
448   result = g_ucs4_to_utf16 (ucs4, ucs4_len, &items_read, &items_written, &error);
449
450   if (ucs4[ucs4_len] == 0)
451     {
452       /* check that len == -1 yields identical results */
453       error2 = NULL;
454       result2 = g_ucs4_to_utf16 (ucs4, -1, &items_read2, &items_written2, &error2);
455       
456       g_assert (error || items_read2 == items_read);
457       g_assert (error || items_written2 == items_written);
458       g_assert (!!result == !!result2);
459       g_assert (!!error == !!error2);
460       if (result)
461       for (i = 0; i <= utf16_len; i++)
462         g_assert (result[i] == result2[i]);
463
464       g_free (result2);
465       if (error2)
466         g_error_free (error2);
467     }
468
469   error3 = NULL;
470   result3 = g_ucs4_to_utf16 (ucs4, -1, NULL, NULL, &error3);
471       
472   if (error_pos)
473     {
474       g_assert (error != NULL);
475       g_assert (result == NULL);
476       g_assert (items_read == error_pos);
477       g_error_free (error);
478
479       g_assert (error3 != NULL);
480       g_assert (result3 == NULL);
481       g_error_free (error3);
482     }
483   else
484     {
485       g_assert (error == NULL);
486       g_assert (items_read == ucs4_len);
487       g_assert (items_written == utf16_len);
488       g_assert (result);
489       for (i = 0; i <= utf16_len; i++)
490         g_assert (result[i] == utf16[i]);
491
492       g_assert (error3 == NULL);
493       g_assert (result3);
494       for (i = 0; i <= utf16_len; i++)
495         g_assert (result3[i] == utf16[i]);
496     }
497
498   g_free (result);
499   g_free (result3);
500 }
501
502 static void
503 check_utf16_to_ucs4 (const gunichar2 *utf16,
504                      glong            utf16_len,
505                      const gunichar  *ucs4,
506                      glong            ucs4_len,
507                      glong            error_pos)
508 {
509   gunichar *result, *result2, *result3;
510   glong items_read, items_read2;
511   glong items_written, items_written2;
512   GError *error, *error2, *error3;
513   gint i;
514
515   error = NULL;
516   result = g_utf16_to_ucs4 (utf16, utf16_len, &items_read, &items_written, &error);
517   if (utf16[utf16_len] == 0)
518     {
519       /* check that len == -1 yields identical results */
520       error2 = NULL;
521       result2 = g_utf16_to_ucs4 (utf16, -1, &items_read2, &items_written2, &error2);
522       g_assert (error || items_read2 == items_read);
523       g_assert (error || items_written2 == items_written2);
524       g_assert (!!result == !!result2);
525       g_assert (!!error == !!error2);
526       if (result)
527         for (i = 0; i <= items_written; i++)
528           g_assert (result[i] == result2[i]);
529
530       g_free (result2);
531       if (error2)
532         g_error_free (error2);
533     }
534
535   error3 = NULL;
536   result3 = g_utf16_to_ucs4 (utf16, utf16_len, NULL, NULL, &error3);
537       
538   if (error3 && error3->code == G_CONVERT_ERROR_PARTIAL_INPUT)
539     {
540       g_assert (error == NULL);
541       g_assert (items_read == error_pos);
542       g_assert (items_read + 1 == utf16_len);
543       g_assert (items_written == ucs4_len);
544       g_assert (result);
545       for (i = 0; i <= items_written; i++)
546         g_assert (result[i] == ucs4[i]);
547     }
548   else if (error_pos)
549     {
550       g_assert (error != NULL);
551       g_assert (result == NULL);
552       g_assert (items_read == error_pos);
553       g_error_free (error);
554
555       g_assert (error3 != NULL);
556       g_assert (result3 == NULL);
557       g_error_free (error3);
558     }
559   else
560     {
561       g_assert (error == NULL);
562       g_assert (items_read == utf16_len);
563       g_assert (items_written == ucs4_len);
564       g_assert (result);
565       for (i = 0; i <= ucs4_len; i++)
566         g_assert (result[i] == ucs4[i]);
567
568       g_assert (error3 == NULL);
569       g_assert (result3);
570       for (i = 0; i <= ucs4_len; i++)
571         g_assert (result3[i] == ucs4[i]);
572     }
573
574   g_free (result);
575   g_free (result3);
576 }
577
578 static void
579 test_unicode_conversions (void)
580 {
581   char *utf8;
582   gunichar ucs4[100];
583   gunichar2 utf16[100];
584
585   utf8 = "abc";
586   ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x63; ucs4[3] = 0;
587   utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0x63; utf16[3] = 0;
588
589   check_utf8_to_ucs4 (utf8, 3, ucs4, 3, 0);
590   check_ucs4_to_utf8 (ucs4, 3, utf8, 3, 0);
591   check_utf8_to_utf16 (utf8, 3, utf16, 3, 0);
592   check_utf16_to_utf8 (utf16, 3, utf8, 3, 0);
593   check_ucs4_to_utf16 (ucs4, 3, utf16, 3, 0);
594   check_utf16_to_ucs4 (utf16, 3, ucs4, 3, 0);
595
596   utf8 = "\316\261\316\262\316\263";
597   ucs4[0] = 0x03b1; ucs4[1] = 0x03b2; ucs4[2] = 0x03b3; ucs4[3] = 0;
598   utf16[0] = 0x03b1; utf16[1] = 0x03b2; utf16[2] = 0x03b3; utf16[3] = 0;
599
600   check_utf8_to_ucs4 (utf8, 6, ucs4, 3, 0);
601   check_ucs4_to_utf8 (ucs4, 3, utf8, 6, 0);
602   check_utf8_to_utf16 (utf8, 6, utf16, 3, 0);
603   check_utf16_to_utf8 (utf16, 3, utf8, 6, 0);
604   check_ucs4_to_utf16 (ucs4, 3, utf16, 3, 0);
605   check_utf16_to_ucs4 (utf16, 3, ucs4, 3, 0);
606
607   /* partial utf8 character */
608   utf8 = "abc\316";
609   ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x63; ucs4[3] = 0;
610   utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0x63; utf16[3] = 0;
611
612   check_utf8_to_ucs4 (utf8, 4, ucs4, 3, 3);
613   check_utf8_to_utf16 (utf8, 4, utf16, 3, 3);
614
615   /* invalid utf8 */
616   utf8 = "abc\316\316";
617   ucs4[0] = 0; 
618   utf16[0] = 0; 
619
620   check_utf8_to_ucs4 (utf8, 5, ucs4, 0, 3);
621   check_utf8_to_utf16 (utf8, 5, utf16, 0, 3);
622
623   /* partial utf16 character */
624   utf8 = "ab";
625   ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0;
626   utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0xd801; utf16[3] = 0;
627   
628   check_utf16_to_utf8 (utf16, 3, utf8, 2, 2);
629   check_utf16_to_ucs4 (utf16, 3, ucs4, 2, 2);
630
631   /* invalid utf16 */
632   utf8 = NULL;
633   ucs4[0] = 0;
634   utf16[0] = 0x61; utf16[1] = 0x62; utf16[2] = 0xdc01; utf16[3] = 0;
635
636   check_utf16_to_utf8 (utf16, 3, utf8, 0, 2);
637   check_utf16_to_ucs4 (utf16, 3, ucs4, 0, 2);
638
639   /* invalid ucs4 */
640   utf8 = NULL;
641   ucs4[0] = 0x61; ucs4[1] = 0x62; ucs4[2] = 0x80000000; ucs4[3] = 0;
642   utf16[0] = 0;
643
644   check_ucs4_to_utf8 (ucs4, 3, utf8, 0, 2);
645   check_ucs4_to_utf16 (ucs4, 3, utf16, 0, 2);
646 }
647
648 int
649 main (int argc, char *argv[])
650 {
651   test_iconv_state ();
652   test_one_half ();
653   test_byte_order ();
654   test_unicode_conversions ();
655
656   return 0;
657 }