Plug a mem leak in data-input-stream test
[platform/upstream/glib.git] / gio / tests / data-input-stream.c
1 /* GLib testing framework examples and tests
2  * Copyright (C) 2008 Red Hat, Inc.
3  * Authors: Tomas Bzatek <tbzatek@redhat.com>
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
23 #include <glib/glib.h>
24 #include <gio/gio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28 #define MAX_LINES       0xFFF
29 #define MAX_BYTES       0x10000 
30
31 static void
32 test_basic (void)
33 {
34   GInputStream *stream;
35   GInputStream *base_stream;
36   gint val;
37
38   base_stream = g_memory_input_stream_new ();
39   stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
40
41   g_object_get (stream, "byte-order", &val, NULL);
42   g_assert_cmpint (val, ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
43   g_object_set (stream, "byte-order", G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN, NULL);
44   g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
45
46   g_object_get (stream, "newline-type", &val, NULL);
47   g_assert_cmpint (val, ==, G_DATA_STREAM_NEWLINE_TYPE_LF);
48   g_object_set (stream, "newline-type", G_DATA_STREAM_NEWLINE_TYPE_CR_LF, NULL);
49   g_assert_cmpint (g_data_input_stream_get_newline_type (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
50
51   g_object_unref (stream);
52   g_object_unref (base_stream);
53 }
54
55 static void
56 test_seek_to_start (GInputStream *stream)
57 {
58   GError *error = NULL;
59   gboolean res = g_seekable_seek (G_SEEKABLE (stream), 0, G_SEEK_SET, NULL, &error);
60   g_assert_cmpint (res, ==, TRUE);
61   g_assert_no_error (error);
62 }
63
64 static void
65 test_read_lines (GDataStreamNewlineType newline_type)
66 {
67   GInputStream *stream;
68   GInputStream *base_stream;
69   GError *error = NULL;
70   char *data;
71   int line;
72   const char* lines[MAX_LINES];
73   const char* endl[4] = {"\n", "\r", "\r\n", "\n"};
74   
75   /*  prepare data */
76   int i;
77   for (i = 0; i < MAX_LINES; i++)
78     lines[i] = "some_text";
79         
80   base_stream = g_memory_input_stream_new ();
81   g_assert (base_stream != NULL);
82   stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
83   g_assert(stream != NULL);
84         
85   /*  Byte order testing */
86   g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
87   g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN);
88   g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
89   g_assert_cmpint (g_data_input_stream_get_byte_order (G_DATA_INPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN);
90   
91   /*  Line ends testing */
92   g_data_input_stream_set_newline_type (G_DATA_INPUT_STREAM (stream), newline_type);
93   g_assert_cmpint (g_data_input_stream_get_newline_type (G_DATA_INPUT_STREAM (stream)), ==, newline_type);
94         
95
96   /*  Add sample data */
97   for (i = 0; i < MAX_LINES; i++) 
98     g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream),
99                                     g_strconcat (lines[i], endl[newline_type], NULL), -1, NULL);
100
101   /*  Seek to the start */
102   test_seek_to_start (base_stream);
103         
104   /*  Test read line */
105   error = NULL;
106   data = (char*)1;
107   line = 0;
108   while (data)
109     {
110       gsize length = -1;
111       data = g_data_input_stream_read_line (G_DATA_INPUT_STREAM (stream), &length, NULL, &error);
112       if (data)
113         {
114           g_assert_cmpstr (data, ==, lines[line]);
115           g_assert_no_error (error);
116           line++;
117         }
118     }
119   g_assert_cmpint (line, ==, MAX_LINES);
120   
121   
122   g_object_unref (base_stream);
123   g_object_unref (stream);
124 }
125
126 static void
127 test_read_lines_LF (void)
128 {
129   test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF);
130 }
131
132 static void
133 test_read_lines_CR (void)
134 {
135   test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR);
136 }
137
138 static void
139 test_read_lines_CR_LF (void)
140 {
141   test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
142 }
143
144 static void
145 test_read_lines_any (void)
146 {
147   test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_ANY);
148 }
149
150 static void
151 test_read_until (void)
152 {
153   GInputStream *stream;
154   GInputStream *base_stream;
155   GError *error = NULL;
156   char *data;
157   int line;
158   int i;
159   
160 #define REPEATS                 10   /* number of rounds */
161 #define DATA_STRING             " part1 # part2 $ part3 % part4 ^"
162 #define DATA_PART_LEN           7    /* number of characters between separators */
163 #define DATA_SEP                "#$%^"
164   const int DATA_PARTS_NUM = strlen (DATA_SEP) * REPEATS;
165   
166   base_stream = g_memory_input_stream_new ();
167   stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
168   
169   for (i = 0; i < REPEATS; i++)
170     g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), DATA_STRING, -1, NULL);
171   
172   /*  Test stop characters */
173   error = NULL;
174   data = (char*)1;
175   line = 0;
176   while (data)
177     {
178       gsize length = -1;
179       data = g_data_input_stream_read_until (G_DATA_INPUT_STREAM (stream), DATA_SEP, &length, NULL, &error);
180       if (data)
181         {
182           g_assert_cmpint (strlen (data), ==, DATA_PART_LEN);
183           g_assert_no_error (error);
184           line++;
185         }
186     }
187   g_assert_no_error (error);
188   g_assert_cmpint (line, ==, DATA_PARTS_NUM);
189         
190         
191   g_object_unref (base_stream);
192   g_object_unref (stream);
193 }
194
195 enum TestDataType {
196   TEST_DATA_BYTE = 0,
197   TEST_DATA_INT16,
198   TEST_DATA_UINT16,
199   TEST_DATA_INT32,
200   TEST_DATA_UINT32,
201   TEST_DATA_INT64,
202   TEST_DATA_UINT64
203 };
204
205 #define TEST_DATA_RETYPE_BUFF(a, t, v)  \
206          (a == TEST_DATA_BYTE   ? (t) *(guchar*)v : \
207          (a == TEST_DATA_INT16  ? (t) *(gint16*)v :      \
208          (a == TEST_DATA_UINT16 ? (t) *(guint16*)v : \
209          (a == TEST_DATA_INT32  ? (t) *(gint32*)v :      \
210          (a == TEST_DATA_UINT32 ? (t) *(guint32*)v : \
211          (a == TEST_DATA_INT64  ? (t) *(gint64*)v :      \
212          (t) *(guint64*)v )))))) 
213
214
215 static void
216 test_data_array (GInputStream *stream, GInputStream *base_stream,
217                  gpointer buffer, int len,
218                  enum TestDataType data_type, GDataStreamByteOrder byte_order)
219 {
220   GError *error = NULL;
221   int pos = 0;
222   int data_size = 1;
223   gint64 data;
224   GDataStreamByteOrder native;
225   gboolean swap;
226   
227   /*  Seek to start */
228   test_seek_to_start (base_stream);
229
230   /*  Set correct data size */
231   switch (data_type)
232     {
233     case TEST_DATA_BYTE:
234       data_size = 1;
235       break;
236     case TEST_DATA_INT16:
237     case TEST_DATA_UINT16:
238       data_size = 2;
239       break;
240     case TEST_DATA_INT32:
241     case TEST_DATA_UINT32:
242       data_size = 4;
243       break;
244     case TEST_DATA_INT64:
245     case TEST_DATA_UINT64:
246       data_size = 8;
247       break; 
248     default:
249       g_assert_not_reached ();
250       break;
251     }
252
253   /*  Set flag to swap bytes if needed */
254   native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN;
255   swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native);
256
257   data = 1;
258   while (data != 0)
259     {
260       switch (data_type)
261         {
262         case TEST_DATA_BYTE:
263           data = g_data_input_stream_read_byte (G_DATA_INPUT_STREAM (stream), NULL, &error);
264           break;
265         case TEST_DATA_INT16:
266           data = g_data_input_stream_read_int16 (G_DATA_INPUT_STREAM (stream), NULL, &error);
267           if (swap)
268             data = (gint16)GUINT16_SWAP_LE_BE((gint16)data);
269           break;
270         case TEST_DATA_UINT16:
271           data = g_data_input_stream_read_uint16 (G_DATA_INPUT_STREAM (stream), NULL, &error);
272           if (swap)
273             data = (guint16)GUINT16_SWAP_LE_BE((guint16)data);
274           break;
275         case TEST_DATA_INT32:
276           data = g_data_input_stream_read_int32 (G_DATA_INPUT_STREAM (stream), NULL, &error);
277           if (swap)
278             data = (gint32)GUINT32_SWAP_LE_BE((gint32)data);
279           break;
280         case TEST_DATA_UINT32:
281           data = g_data_input_stream_read_uint32 (G_DATA_INPUT_STREAM (stream), NULL, &error);
282           if (swap)
283             data = (guint32)GUINT32_SWAP_LE_BE((guint32)data);
284           break;
285         case TEST_DATA_INT64:
286           data = g_data_input_stream_read_int64 (G_DATA_INPUT_STREAM (stream), NULL, &error);
287           if (swap)
288             data = (gint64)GUINT64_SWAP_LE_BE((gint64)data);
289           break;
290         case TEST_DATA_UINT64:
291           data = g_data_input_stream_read_uint64 (G_DATA_INPUT_STREAM (stream), NULL, &error);
292           if (swap)
293             data = (guint64)GUINT64_SWAP_LE_BE((guint64)data);
294           break;
295         default:
296           g_assert_not_reached ();
297           break;
298         }
299       if (!error)
300         g_assert_cmpint (data, ==, TEST_DATA_RETYPE_BUFF(data_type, gint64, ((guchar*)buffer + pos)));
301       
302       pos += data_size;
303     }
304   if (pos < len + 1)
305     g_assert_no_error (error);
306   if (error)
307     g_error_free (error);
308   g_assert_cmpint (pos - data_size, ==, len);
309 }
310
311 static void
312 test_read_int (void)
313 {
314   GInputStream *stream;
315   GInputStream *base_stream;
316   GRand *randomizer;
317   int i;
318   gpointer buffer;
319   
320   randomizer = g_rand_new ();
321   buffer = g_malloc0 (MAX_BYTES);
322   
323   /*  Fill in some random data */
324   for (i = 0; i < MAX_BYTES; i++)
325     {
326       guchar x = 0;
327       while (! x)
328         x = (guchar)g_rand_int (randomizer);
329       *(guchar*)((guchar*)buffer + sizeof(guchar) * i) = x; 
330     }
331
332   base_stream = g_memory_input_stream_new ();
333   stream = G_INPUT_STREAM (g_data_input_stream_new (base_stream));
334   g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (base_stream), buffer, MAX_BYTES, NULL);
335   
336   
337   for (i = 0; i < 3; i++)
338     {
339       int j;
340       g_data_input_stream_set_byte_order (G_DATA_INPUT_STREAM (stream), i);
341       
342       for (j = 0; j <= TEST_DATA_UINT64; j++)
343         test_data_array (stream, base_stream, buffer, MAX_BYTES, j, i);
344     }
345
346   g_object_unref (base_stream);
347   g_object_unref (stream);
348   g_rand_free (randomizer);
349   g_free (buffer);
350 }
351
352
353 int
354 main (int   argc,
355       char *argv[])
356 {
357   g_type_init ();
358   g_test_init (&argc, &argv, NULL);
359
360   g_test_add_func ("/data-input-stream/basic", test_basic);
361   g_test_add_func ("/data-input-stream/read-lines-LF", test_read_lines_LF);
362   g_test_add_func ("/data-input-stream/read-lines-CR", test_read_lines_CR);
363   g_test_add_func ("/data-input-stream/read-lines-CR-LF", test_read_lines_CR_LF);
364   g_test_add_func ("/data-input-stream/read-lines-any", test_read_lines_any);
365   g_test_add_func ("/data-input-stream/read-until", test_read_until);
366   g_test_add_func ("/data-input-stream/read-int", test_read_int);
367
368   return g_test_run();
369 }