1 | #include <gio/gio.h> |
2 | |
3 | static void |
4 | test_write (void) |
5 | { |
6 | GOutputStream *base; |
7 | GOutputStream *out; |
8 | GError *error; |
9 | const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz" ; |
10 | |
11 | base = g_memory_output_stream_new (data: g_malloc0 (n_bytes: 20), size: 20, NULL, destroy_function: g_free); |
12 | out = g_buffered_output_stream_new (base_stream: base); |
13 | |
14 | g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 4096); |
15 | g_assert (!g_buffered_output_stream_get_auto_grow (G_BUFFERED_OUTPUT_STREAM (out))); |
16 | g_object_set (object: out, first_property_name: "auto-grow" , TRUE, NULL); |
17 | g_assert (g_buffered_output_stream_get_auto_grow (G_BUFFERED_OUTPUT_STREAM (out))); |
18 | g_object_set (object: out, first_property_name: "auto-grow" , FALSE, NULL); |
19 | |
20 | g_buffered_output_stream_set_buffer_size (G_BUFFERED_OUTPUT_STREAM (out), size: 16); |
21 | g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 16); |
22 | |
23 | error = NULL; |
24 | g_assert_cmpint (g_output_stream_write (out, buffer, 10, NULL, &error), ==, 10); |
25 | g_assert_no_error (error); |
26 | |
27 | g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); |
28 | |
29 | g_assert_cmpint (g_output_stream_write (out, buffer + 10, 10, NULL, &error), ==, 6); |
30 | g_assert_no_error (error); |
31 | |
32 | g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); |
33 | g_assert (g_output_stream_flush (out, NULL, &error)); |
34 | g_assert_no_error (error); |
35 | g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 16); |
36 | |
37 | g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnop" ); |
38 | |
39 | g_object_unref (object: out); |
40 | g_object_unref (object: base); |
41 | } |
42 | |
43 | static void |
44 | test_grow (void) |
45 | { |
46 | GOutputStream *base; |
47 | GOutputStream *out; |
48 | GError *error; |
49 | const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz" ; |
50 | gint size; |
51 | gboolean grow; |
52 | |
53 | base = g_memory_output_stream_new (data: g_malloc0 (n_bytes: 30), size: 30, realloc_function: g_realloc, destroy_function: g_free); |
54 | out = g_buffered_output_stream_new_sized (base_stream: base, size: 16); |
55 | |
56 | g_buffered_output_stream_set_auto_grow (G_BUFFERED_OUTPUT_STREAM (out), TRUE); |
57 | |
58 | g_object_get (object: out, first_property_name: "buffer-size" , &size, "auto-grow" , &grow, NULL); |
59 | g_assert_cmpint (size, ==, 16); |
60 | g_assert (grow); |
61 | |
62 | g_assert (g_seekable_can_seek (G_SEEKABLE (out))); |
63 | |
64 | error = NULL; |
65 | g_assert_cmpint (g_output_stream_write (out, buffer, 10, NULL, &error), ==, 10); |
66 | g_assert_no_error (error); |
67 | |
68 | g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), ==, 16); |
69 | g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); |
70 | |
71 | g_assert_cmpint (g_output_stream_write (out, buffer + 10, 10, NULL, &error), ==, 10); |
72 | g_assert_no_error (error); |
73 | |
74 | g_assert_cmpint (g_buffered_output_stream_get_buffer_size (G_BUFFERED_OUTPUT_STREAM (out)), >=, 20); |
75 | g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (base)), ==, 0); |
76 | |
77 | g_assert (g_output_stream_flush (out, NULL, &error)); |
78 | g_assert_no_error (error); |
79 | |
80 | g_assert_cmpstr (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (base)), ==, "abcdefghijklmnopqrst" ); |
81 | |
82 | g_object_unref (object: out); |
83 | g_object_unref (object: base); |
84 | } |
85 | |
86 | static void |
87 | test_close (void) |
88 | { |
89 | GOutputStream *base; |
90 | GOutputStream *out; |
91 | GError *error; |
92 | |
93 | base = g_memory_output_stream_new (data: g_malloc0 (n_bytes: 30), size: 30, realloc_function: g_realloc, destroy_function: g_free); |
94 | out = g_buffered_output_stream_new (base_stream: base); |
95 | |
96 | g_assert (g_filter_output_stream_get_close_base_stream (G_FILTER_OUTPUT_STREAM (out))); |
97 | |
98 | error = NULL; |
99 | g_assert (g_output_stream_close (out, NULL, &error)); |
100 | g_assert_no_error (error); |
101 | g_assert (g_output_stream_is_closed (base)); |
102 | |
103 | g_object_unref (object: out); |
104 | g_object_unref (object: base); |
105 | |
106 | base = g_memory_output_stream_new (data: g_malloc0 (n_bytes: 30), size: 30, realloc_function: g_realloc, destroy_function: g_free); |
107 | out = g_buffered_output_stream_new (base_stream: base); |
108 | |
109 | g_filter_output_stream_set_close_base_stream (G_FILTER_OUTPUT_STREAM (out), FALSE); |
110 | |
111 | error = NULL; |
112 | g_assert (g_output_stream_close (out, NULL, &error)); |
113 | g_assert_no_error (error); |
114 | g_assert (!g_output_stream_is_closed (base)); |
115 | |
116 | g_object_unref (object: out); |
117 | g_object_unref (object: base); |
118 | } |
119 | |
120 | static void |
121 | test_seek (void) |
122 | { |
123 | GMemoryOutputStream *base; |
124 | GOutputStream *out; |
125 | GSeekable *seekable; |
126 | GError *error; |
127 | gsize bytes_written; |
128 | gboolean ret; |
129 | const gchar buffer[] = "abcdefghijklmnopqrstuvwxyz" ; |
130 | |
131 | base = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (g_malloc0 (30), 30, NULL, g_free)); |
132 | out = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base), size: 8); |
133 | seekable = G_SEEKABLE (out); |
134 | error = NULL; |
135 | |
136 | /* Write data */ |
137 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 0); |
138 | ret = g_output_stream_write_all (stream: out, buffer, count: 4, bytes_written: &bytes_written, NULL, error: &error); |
139 | g_assert_no_error (error); |
140 | g_assert_cmpint (bytes_written, ==, 4); |
141 | g_assert (ret); |
142 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4); |
143 | g_assert_cmpint (g_memory_output_stream_get_data_size (base), ==, 0); |
144 | |
145 | /* Forward relative seek */ |
146 | ret = g_seekable_seek (seekable, offset: 2, type: G_SEEK_CUR, NULL, error: &error); |
147 | g_assert_no_error (error); |
148 | g_assert (ret); |
149 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6); |
150 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); |
151 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); |
152 | g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); |
153 | g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); |
154 | ret = g_output_stream_write_all (stream: out, buffer, count: 2, bytes_written: &bytes_written, NULL, error: &error); |
155 | g_assert_no_error (error); |
156 | g_assert (ret); |
157 | g_assert_cmpint (bytes_written, ==, 2); |
158 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8); |
159 | |
160 | /* Backward relative seek */ |
161 | ret = g_seekable_seek (seekable, offset: -4, type: G_SEEK_CUR, NULL, error: &error); |
162 | g_assert_no_error (error); |
163 | g_assert (ret); |
164 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4); |
165 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); |
166 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); |
167 | g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); |
168 | g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); |
169 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); |
170 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); |
171 | ret = g_output_stream_write_all (stream: out, buffer, count: 2, bytes_written: &bytes_written, NULL, error: &error); |
172 | g_assert_no_error (error); |
173 | g_assert (ret); |
174 | g_assert_cmpint (bytes_written, ==, 2); |
175 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6); |
176 | |
177 | /* From start */ |
178 | ret = g_seekable_seek (seekable, offset: 2, type: G_SEEK_SET, NULL, error: &error); |
179 | g_assert_no_error (error); |
180 | g_assert (ret); |
181 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 2); |
182 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); |
183 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); |
184 | g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); |
185 | g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); |
186 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]); |
187 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]); |
188 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); |
189 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); |
190 | ret = g_output_stream_write_all (stream: out, buffer, count: 2, bytes_written: &bytes_written, NULL, error: &error); |
191 | g_assert_no_error (error); |
192 | g_assert (ret); |
193 | g_assert_cmpint (bytes_written, ==, 2); |
194 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 4); |
195 | |
196 | /* From end */ |
197 | ret = g_seekable_seek (seekable, offset: 6 - 30, type: G_SEEK_END, NULL, error: &error); |
198 | g_assert_no_error (error); |
199 | g_assert (ret); |
200 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 6); |
201 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); |
202 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); |
203 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); |
204 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); |
205 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]); |
206 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]); |
207 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); |
208 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); |
209 | ret = g_output_stream_write_all (stream: out, buffer: buffer + 2, count: 2, bytes_written: &bytes_written, NULL, error: &error); |
210 | g_assert_no_error (error); |
211 | g_assert (ret); |
212 | g_assert_cmpint (bytes_written, ==, 2); |
213 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8); |
214 | |
215 | /* Check flush */ |
216 | ret = g_output_stream_flush (stream: out, NULL, error: &error); |
217 | g_assert_no_error (error); |
218 | g_assert (ret); |
219 | g_assert_cmpint (g_seekable_tell (G_SEEKABLE (out)), ==, 8); |
220 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[0]); |
221 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[1]); |
222 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[2]); |
223 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[3]); |
224 | g_assert_cmpint ('a', ==, ((gchar *)g_memory_output_stream_get_data (base))[4]); |
225 | g_assert_cmpint ('b', ==, ((gchar *)g_memory_output_stream_get_data (base))[5]); |
226 | g_assert_cmpint ('c', ==, ((gchar *)g_memory_output_stream_get_data (base))[6]); |
227 | g_assert_cmpint ('d', ==, ((gchar *)g_memory_output_stream_get_data (base))[7]); |
228 | |
229 | g_object_unref (object: out); |
230 | g_object_unref (object: base); |
231 | } |
232 | |
233 | static void |
234 | test_truncate(void) |
235 | { |
236 | GMemoryOutputStream *base_stream; |
237 | GOutputStream *stream; |
238 | GSeekable *seekable; |
239 | GError *error; |
240 | gsize bytes_written; |
241 | guchar *stream_data; |
242 | gsize len; |
243 | gboolean res; |
244 | |
245 | len = 8; |
246 | |
247 | /* Create objects */ |
248 | stream_data = g_malloc0 (n_bytes: len); |
249 | base_stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new (stream_data, len, g_realloc, g_free)); |
250 | stream = g_buffered_output_stream_new_sized (G_OUTPUT_STREAM (base_stream), size: 8); |
251 | seekable = G_SEEKABLE (stream); |
252 | |
253 | g_assert (g_seekable_can_truncate (seekable)); |
254 | |
255 | /* Write */ |
256 | g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len); |
257 | g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 0); |
258 | |
259 | error = NULL; |
260 | res = g_output_stream_write_all (stream, buffer: "ab" , count: 2, bytes_written: &bytes_written, NULL, error: &error); |
261 | g_assert_no_error (error); |
262 | g_assert (res); |
263 | res = g_output_stream_write_all (stream, buffer: "cd" , count: 2, bytes_written: &bytes_written, NULL, error: &error); |
264 | g_assert_no_error (error); |
265 | g_assert (res); |
266 | |
267 | res = g_output_stream_flush (stream, NULL, error: &error); |
268 | g_assert_no_error (error); |
269 | g_assert (res); |
270 | |
271 | g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, len); |
272 | g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); |
273 | stream_data = g_memory_output_stream_get_data (ostream: base_stream); |
274 | g_assert_cmpint (stream_data[0], ==, 'a'); |
275 | g_assert_cmpint (stream_data[1], ==, 'b'); |
276 | g_assert_cmpint (stream_data[2], ==, 'c'); |
277 | g_assert_cmpint (stream_data[3], ==, 'd'); |
278 | |
279 | /* Truncate at position */ |
280 | res = g_seekable_truncate (seekable, offset: 4, NULL, error: &error); |
281 | g_assert_no_error (error); |
282 | g_assert (res); |
283 | g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 4); |
284 | g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 4); |
285 | stream_data = g_memory_output_stream_get_data (ostream: base_stream); |
286 | g_assert_cmpint (stream_data[0], ==, 'a'); |
287 | g_assert_cmpint (stream_data[1], ==, 'b'); |
288 | g_assert_cmpint (stream_data[2], ==, 'c'); |
289 | g_assert_cmpint (stream_data[3], ==, 'd'); |
290 | |
291 | /* Truncate beyond position */ |
292 | res = g_seekable_truncate (seekable, offset: 6, NULL, error: &error); |
293 | g_assert_no_error (error); |
294 | g_assert (res); |
295 | g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 6); |
296 | g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 6); |
297 | stream_data = g_memory_output_stream_get_data (ostream: base_stream); |
298 | g_assert_cmpint (stream_data[0], ==, 'a'); |
299 | g_assert_cmpint (stream_data[1], ==, 'b'); |
300 | g_assert_cmpint (stream_data[2], ==, 'c'); |
301 | g_assert_cmpint (stream_data[3], ==, 'd'); |
302 | |
303 | /* Truncate before position */ |
304 | res = g_seekable_truncate (seekable, offset: 2, NULL, error: &error); |
305 | g_assert_no_error (error); |
306 | g_assert (res); |
307 | g_assert_cmpint (g_memory_output_stream_get_size (base_stream), ==, 2); |
308 | g_assert_cmpint (g_memory_output_stream_get_data_size (base_stream), ==, 2); |
309 | stream_data = g_memory_output_stream_get_data (ostream: base_stream); |
310 | g_assert_cmpint (stream_data[0], ==, 'a'); |
311 | g_assert_cmpint (stream_data[1], ==, 'b'); |
312 | |
313 | g_object_unref (object: stream); |
314 | g_object_unref (object: base_stream); |
315 | } |
316 | |
317 | int |
318 | main (int argc, char *argv[]) |
319 | { |
320 | g_test_init (argc: &argc, argv: &argv, NULL); |
321 | |
322 | g_test_add_func (testpath: "/buffered-output-stream/write" , test_func: test_write); |
323 | g_test_add_func (testpath: "/buffered-output-stream/grow" , test_func: test_grow); |
324 | g_test_add_func (testpath: "/buffered-output-stream/seek" , test_func: test_seek); |
325 | g_test_add_func (testpath: "/buffered-output-stream/truncate" , test_func: test_truncate); |
326 | g_test_add_func (testpath: "/filter-output-stream/close" , test_func: test_close); |
327 | |
328 | return g_test_run (); |
329 | } |
330 | |