Add GUtf8InputStream - Bug #603270
[platform/upstream/glib.git] / gio / tests / utf8-input-stream.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2009 Paolo Borelli
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Paolo Borelli <pborelli@gnome.org>
21  */
22
23 #include <glib/glib.h>
24 #include <gio/gio.h>
25 #include <string.h>
26
27 static void
28 do_test_read (const char *str, gssize expected_nread, glong expected_nchar)
29 {
30   GInputStream *base;
31   GInputStream *in;
32   gssize len, n;
33   char *buf;
34   GError *err;
35
36   len = strlen (str);
37
38   base = g_memory_input_stream_new_from_data (str, -1, NULL);
39   in = g_utf8_input_stream_new (base);
40   g_object_unref (base);
41
42   buf = g_new0 (char, strlen(str));
43   err = NULL;
44   n = g_input_stream_read (in, buf, len, NULL, &err);
45   g_assert_cmpint (n, ==, expected_nread);
46   if (expected_nread < 0)
47     {
48       g_assert_error (err, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
49     }
50   else
51     {
52       g_assert_cmpstr (str, ==, buf);
53       g_assert_cmpint (g_utf8_strlen (buf, -1), ==, expected_nchar);
54       g_assert (err == NULL);
55     }
56   g_free (buf);
57
58   g_object_unref (in);
59 }
60
61 static void
62 do_test_read_partial (const char *str,
63                       gssize chunk_len,
64                       gssize expected_nread1,
65                       gssize expected_nread2,
66                       glong expected_nchar)
67 {
68   GInputStream *base;
69   GInputStream *in;
70   gssize len, n1, n2;
71   char *buf;
72   GError *err;
73
74   len = strlen (str);
75
76   base = g_memory_input_stream_new_from_data (str, -1, NULL);
77   in = g_utf8_input_stream_new (base);
78   g_object_unref (base);
79
80   buf = g_new0 (char, strlen(str));
81   err = NULL;
82   n1 = g_input_stream_read (in, buf, chunk_len, NULL, &err);
83   g_assert_cmpint (n1, ==, expected_nread1);
84   g_assert (err == NULL);
85
86   n2 = g_input_stream_read (in, buf + n1, len - n1, NULL, &err);
87   g_assert_cmpint (n2, ==, expected_nread2);
88   if (expected_nread2 < 0)
89     {
90       g_assert_error (err, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
91     }
92   else
93     {
94       g_assert_cmpstr (str, ==, buf);
95       g_assert_cmpint (g_utf8_strlen (buf, -1), ==, expected_nchar);
96       g_assert (err == NULL);
97     }
98   g_free (buf);
99
100   g_object_unref (in);
101 }
102
103 static void
104 test_read_ascii (void)
105 {
106   do_test_read ("foobar", 6, 6);
107 }
108
109 static void
110 test_read_utf8 (void)
111 {
112   do_test_read ("foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz", 18, 15);
113 }
114
115 static void
116 test_read_utf8_partial (void)
117 {
118   do_test_read_partial ("foobar\xc3\xa8\xc3\xa8\xc3\xa8zzzzzz", 7, 6, 12, 15);
119 }
120
121 static void
122 test_read_invalid_start (void)
123 {
124   do_test_read ("\xef\xbf\xbezzzzzz", -1, -1);
125 }
126
127 static void
128 test_read_invalid_middle (void)
129 {
130   do_test_read ("foobar\xef\xbf\xbezzzzzz", -1, -1);
131 }
132
133 static void
134 test_read_invalid_end (void)
135 {
136   do_test_read ("foobar\xef\xbf\xbe", -1, -1);
137 }
138
139 static void
140 test_read_invalid_partial (void)
141 {
142   do_test_read_partial ("foobar\xef\xbf\xbezzzzzz", 7, 6, -1, -1);
143 }
144
145 static void
146 test_read_small_valid (void)
147 {
148   GInputStream *base;
149   GInputStream *in;
150   gssize len, n;
151   char *buf;
152   GError *err;
153
154   base = g_memory_input_stream_new_from_data ("\xc3\xa8\xc3\xa8", -1, NULL);
155   in = g_utf8_input_stream_new (base);
156   g_object_unref (base);
157
158   len = strlen("\xc3\xa8\xc3\xa8");
159   buf = g_new0 (char, len);
160   err = NULL;
161
162   /* read a single byte */
163   n = g_input_stream_read (in, buf, 1, NULL, &err);
164   g_assert_cmpint (n, ==, 1);
165   g_assert_cmpstr ("\xc3", ==, buf);
166   g_assert (err == NULL);
167
168   /* read the rest */
169   n = g_input_stream_read (in, buf + n, len - n, NULL, &err);
170   g_assert_cmpint (n, ==, len - 1);
171   g_assert_cmpstr ("\xc3\xa8\xc3\xa8", ==, buf);
172   g_assert (err == NULL);
173
174   g_object_unref (in);
175 }
176
177 static void
178 test_read_small_invalid (void)
179 {
180   GInputStream *base;
181   GInputStream *in;
182   gssize n;
183   char *buf;
184   GError *err;
185
186   base = g_memory_input_stream_new_from_data ("\xbf\xbe", -1, NULL);
187   in = g_utf8_input_stream_new (base);
188   g_object_unref (base);
189
190   buf = g_new0 (char, 2);
191   err = NULL;
192   n = g_input_stream_read (in, buf, 1, NULL, &err);
193   g_assert_cmpint (n, ==, -1);
194   g_assert_error (err, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
195
196   g_object_unref (in);
197 }
198
199 static void
200 test_read_small_consecutive (void)
201 {
202   GInputStream *base;
203   GInputStream *in;
204   gssize len, n;
205   char *buf;
206   GError *err;
207
208   base = g_memory_input_stream_new_from_data ("\xc3\xa8\xc3\xa8", -1, NULL);
209   in = g_utf8_input_stream_new (base);
210   g_object_unref (base);
211
212   len = strlen("\xc3\xa8\xc3\xa8");
213   buf = g_new0 (char, len);
214   err = NULL;
215   n = 0;
216
217   /* read a single byte at a time */
218   while (n < len)
219   {
220     gssize r;
221
222     r = g_input_stream_read (in, buf + n, 1, NULL, &err);
223     g_assert_cmpint (r, ==, 1);
224     g_assert (err == NULL);
225
226     n += r;
227   }
228
229   g_assert_cmpstr ("\xc3\xa8\xc3\xa8", ==, buf);
230
231   g_object_unref (in);
232 }
233
234 int
235 main (int   argc,
236       char *argv[])
237 {
238   g_type_init ();
239   g_test_init (&argc, &argv, NULL);
240   g_test_add_func ("/utf8-input-stream/read-ascii", test_read_ascii);
241   g_test_add_func ("/utf8-input-stream/read-utf8", test_read_utf8);
242   g_test_add_func ("/utf8-input-stream/read-utf8-partial", test_read_utf8_partial);
243   g_test_add_func ("/utf8-input-stream/read-invalid-start", test_read_invalid_start);
244   g_test_add_func ("/utf8-input-stream/read-invalid-middle", test_read_invalid_middle);
245   g_test_add_func ("/utf8-input-stream/read-invalid-end", test_read_invalid_end);
246   g_test_add_func ("/utf8-input-stream/read-invalid-partial", test_read_invalid_partial);
247   g_test_add_func ("/utf8-input-stream/read-small-valid", test_read_small_valid);
248   g_test_add_func ("/utf8-input-stream/read-small-invalid", test_read_small_invalid);
249   g_test_add_func ("/utf8-input-stream/read-small-consecutive", test_read_small_consecutive);
250
251   return g_test_run();
252 }