Branch data Line data Source code
1 : : /*
2 : : * Copyright © 2009 Codethink Limited
3 : : *
4 : : * SPDX-License-Identifier: LGPL-2.1-or-later
5 : : *
6 : : * This library is free software; you can redistribute it and/or
7 : : * modify it under the terms of the GNU Lesser General Public
8 : : * License as published by the Free Software Foundation; either
9 : : * version 2.1 of the License, or (at your option) any later version.
10 : : *
11 : : * See the included COPYING file for more information.
12 : : *
13 : : * Author: Ryan Lortie <desrt@desrt.ca>
14 : : */
15 : :
16 : : #include <string.h>
17 : : #include <glib/glib.h>
18 : : #include <gio/gio.h>
19 : :
20 : : /* GFilterInputStream and GFilterOutputStream are abstract, so define
21 : : * minimal subclasses for testing. (This used to use
22 : : * GBufferedInputStream and GBufferedOutputStream, but those have
23 : : * their own test program, and they override some methods, meaning the
24 : : * core filter stream functionality wasn't getting fully tested.)
25 : : */
26 : :
27 : : GType test_filter_input_stream_get_type (void);
28 : : GType test_filter_output_stream_get_type (void);
29 : :
30 : : #define TEST_TYPE_FILTER_INPUT_STREAM (test_filter_input_stream_get_type ())
31 : : #define TEST_FILTER_INPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_FILTER_INPUT_STREAM, TestFilterInputStream))
32 : : #define TEST_TYPE_FILTER_OUTPUT_STREAM (test_filter_output_stream_get_type ())
33 : : #define TEST_FILTER_OUTPUT_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), TEST_TYPE_FILTER_OUTPUT_STREAM, TestFilterOutputStream))
34 : :
35 : : typedef GFilterInputStream TestFilterInputStream;
36 : : typedef GFilterInputStreamClass TestFilterInputStreamClass;
37 : : typedef GFilterOutputStream TestFilterOutputStream;
38 : : typedef GFilterOutputStreamClass TestFilterOutputStreamClass;
39 : :
40 : 6 : G_DEFINE_TYPE (TestFilterInputStream, test_filter_input_stream, G_TYPE_FILTER_INPUT_STREAM)
41 : 6 : G_DEFINE_TYPE (TestFilterOutputStream, test_filter_output_stream, G_TYPE_FILTER_OUTPUT_STREAM)
42 : :
43 : : static void
44 : 4 : test_filter_input_stream_init (TestFilterInputStream *stream)
45 : : {
46 : 4 : }
47 : :
48 : : static void
49 : 1 : test_filter_input_stream_class_init (TestFilterInputStreamClass *klass)
50 : : {
51 : 1 : }
52 : :
53 : : static void
54 : 4 : test_filter_output_stream_init (TestFilterOutputStream *stream)
55 : : {
56 : 4 : }
57 : :
58 : : static void
59 : 1 : test_filter_output_stream_class_init (TestFilterOutputStreamClass *klass)
60 : : {
61 : 1 : }
62 : :
63 : : /* Now the tests */
64 : :
65 : : static void
66 : 1 : test_input_filter (void)
67 : : {
68 : : GInputStream *base, *f1, *f2, *s;
69 : : gboolean close_base;
70 : : gchar buf[1024];
71 : 1 : GError *error = NULL;
72 : :
73 : 1 : g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=568394");
74 : 1 : base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
75 : 1 : f1 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
76 : : "base-stream", base,
77 : : "close-base-stream", FALSE,
78 : : NULL);
79 : 1 : f2 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
80 : : "base-stream", base,
81 : : NULL);
82 : :
83 : 1 : g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
84 : 1 : g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
85 : :
86 : 1 : g_assert (!g_input_stream_is_closed (base));
87 : 1 : g_assert (!g_input_stream_is_closed (f1));
88 : 1 : g_assert (!g_input_stream_is_closed (f2));
89 : :
90 : 1 : g_object_get (f1,
91 : : "close-base-stream", &close_base,
92 : : "base-stream", &s,
93 : : NULL);
94 : 1 : g_assert (!close_base);
95 : 1 : g_assert (s == base);
96 : 1 : g_object_unref (s);
97 : :
98 : 1 : g_object_unref (f1);
99 : :
100 : 1 : g_assert (!g_input_stream_is_closed (base));
101 : 1 : g_assert (!g_input_stream_is_closed (f2));
102 : :
103 : 1 : g_input_stream_skip (f2, 3, NULL, &error);
104 : 1 : g_assert_no_error (error);
105 : :
106 : 1 : memset (buf, 0, 1024);
107 : 1 : g_input_stream_read_all (f2, buf, 1024, NULL, NULL, &error);
108 : 1 : g_assert_no_error (error);
109 : 1 : g_assert_cmpstr (buf, ==, "defghijk");
110 : :
111 : 1 : g_object_unref (f2);
112 : :
113 : 1 : g_assert (g_input_stream_is_closed (base));
114 : :
115 : 1 : g_object_unref (base);
116 : 1 : }
117 : :
118 : : static void
119 : 1 : test_output_filter (void)
120 : : {
121 : : GOutputStream *base, *f1, *f2;
122 : :
123 : 1 : base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
124 : 1 : f1 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
125 : : "base-stream", base,
126 : : "close-base-stream", FALSE,
127 : : NULL);
128 : 1 : f2 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
129 : : "base-stream", base,
130 : : NULL);
131 : :
132 : 1 : g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
133 : 1 : g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
134 : :
135 : 1 : g_assert (!g_output_stream_is_closed (base));
136 : 1 : g_assert (!g_output_stream_is_closed (f1));
137 : 1 : g_assert (!g_output_stream_is_closed (f2));
138 : :
139 : 1 : g_object_unref (f1);
140 : :
141 : 1 : g_assert (!g_output_stream_is_closed (base));
142 : 1 : g_assert (!g_output_stream_is_closed (f2));
143 : :
144 : 1 : g_object_unref (f2);
145 : :
146 : 1 : g_assert (g_output_stream_is_closed (base));
147 : :
148 : 1 : g_object_unref (base);
149 : 1 : }
150 : :
151 : : gpointer expected_obj;
152 : : gpointer expected_data;
153 : : gboolean callback_happened;
154 : : GMainLoop *loop;
155 : :
156 : : static void
157 : 5 : return_result_cb (GObject *object,
158 : : GAsyncResult *result,
159 : : gpointer user_data)
160 : : {
161 : 5 : GAsyncResult **ret = user_data;
162 : :
163 : 5 : *ret = g_object_ref (result);
164 : 5 : g_main_loop_quit (loop);
165 : 5 : }
166 : :
167 : : static void
168 : 2 : in_cb (GObject *object,
169 : : GAsyncResult *result,
170 : : gpointer user_data)
171 : : {
172 : 2 : GError *error = NULL;
173 : :
174 : 2 : g_assert (object == expected_obj);
175 : 2 : g_assert (user_data == expected_data);
176 : 2 : g_assert (callback_happened == FALSE);
177 : :
178 : 2 : g_input_stream_close_finish (expected_obj, result, &error);
179 : 2 : g_assert (error == NULL);
180 : :
181 : 2 : callback_happened = TRUE;
182 : 2 : g_main_loop_quit (loop);
183 : 2 : }
184 : :
185 : : static void
186 : 1 : test_input_async (void)
187 : : {
188 : : GInputStream *base, *f1, *f2;
189 : : char buf[20];
190 : 1 : GAsyncResult *result = NULL;
191 : 1 : GError *error = NULL;
192 : :
193 : 1 : loop = g_main_loop_new (NULL, FALSE);
194 : :
195 : 1 : base = g_memory_input_stream_new_from_data ("abcdefghijklmnopqrstuvwxyz", -1, NULL);
196 : 1 : f1 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
197 : : "base-stream", base,
198 : : "close-base-stream", FALSE,
199 : : NULL);
200 : 1 : f2 = g_object_new (TEST_TYPE_FILTER_INPUT_STREAM,
201 : : "base-stream", base,
202 : : NULL);
203 : :
204 : 1 : g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
205 : 1 : g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
206 : :
207 : :
208 : 1 : memset (buf, 0, sizeof (buf));
209 : 1 : g_input_stream_read_async (f1, buf, 10, G_PRIORITY_DEFAULT,
210 : : NULL, return_result_cb, &result);
211 : 1 : g_main_loop_run (loop);
212 : 1 : g_assert_cmpint (g_input_stream_read_finish (f1, result, &error), ==, 10);
213 : 1 : g_assert_cmpstr (buf, ==, "abcdefghij");
214 : 1 : g_assert_no_error (error);
215 : 1 : g_clear_object (&result);
216 : :
217 : 1 : g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 10);
218 : :
219 : 1 : g_input_stream_skip_async (f2, 10, G_PRIORITY_DEFAULT,
220 : : NULL, return_result_cb, &result);
221 : 1 : g_main_loop_run (loop);
222 : 1 : g_assert_cmpint (g_input_stream_skip_finish (f2, result, &error), ==, 10);
223 : 1 : g_assert_no_error (error);
224 : 1 : g_clear_object (&result);
225 : :
226 : 1 : g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 20);
227 : :
228 : 1 : memset (buf, 0, sizeof (buf));
229 : 1 : g_input_stream_read_async (f1, buf, 10, G_PRIORITY_DEFAULT,
230 : : NULL, return_result_cb, &result);
231 : 1 : g_main_loop_run (loop);
232 : 1 : g_assert_cmpint (g_input_stream_read_finish (f1, result, &error), ==, 6);
233 : 1 : g_assert_cmpstr (buf, ==, "uvwxyz");
234 : 1 : g_assert_no_error (error);
235 : 1 : g_clear_object (&result);
236 : :
237 : 1 : g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 26);
238 : :
239 : :
240 : 1 : g_assert (!g_input_stream_is_closed (base));
241 : 1 : g_assert (!g_input_stream_is_closed (f1));
242 : 1 : g_assert (!g_input_stream_is_closed (f2));
243 : :
244 : 1 : expected_obj = f1;
245 : 1 : expected_data = g_malloc (20);
246 : 1 : callback_happened = FALSE;
247 : 1 : g_input_stream_close_async (f1, 0, NULL, in_cb, expected_data);
248 : :
249 : 1 : g_assert (callback_happened == FALSE);
250 : 1 : g_main_loop_run (loop);
251 : 1 : g_assert (callback_happened == TRUE);
252 : :
253 : 1 : g_assert (!g_input_stream_is_closed (base));
254 : 1 : g_assert (!g_input_stream_is_closed (f2));
255 : 1 : g_free (expected_data);
256 : 1 : g_object_unref (f1);
257 : 1 : g_assert (!g_input_stream_is_closed (base));
258 : 1 : g_assert (!g_input_stream_is_closed (f2));
259 : :
260 : 1 : expected_obj = f2;
261 : 1 : expected_data = g_malloc (20);
262 : 1 : callback_happened = FALSE;
263 : 1 : g_input_stream_close_async (f2, 0, NULL, in_cb, expected_data);
264 : :
265 : 1 : g_assert (callback_happened == FALSE);
266 : 1 : g_main_loop_run (loop);
267 : 1 : g_assert (callback_happened == TRUE);
268 : :
269 : 1 : g_assert (g_input_stream_is_closed (base));
270 : 1 : g_assert (g_input_stream_is_closed (f2));
271 : 1 : g_free (expected_data);
272 : 1 : g_object_unref (f2);
273 : :
274 : 1 : g_assert (g_input_stream_is_closed (base));
275 : 1 : g_object_unref (base);
276 : 1 : g_main_loop_unref (loop);
277 : 1 : }
278 : :
279 : : static void
280 : 2 : out_cb (GObject *object,
281 : : GAsyncResult *result,
282 : : gpointer user_data)
283 : : {
284 : 2 : GError *error = NULL;
285 : :
286 : 2 : g_assert (object == expected_obj);
287 : 2 : g_assert (user_data == expected_data);
288 : 2 : g_assert (callback_happened == FALSE);
289 : :
290 : 2 : g_output_stream_close_finish (expected_obj, result, &error);
291 : 2 : g_assert (error == NULL);
292 : :
293 : 2 : callback_happened = TRUE;
294 : 2 : g_main_loop_quit (loop);
295 : 2 : }
296 : :
297 : : static void
298 : 1 : test_output_async (void)
299 : : {
300 : : GOutputStream *base, *f1, *f2;
301 : 1 : GAsyncResult *result = NULL;
302 : 1 : GError *error = NULL;
303 : :
304 : 1 : loop = g_main_loop_new (NULL, FALSE);
305 : :
306 : 1 : base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
307 : 1 : f1 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
308 : : "base-stream", base,
309 : : "close-base-stream", FALSE,
310 : : NULL);
311 : 1 : f2 = g_object_new (TEST_TYPE_FILTER_OUTPUT_STREAM,
312 : : "base-stream", base,
313 : : NULL);
314 : :
315 : 1 : g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
316 : 1 : g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
317 : :
318 : :
319 : 1 : g_output_stream_write_async (f1, "abcdefghijklm", 13, G_PRIORITY_DEFAULT,
320 : : NULL, return_result_cb, &result);
321 : 1 : g_main_loop_run (loop);
322 : 1 : g_assert_cmpint (g_output_stream_write_finish (f1, result, &error), ==, 13);
323 : 1 : g_assert_no_error (error);
324 : 1 : g_clear_object (&result);
325 : :
326 : 1 : g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 13);
327 : :
328 : 1 : g_output_stream_write_async (f2, "nopqrstuvwxyz", 13, G_PRIORITY_DEFAULT,
329 : : NULL, return_result_cb, &result);
330 : 1 : g_main_loop_run (loop);
331 : 1 : g_assert_cmpint (g_output_stream_write_finish (f2, result, &error), ==, 13);
332 : 1 : g_assert_no_error (error);
333 : 1 : g_clear_object (&result);
334 : :
335 : 1 : g_assert_cmpint (g_seekable_tell (G_SEEKABLE (base)), ==, 26);
336 : :
337 : 1 : g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 26);
338 : 1 : g_output_stream_write (base, "\0", 1, NULL, &error);
339 : 1 : g_assert_no_error (error);
340 : 1 : g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnopqrstuvwxyz");
341 : :
342 : :
343 : 1 : g_assert (!g_output_stream_is_closed (base));
344 : 1 : g_assert (!g_output_stream_is_closed (f1));
345 : 1 : g_assert (!g_output_stream_is_closed (f2));
346 : :
347 : 1 : expected_obj = f1;
348 : 1 : expected_data = g_malloc (20);
349 : 1 : callback_happened = FALSE;
350 : 1 : g_output_stream_close_async (f1, 0, NULL, out_cb, expected_data);
351 : :
352 : 1 : g_assert (callback_happened == FALSE);
353 : 1 : g_main_loop_run (loop);
354 : 1 : g_assert (callback_happened == TRUE);
355 : :
356 : 1 : g_assert (!g_output_stream_is_closed (base));
357 : 1 : g_assert (!g_output_stream_is_closed (f2));
358 : 1 : g_free (expected_data);
359 : 1 : g_object_unref (f1);
360 : 1 : g_assert (!g_output_stream_is_closed (base));
361 : 1 : g_assert (!g_output_stream_is_closed (f2));
362 : :
363 : 1 : expected_obj = f2;
364 : 1 : expected_data = g_malloc (20);
365 : 1 : callback_happened = FALSE;
366 : 1 : g_output_stream_close_async (f2, 0, NULL, out_cb, expected_data);
367 : :
368 : 1 : g_assert (callback_happened == FALSE);
369 : 1 : g_main_loop_run (loop);
370 : 1 : g_assert (callback_happened == TRUE);
371 : :
372 : 1 : g_assert (g_output_stream_is_closed (base));
373 : 1 : g_assert (g_output_stream_is_closed (f2));
374 : 1 : g_free (expected_data);
375 : 1 : g_object_unref (f2);
376 : :
377 : 1 : g_assert (g_output_stream_is_closed (base));
378 : 1 : g_object_unref (base);
379 : 1 : g_main_loop_unref (loop);
380 : 1 : }
381 : :
382 : : int
383 : 1 : main (int argc, char **argv)
384 : : {
385 : 1 : g_test_init (&argc, &argv, NULL);
386 : :
387 : 1 : g_test_add_func ("/filter-stream/input", test_input_filter);
388 : 1 : g_test_add_func ("/filter-stream/output", test_output_filter);
389 : 1 : g_test_add_func ("/filter-stream/async-input", test_input_async);
390 : 1 : g_test_add_func ("/filter-stream/async-output", test_output_async);
391 : :
392 : 1 : return g_test_run();
393 : : }
|