[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / gio / tests / memory-output-stream.c
1 /* GLib testing framework examples and tests
2  * Copyright (C) 2008 Red Hat, Inc.
3  * Author: Matthias Clasen
4  *
5  * This work is provided "as is"; redistribution and modification
6  * in whole or in part, in any medium, physical or electronic is
7  * permitted without restriction.
8  *
9  * This work is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  *
13  * In no event shall the authors or contributors be liable for any
14  * direct, indirect, incidental, special, exemplary, or consequential
15  * damages (including, but not limited to, procurement of substitute
16  * goods or services; loss of use, data, or profits; or business
17  * interruption) however caused and on any theory of liability, whether
18  * in contract, strict liability, or tort (including negligence or
19  * otherwise) arising in any way out of the use of this software, even
20  * if advised of the possibility of such damage.
21  */
22 #include <glib/glib.h>
23 #include <gio/gio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 static void
28 test_truncate (void)
29 {
30   GOutputStream *mo;
31   GDataOutputStream *o;
32   int i;
33   GError *error = NULL;
34   guint8 *data;
35
36   g_test_bug ("540423");
37
38   mo = g_memory_output_stream_new_resizable ();
39   g_assert (g_seekable_can_truncate (G_SEEKABLE (mo)));
40   o = g_data_output_stream_new (mo);
41   for (i = 0; i < 1000; i++)
42     {
43       g_data_output_stream_put_byte (o, 1, NULL, &error);
44       g_assert_no_error (error);
45     }
46   g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 1000);
47   g_seekable_truncate (G_SEEKABLE (mo), 0, NULL, &error);
48   g_assert_cmpuint (g_seekable_tell (G_SEEKABLE (mo)), ==, 1000);
49   
50   g_assert_no_error (error);
51   g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 0);
52   for (i = 0; i < 2000; i++)
53     {
54       g_data_output_stream_put_byte (o, 2, NULL, &error);
55       g_assert_no_error (error);
56     }
57   g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 3000);
58
59   data = (guint8 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
60
61   /* The 1's written initially were lost when we truncated to 0
62    * and then started writing at position 1000.
63    */
64   for (i = 0; i < 1000; i++)
65     g_assert_cmpuint (data[i], ==, 0);
66   for (i = 1000; i < 3000; i++)
67     g_assert_cmpuint (data[i], ==, 2);
68
69   g_test_bug ("720080");
70
71   g_seekable_truncate (G_SEEKABLE (mo), 8192, NULL, &error);
72   g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 8192);
73
74   data = (guint8 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
75   for (i = 3000; i < 8192; i++)
76     g_assert_cmpuint (data[i], ==, 0);
77
78   g_object_unref (o);
79   g_object_unref (mo);
80 }
81
82 static void
83 test_seek_fixed (void)
84 {
85   GOutputStream *mo;
86   GError *error;
87
88   mo = g_memory_output_stream_new (g_new (gchar, 100), 100, NULL, g_free);
89
90   g_assert (G_IS_SEEKABLE (mo));
91   g_assert (g_seekable_can_seek (G_SEEKABLE (mo)));
92   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
93
94   error = NULL;
95   g_assert (!g_seekable_seek (G_SEEKABLE (mo), 222, G_SEEK_CUR, NULL, &error));
96   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
97   g_clear_error (&error);
98   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
99
100   g_assert (g_seekable_seek (G_SEEKABLE (mo), 26, G_SEEK_SET, NULL, &error));
101   g_assert_no_error (error);
102   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 26);
103
104   g_assert (g_seekable_seek (G_SEEKABLE (mo), 20, G_SEEK_CUR, NULL, &error));
105   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
106   g_assert_no_error (error);
107
108   g_assert (!g_seekable_seek (G_SEEKABLE (mo), 200, G_SEEK_CUR, NULL, &error));
109   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
110   g_clear_error (&error);
111   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
112
113   g_assert (!g_seekable_seek (G_SEEKABLE (mo), 1, G_SEEK_END, NULL, &error));
114   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
115   g_clear_error (&error);
116   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
117
118   g_assert (g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_END, NULL, &error));
119   g_assert_no_error (error);
120   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 100);
121
122   g_assert (g_seekable_seek (G_SEEKABLE (mo), -1, G_SEEK_END, NULL, &error));
123   g_assert_no_error (error);
124   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 99);
125
126   g_object_unref (mo);
127 }
128
129 static void
130 test_seek_resizable_stream (GOutputStream *mo)
131 {
132   GError *error;
133
134   g_assert (G_IS_SEEKABLE (mo));
135   g_assert (g_seekable_can_seek (G_SEEKABLE (mo)));
136   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
137
138   error = NULL;
139   g_assert (g_seekable_seek (G_SEEKABLE (mo), 222, G_SEEK_CUR, NULL, &error));
140   g_assert_no_error (error);
141   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 222);
142
143   g_assert (g_seekable_seek (G_SEEKABLE (mo), 26, G_SEEK_SET, NULL, &error));
144   g_assert_no_error (error);
145   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 26);
146
147   g_assert (g_seekable_seek (G_SEEKABLE (mo), 20, G_SEEK_CUR, NULL, &error));
148   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
149   g_assert_no_error (error);
150
151   g_assert (g_seekable_seek (G_SEEKABLE (mo), 200, G_SEEK_CUR, NULL, &error));
152   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 246);
153   g_assert_no_error (error);
154
155   g_assert (g_seekable_seek (G_SEEKABLE (mo), 1, G_SEEK_END, NULL, &error));
156   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 1);
157   g_assert_no_error (error);
158
159   g_assert (g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_END, NULL, &error));
160   g_assert_no_error (error);
161   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
162
163   /* The 'end' is still zero, so this should fail */
164   g_assert (!g_seekable_seek (G_SEEKABLE (mo), -1, G_SEEK_END, NULL, &error));
165   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
166   g_clear_error (&error);
167   g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
168 }
169
170 static void
171 test_seek_resizable (void)
172 {
173   GOutputStream *mo;
174   gint i;
175
176   /* For resizable streams, the initially allocated size is purely an
177    * implementation detail.  We should not be able to tell the
178    * difference based on the seek API, so make a bunch of streams with
179    * different sizes and subject them to the same test.
180    */
181   for (i = 0; i < 1024; i++)
182     {
183       mo = g_memory_output_stream_new (g_malloc (i), i, g_realloc, g_free);
184
185       test_seek_resizable_stream (mo);
186
187       g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 0);
188       /* No writes = no resizes */
189       g_assert_cmpint (g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, i);
190
191       g_object_unref (mo);
192     }
193 }
194
195 static void
196 test_data_size (void)
197 {
198   GOutputStream *mo;
199   GDataOutputStream *o;
200   int pos;
201
202   g_test_bug ("540459");
203
204   mo = g_memory_output_stream_new_resizable ();
205   o = g_data_output_stream_new (mo);
206   g_data_output_stream_put_byte (o, 1, NULL, NULL);
207   pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
208   g_assert_cmpint (pos, ==, 1);
209
210   g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_CUR, NULL, NULL);
211   pos = g_seekable_tell (G_SEEKABLE (mo));
212   g_assert_cmpint (pos, ==, 1);
213
214   g_test_bug ("540461");
215   
216   g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_SET, NULL, NULL);
217   pos = g_seekable_tell (G_SEEKABLE (mo));
218   g_assert_cmpint (pos, ==, 0);
219   
220   pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
221   g_assert_cmpint (pos, ==, 1);
222
223   g_assert_cmpint (g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 16);
224
225   g_object_unref (o);
226   g_object_unref (mo);
227 }
228
229 static void
230 test_properties (void)
231 {
232   GOutputStream *mo;
233   GDataOutputStream *o;
234   int i;
235   GError *error = NULL;
236   gsize data_size_fun;
237   gsize data_size_prop = 0;
238   gpointer data_fun;
239   gpointer data_prop;
240   gpointer func;
241
242   g_test_bug ("605733");
243
244   mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
245                                       "realloc-function", g_realloc,
246                                       "destroy-function", g_free,
247                                       NULL);
248   o = g_data_output_stream_new (mo);
249
250   for (i = 0; i < 1000; i++)
251     {
252       g_data_output_stream_put_byte (o, 1, NULL, &error);
253       g_assert_no_error (error);
254     }
255
256   data_size_fun = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
257   g_object_get (mo, "data-size", &data_size_prop, NULL);
258   g_assert_cmpint (data_size_fun, ==, data_size_prop);
259
260   data_fun = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
261   g_object_get (mo, "data", &data_prop, NULL);
262   g_assert_cmphex (GPOINTER_TO_SIZE (data_fun), ==, GPOINTER_TO_SIZE (data_prop));
263
264   g_object_get (mo, "realloc-function", &func, NULL);
265   g_assert (func == g_realloc);
266   g_object_get (mo, "destroy-function", &func, NULL);
267   g_assert (func == g_free);
268
269   data_size_fun = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo));
270   g_object_get (mo, "size", &data_size_prop, NULL);
271   g_assert_cmpint (data_size_fun, ==, data_size_prop);
272
273   g_object_unref (o);
274   g_object_unref (mo);
275 }
276
277 static void
278 test_write_bytes (void)
279 {
280   GOutputStream *mo;
281   GBytes *bytes, *bytes2;
282   GError *error = NULL;
283
284   mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
285                                       "realloc-function", g_realloc,
286                                       "destroy-function", g_free,
287                                       NULL);
288   bytes = g_bytes_new_static ("hello world!", strlen ("hello world!") + 1);
289   g_output_stream_write_bytes (mo, bytes, NULL, &error);
290   g_assert_no_error (error);
291
292   g_output_stream_close (mo, NULL, &error);
293   g_assert_no_error (error);
294
295   bytes2 = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mo));
296   g_object_unref (mo);
297   g_assert (g_bytes_equal (bytes, bytes2));
298
299   g_bytes_unref (bytes);
300   g_bytes_unref (bytes2);
301 }
302
303 static void
304 test_steal_as_bytes (void)
305 {
306   GOutputStream *mo;
307   GDataOutputStream *o;
308   GError *error = NULL;
309   GBytes *bytes;
310   gsize size;
311
312   mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
313                                       "realloc-function", g_realloc,
314                                       "destroy-function", g_free,
315                                       NULL);
316   o = g_data_output_stream_new (mo);
317
318   g_data_output_stream_put_string (o, "hello ", NULL, &error);
319   g_assert_no_error (error);
320
321   g_data_output_stream_put_string (o, "world!", NULL, &error);
322   g_assert_no_error (error);
323
324   g_data_output_stream_put_byte (o, '\0', NULL, &error);
325   g_assert_no_error (error);
326
327   g_output_stream_close ((GOutputStream*) o, NULL, &error);
328   g_assert_no_error (error);
329
330   bytes = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)mo);
331   g_object_unref (mo);
332
333   g_assert_cmpint (g_bytes_get_size (bytes), ==, strlen ("hello world!") + 1);
334   g_assert_cmpstr (g_bytes_get_data (bytes, &size), ==, "hello world!");
335
336   g_bytes_unref (bytes);
337   g_object_unref (o);
338 }
339
340 int
341 main (int   argc,
342       char *argv[])
343 {
344   g_test_init (&argc, &argv, NULL);
345   g_test_bug_base ("http://bugzilla.gnome.org/");
346
347   g_test_add_func ("/memory-output-stream/truncate", test_truncate);
348   g_test_add_func ("/memory-output-stream/seek/fixed", test_seek_fixed);
349   g_test_add_func ("/memory-output-stream/seek/resizable", test_seek_resizable);
350   g_test_add_func ("/memory-output-stream/get-data-size", test_data_size);
351   g_test_add_func ("/memory-output-stream/properties", test_properties);
352   g_test_add_func ("/memory-output-stream/write-bytes", test_write_bytes);
353   g_test_add_func ("/memory-output-stream/steal_as_bytes", test_steal_as_bytes);
354
355   return g_test_run();
356 }