1 /* GLib testing framework examples and tests
2 * Copyright (C) 2007 Imendio AB
3 * Authors: Tim Janik
4 *
5 * SPDX-License-Identifier: LicenseRef-old-glib-tests
6 *
7 * This work is provided "as is"; redistribution and modification
8 * in whole or in part, in any medium, physical or electronic is
9 * permitted without restriction.
10 *
11 * This work is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 *
15 * In no event shall the authors or contributors be liable for any
16 * direct, indirect, incidental, special, exemplary, or consequential
17 * damages (including, but not limited to, procurement of substitute
18 * goods or services; loss of use, data, or profits; or business
19 * interruption) however caused and on any theory of liability, whether
20 * in contract, strict liability, or tort (including negligence or
21 * otherwise) arising in any way out of the use of this software, even
22 * if advised of the possibility of such damage.
23 */
24
25 #include <glib/glib.h>
26 #include <gio/gio.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 static void
31 test_read_chunks (void)
32 {
33 const char *data1 = "abcdefghijklmnopqrstuvwxyz";
34 const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
35 const char *result = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
36 char buffer[128];
37 gsize bytes_read, pos, len, chunk_size;
38 GError *error = NULL;
39 GInputStream *stream;
40 gboolean res;
41
42 stream = g_memory_input_stream_new ();
43
44 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
45 data1, -1, NULL);
46 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
47 data2, -1, NULL);
48 len = strlen (data1) + strlen (data2);
49
50 for (chunk_size = 1; chunk_size < len - 1; chunk_size++)
51 {
52 pos = 0;
53 while (pos < len)
54 {
55 bytes_read = g_input_stream_read (stream, buffer, chunk_size, NULL, &error);
56 g_assert_no_error (error);
57 g_assert_cmpint (bytes_read, ==, MIN (chunk_size, len - pos));
58 g_assert (strncmp (buffer, result + pos, bytes_read) == 0);
59
60 pos += bytes_read;
61 }
62
63 g_assert_cmpint (pos, ==, len);
64 res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
65 g_assert_cmpint (res, ==, TRUE);
66 g_assert_no_error (error);
67 }
68
69 g_object_unref (stream);
70 }
71
72 GMainLoop *loop;
73
74 static void
75 async_read_chunk (GObject *object,
76 GAsyncResult *result,
77 gpointer user_data)
78 {
79 gsize *bytes_read = user_data;
80 GError *error = NULL;
81
82 *bytes_read = g_input_stream_read_finish (G_INPUT_STREAM (object),
83 result, &error);
84 g_assert_no_error (error);
85
86 g_main_loop_quit (loop);
87 }
88
89 static void
90 async_skipped_chunk (GObject *object,
91 GAsyncResult *result,
92 gpointer user_data)
93 {
94 gsize *bytes_skipped = user_data;
95 GError *error = NULL;
96
97 *bytes_skipped = g_input_stream_skip_finish (G_INPUT_STREAM (object),
98 result, &error);
99 g_assert_no_error (error);
100
101 g_main_loop_quit (loop);
102 }
103
104 static void
105 test_async (void)
106 {
107 const char *data1 = "abcdefghijklmnopqrstuvwxyz";
108 const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
109 const char *result = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
110 char buffer[128];
111 gsize bytes_read, bytes_skipped;
112 gsize pos, len, chunk_size;
113 GError *error = NULL;
114 GInputStream *stream;
115 gboolean res;
116
117 loop = g_main_loop_new (NULL, FALSE);
118
119 stream = g_memory_input_stream_new ();
120
121 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
122 data1, -1, NULL);
123 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
124 data2, -1, NULL);
125 len = strlen (data1) + strlen (data2);
126
127 for (chunk_size = 1; chunk_size < len - 1; chunk_size++)
128 {
129 pos = 0;
130 while (pos < len)
131 {
132 g_input_stream_read_async (stream, buffer, chunk_size,
133 G_PRIORITY_DEFAULT, NULL,
134 async_read_chunk, &bytes_read);
135 g_main_loop_run (loop);
136
137 g_assert_cmpint (bytes_read, ==, MIN (chunk_size, len - pos));
138 g_assert (strncmp (buffer, result + pos, bytes_read) == 0);
139
140 pos += bytes_read;
141 }
142
143 g_assert_cmpint (pos, ==, len);
144 res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
145 g_assert_cmpint (res, ==, TRUE);
146 g_assert_no_error (error);
147
148 pos = 0;
149 while (pos + chunk_size + 1 < len)
150 {
151 g_input_stream_skip_async (stream, chunk_size,
152 G_PRIORITY_DEFAULT, NULL,
153 async_skipped_chunk, &bytes_skipped);
154 g_main_loop_run (loop);
155
156 g_assert_cmpint (bytes_skipped, ==, MIN (chunk_size, len - pos));
157
158 pos += bytes_skipped;
159 }
160
161 g_input_stream_read_async (stream, buffer, len - pos,
162 G_PRIORITY_DEFAULT, NULL,
163 async_read_chunk, &bytes_read);
164 g_main_loop_run (loop);
165
166 g_assert_cmpint (bytes_read, ==, len - pos);
167 g_assert (strncmp (buffer, result + pos, bytes_read) == 0);
168
169 res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
170 g_assert_cmpint (res, ==, TRUE);
171 g_assert_no_error (error);
172 }
173
174 g_object_unref (stream);
175 g_main_loop_unref (loop);
176 }
177
178 static void
179 test_seek (void)
180 {
181 const char *data1 = "abcdefghijklmnopqrstuvwxyz";
182 const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
183 GInputStream *stream;
184 GError *error;
185 char buffer[10];
186
187 stream = g_memory_input_stream_new ();
188
189 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
190 data1, -1, NULL);
191 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
192 data2, -1, NULL);
193
194 g_assert (G_IS_SEEKABLE (stream));
195 g_assert (g_seekable_can_seek (G_SEEKABLE (stream)));
196
197 error = NULL;
198 g_assert (g_seekable_seek (G_SEEKABLE (stream), 26, G_SEEK_SET, NULL, &error));
199 g_assert_no_error (error);
200 g_assert_cmpint (g_seekable_tell (G_SEEKABLE (stream)), ==, 26);
201
202 g_assert (g_input_stream_read (stream, buffer, 1, NULL, &error) == 1);
203 g_assert_no_error (error);
204
205 g_assert (buffer[0] == 'A');
206
207 g_assert (!g_seekable_seek (G_SEEKABLE (stream), 26, G_SEEK_CUR, NULL, &error));
208 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
209 g_error_free (error);
210
211 g_object_unref (stream);
212 }
213
214 static void
215 test_truncate (void)
216 {
217 const char *data1 = "abcdefghijklmnopqrstuvwxyz";
218 const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
219 GInputStream *stream;
220 GError *error;
221
222 stream = g_memory_input_stream_new ();
223
224 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
225 data1, -1, NULL);
226 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
227 data2, -1, NULL);
228
229 g_assert (G_IS_SEEKABLE (stream));
230 g_assert (!g_seekable_can_truncate (G_SEEKABLE (stream)));
231
232 error = NULL;
233 g_assert (!g_seekable_truncate (G_SEEKABLE (stream), 26, NULL, &error));
234 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
235 g_error_free (error);
236
237 g_object_unref (stream);
238 }
239
240 static void
241 test_read_bytes (void)
242 {
243 const char *data1 = "abcdefghijklmnopqrstuvwxyz";
244 const char *data2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
245 GInputStream *stream;
246 GError *error = NULL;
247 GBytes *bytes;
248 gsize size;
249 gconstpointer data;
250
251 stream = g_memory_input_stream_new ();
252 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
253 data1, -1, NULL);
254 g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (stream),
255 data2, -1, NULL);
256
257 bytes = g_input_stream_read_bytes (stream, 26, NULL, &error);
258 g_assert_no_error (error);
259
260 data = g_bytes_get_data (bytes, &size);
261 g_assert_cmpint (size, ==, 26);
262 g_assert (strncmp (data, data1, 26) == 0);
263
264 g_bytes_unref (bytes);
265 g_object_unref (stream);
266 }
267
268 static void
269 test_from_bytes (void)
270 {
271 gchar data[4096], buffer[4096];
272 GBytes *bytes;
273 GError *error = NULL;
274 GInputStream *stream;
275 gint i;
276
277 for (i = 0; i < 4096; i++)
278 data[i] = 1 + i % 255;
279
280 bytes = g_bytes_new_static (data, 4096);
281 stream = g_memory_input_stream_new_from_bytes (bytes);
282 g_assert (g_input_stream_read (stream, buffer, 2048, NULL, &error) == 2048);
283 g_assert_no_error (error);
284 g_assert (strncmp (data, buffer, 2048) == 0);
285
286 g_object_unref (stream);
287 g_bytes_unref (bytes);
288 }
289
290 int
291 main (int argc,
292 char *argv[])
293 {
294 g_test_init (&argc, &argv, NULL);
295
296 g_test_add_func ("/memory-input-stream/read-chunks", test_read_chunks);
297 g_test_add_func ("/memory-input-stream/async", test_async);
298 g_test_add_func ("/memory-input-stream/seek", test_seek);
299 g_test_add_func ("/memory-input-stream/truncate", test_truncate);
300 g_test_add_func ("/memory-input-stream/read-bytes", test_read_bytes);
301 g_test_add_func ("/memory-input-stream/from-bytes", test_from_bytes);
302
303 return g_test_run();
304 }