1/*
2 * Copyright © 2009 Codethink Limited
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2 of the licence or (at
7 * your option) any later version.
8 *
9 * See the included COPYING file for more information.
10 *
11 * Author: Ryan Lortie <desrt@desrt.ca>
12 */
13
14#include <glib/glib.h>
15#include <gio/gio.h>
16
17static void
18test_input_filter (void)
19{
20  GInputStream *base, *f1, *f2;
21
22  g_test_bug ("568394");
23  base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
24  f1 = g_buffered_input_stream_new (base);
25  f2 = g_buffered_input_stream_new (base);
26
27  g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (f1), FALSE);
28
29  g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
30  g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
31
32  g_assert (!g_input_stream_is_closed (base));
33  g_assert (!g_input_stream_is_closed (f1));
34  g_assert (!g_input_stream_is_closed (f2));
35
36  g_object_unref (f1);
37
38  g_assert (!g_input_stream_is_closed (base));
39  g_assert (!g_input_stream_is_closed (f2));
40
41  g_object_unref (f2);
42
43  g_assert (g_input_stream_is_closed (base));
44
45  g_object_unref (base);
46}
47
48static void
49test_output_filter (void)
50{
51  GOutputStream *base, *f1, *f2;
52
53  base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
54  f1 = g_buffered_output_stream_new (base);
55  f2 = g_buffered_output_stream_new (base);
56
57  g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (f1), FALSE);
58
59  g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
60  g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
61
62  g_assert (!g_output_stream_is_closed (base));
63  g_assert (!g_output_stream_is_closed (f1));
64  g_assert (!g_output_stream_is_closed (f2));
65
66  g_object_unref (f1);
67
68  g_assert (!g_output_stream_is_closed (base));
69  g_assert (!g_output_stream_is_closed (f2));
70
71  g_object_unref (f2);
72
73  g_assert (g_output_stream_is_closed (base));
74
75  g_object_unref (base);
76}
77
78gpointer expected_obj;
79gpointer expected_data;
80gboolean callback_happened;
81
82static void
83in_cb (GObject      *object,
84       GAsyncResult *result,
85       gpointer      user_data)
86{
87  GError *error = NULL;
88
89  g_assert (object == expected_obj);
90  g_assert (user_data == expected_data);
91  g_assert (callback_happened == FALSE);
92
93  g_input_stream_close_finish (expected_obj, result, &error);
94  g_assert (error == NULL);
95
96  callback_happened = TRUE;
97}
98
99static void
100test_input_async (void)
101{
102  GInputStream *base, *f1, *f2;
103
104  base = g_memory_input_stream_new_from_data ("abcdefghijk", -1, NULL);
105  f1 = g_buffered_input_stream_new (base);
106  f2 = g_buffered_input_stream_new (base);
107
108  g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (f1), FALSE);
109
110  g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f1)) == base);
111  g_assert (g_filter_input_stream_get_base_stream (G_FILTER_INPUT_STREAM (f2)) == base);
112
113  g_assert (!g_input_stream_is_closed (base));
114  g_assert (!g_input_stream_is_closed (f1));
115  g_assert (!g_input_stream_is_closed (f2));
116
117  expected_obj = f1;
118  expected_data = g_malloc (20);
119  callback_happened = FALSE;
120  g_input_stream_close_async (f1, 0, NULL, in_cb, expected_data);
121
122  g_assert (callback_happened == FALSE);
123  while (g_main_context_pending (NULL))
124    g_main_context_iteration (NULL, FALSE);
125  g_assert (callback_happened == TRUE);
126
127  g_assert (!g_input_stream_is_closed (base));
128  g_assert (!g_input_stream_is_closed (f2));
129  g_free (expected_data);
130  g_object_unref (f1);
131  g_assert (!g_input_stream_is_closed (base));
132  g_assert (!g_input_stream_is_closed (f2));
133
134  expected_obj = f2;
135  expected_data = g_malloc (20);
136  callback_happened = FALSE;
137  g_input_stream_close_async (f2, 0, NULL, in_cb, expected_data);
138
139  g_assert (callback_happened == FALSE);
140  while (g_main_context_pending (NULL))
141    g_main_context_iteration (NULL, FALSE);
142  g_assert (callback_happened == TRUE);
143
144  g_assert (g_input_stream_is_closed (base));
145  g_assert (g_input_stream_is_closed (f2));
146  g_free (expected_data);
147  g_object_unref (f2);
148
149  g_assert (g_input_stream_is_closed (base));
150  g_object_unref (base);
151}
152
153static void
154out_cb (GObject      *object,
155        GAsyncResult *result,
156        gpointer      user_data)
157{
158  GError *error = NULL;
159
160  g_assert (object == expected_obj);
161  g_assert (user_data == expected_data);
162  g_assert (callback_happened == FALSE);
163
164  g_output_stream_close_finish (expected_obj, result, &error);
165  g_assert (error == NULL);
166
167  callback_happened = TRUE;
168}
169
170
171static void
172test_output_async (void)
173{
174  GOutputStream *base, *f1, *f2;
175
176  base = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
177  f1 = g_buffered_output_stream_new (base);
178  f2 = g_buffered_output_stream_new (base);
179
180  g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (f1), FALSE);
181
182  g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f1)) == base);
183  g_assert (g_filter_output_stream_get_base_stream (G_FILTER_OUTPUT_STREAM (f2)) == base);
184
185  g_assert (!g_output_stream_is_closed (base));
186  g_assert (!g_output_stream_is_closed (f1));
187  g_assert (!g_output_stream_is_closed (f2));
188
189  expected_obj = f1;
190  expected_data = g_malloc (20);
191  callback_happened = FALSE;
192  g_output_stream_close_async (f1, 0, NULL, out_cb, expected_data);
193
194  g_assert (callback_happened == FALSE);
195  while (g_main_context_pending (NULL))
196    g_main_context_iteration (NULL, FALSE);
197  g_assert (callback_happened == TRUE);
198
199  g_assert (!g_output_stream_is_closed (base));
200  g_assert (!g_output_stream_is_closed (f2));
201  g_free (expected_data);
202  g_object_unref (f1);
203  g_assert (!g_output_stream_is_closed (base));
204  g_assert (!g_output_stream_is_closed (f2));
205
206  expected_obj = f2;
207  expected_data = g_malloc (20);
208  callback_happened = FALSE;
209  g_output_stream_close_async (f2, 0, NULL, out_cb, expected_data);
210
211  g_assert (callback_happened == FALSE);
212  while (g_main_context_pending (NULL))
213    g_main_context_iteration (NULL, FALSE);
214  g_assert (callback_happened == TRUE);
215
216  g_assert (g_output_stream_is_closed (base));
217  g_assert (g_output_stream_is_closed (f2));
218  g_free (expected_data);
219  g_object_unref (f2);
220
221  g_assert (g_output_stream_is_closed (base));
222  g_object_unref (base);
223}
224
225
226int
227main (int argc, char **argv)
228{
229  g_test_init (&argc, &argv, NULL);
230  g_test_bug_base ("http://bugzilla.gnome.org/");
231
232  g_type_init ();
233  g_test_add_func ("/filter-stream/input", test_input_filter);
234  g_test_add_func ("/filter-stream/output", test_output_filter);
235  g_test_add_func ("/filter-stream/async-input", test_input_async);
236  g_test_add_func ("/filter-stream/async-output", test_output_async);
237
238  return g_test_run();
239}
240