1 /* GLib testing framework examples and tests 2 * Copyright (C) 2008 Red Hat, Inc. 3 * Authors: Tomas Bzatek <tbzatek (at) 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_LINES_BUFF 0xFFFFFF 30 #define MAX_BYTES_BINARY 0x100 31 32 static void 33 test_read_lines (GDataStreamNewlineType newline_type) 34 { 35 GOutputStream *stream; 36 GOutputStream *base_stream; 37 GError *error = NULL; 38 gpointer data; 39 char *lines; 40 int size; 41 int i; 42 43 #define TEST_STRING "some_text" 44 45 const char* endl[4] = {"\n", "\r", "\r\n", "\n"}; 46 47 48 data = g_malloc0 (MAX_LINES_BUFF); 49 lines = g_malloc0 ((strlen (TEST_STRING) + strlen (endl[newline_type])) * MAX_LINES + 1); 50 51 /* initialize objects */ 52 base_stream = g_memory_output_stream_new (data, MAX_LINES_BUFF, NULL, NULL); 53 stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream)); 54 55 56 /* fill data */ 57 for (i = 0; i < MAX_LINES; i++) 58 { 59 gboolean res; 60 char *s = g_strconcat (TEST_STRING, endl[newline_type], NULL); 61 res = g_data_output_stream_put_string (G_DATA_OUTPUT_STREAM (stream), s, NULL, &error); 62 g_stpcpy ((char*)(lines + i*strlen(s)), s); 63 g_assert_no_error (error); 64 g_assert (res == TRUE); 65 } 66 67 /* Byte order testing */ 68 g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); 69 g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN); 70 g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); 71 g_assert_cmpint (g_data_output_stream_get_byte_order (G_DATA_OUTPUT_STREAM (stream)), ==, G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN); 72 73 /* compare data */ 74 size = strlen (data); 75 g_assert_cmpint (size, <, MAX_LINES_BUFF); 76 g_assert_cmpstr ((char*)data, ==, lines); 77 78 g_object_unref (base_stream); 79 g_object_unref (stream); 80 g_free (data); 81 g_free (lines); 82 } 83 84 static void 85 test_read_lines_LF (void) 86 { 87 test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_LF); 88 } 89 90 static void 91 test_read_lines_CR (void) 92 { 93 test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR); 94 } 95 96 static void 97 test_read_lines_CR_LF (void) 98 { 99 test_read_lines (G_DATA_STREAM_NEWLINE_TYPE_CR_LF); 100 } 101 102 enum TestDataType { 103 TEST_DATA_BYTE = 0, 104 TEST_DATA_INT16, 105 TEST_DATA_UINT16, 106 TEST_DATA_INT32, 107 TEST_DATA_UINT32, 108 TEST_DATA_INT64, 109 TEST_DATA_UINT64 110 }; 111 112 #define TEST_DATA_RETYPE(a, v) \ 113 (a == TEST_DATA_BYTE ? (guchar)v : \ 114 (a == TEST_DATA_INT16 ? (gint16)v : \ 115 (a == TEST_DATA_UINT16 ? (guint16)v : \ 116 (a == TEST_DATA_INT32 ? (gint32)v : \ 117 (a == TEST_DATA_UINT32 ? (guint32)v : \ 118 (a == TEST_DATA_INT64 ? (gint64)v : \ 119 (guint64)v )))))) 120 121 #define TEST_DATA_RETYPE_BUFF(a, v) \ 122 (a == TEST_DATA_BYTE ? *(guchar*)v : \ 123 (a == TEST_DATA_INT16 ? *(gint16*)v : \ 124 (a == TEST_DATA_UINT16 ? *(guint16*)v : \ 125 (a == TEST_DATA_INT32 ? *(gint32*)v : \ 126 (a == TEST_DATA_UINT32 ? *(guint32*)v : \ 127 (a == TEST_DATA_INT64 ? *(gint64*)v : \ 128 *(guint64*)v )))))) 129 130 131 132 133 static void 134 test_data_array (gpointer buffer, int len, 135 enum TestDataType data_type, GDataStreamByteOrder byte_order) 136 { 137 GOutputStream *stream; 138 GOutputStream *base_stream; 139 gpointer stream_data; 140 141 GError *error = NULL; 142 int pos; 143 int data_size = 1; 144 GDataStreamByteOrder native; 145 gboolean swap; 146 gboolean res; 147 guint64 data; 148 149 /* create objects */ 150 stream_data = g_malloc0 (len); 151 base_stream = g_memory_output_stream_new (stream_data, len, NULL, NULL); 152 stream = G_OUTPUT_STREAM (g_data_output_stream_new (base_stream)); 153 g_data_output_stream_set_byte_order (G_DATA_OUTPUT_STREAM (stream), byte_order); 154 155 156 /* Set correct data size */ 157 switch (data_type) 158 { 159 case TEST_DATA_BYTE: 160 data_size = 1; 161 break; 162 case TEST_DATA_INT16: 163 case TEST_DATA_UINT16: 164 data_size = 2; 165 break; 166 case TEST_DATA_INT32: 167 case TEST_DATA_UINT32: 168 data_size = 4; 169 break; 170 case TEST_DATA_INT64: 171 case TEST_DATA_UINT64: 172 data_size = 8; 173 break; 174 } 175 176 /* Set flag to swap bytes if needed */ 177 native = (G_BYTE_ORDER == G_BIG_ENDIAN) ? G_DATA_STREAM_BYTE_ORDER_BIG_ENDIAN : G_DATA_STREAM_BYTE_ORDER_LITTLE_ENDIAN; 178 swap = (byte_order != G_DATA_STREAM_BYTE_ORDER_HOST_ENDIAN) && (byte_order != native); 179 180 /* Write data to the file */ 181 pos = 0; 182 while (pos < len) 183 { 184 switch (data_type) 185 { 186 case TEST_DATA_BYTE: 187 res = g_data_output_stream_put_byte (G_DATA_OUTPUT_STREAM (stream), TEST_DATA_RETYPE_BUFF (data_type, ((guchar*)buffer + pos)), NULL, &error); 188 break; 189 case TEST_DATA_INT16: 190 res = g_data_output_stream_put_int16 (G_DATA_OUTPUT_STREAM (stream), TEST_DATA_RETYPE_BUFF (data_type, ((guchar*)buffer + pos)), NULL, &error); 191 break; 192 case TEST_DATA_UINT16: 193 res = g_data_output_stream_put_uint16 (G_DATA_OUTPUT_STREAM (stream), TEST_DATA_RETYPE_BUFF (data_type, ((guchar*)buffer + pos)), NULL, &error); 194 break; 195 case TEST_DATA_INT32: 196 res = g_data_output_stream_put_int32 (G_DATA_OUTPUT_STREAM (stream), TEST_DATA_RETYPE_BUFF (data_type, ((guchar*)buffer + pos)), NULL, &error); 197 break; 198 case TEST_DATA_UINT32: 199 res = g_data_output_stream_put_uint32 (G_DATA_OUTPUT_STREAM (stream), TEST_DATA_RETYPE_BUFF (data_type, ((guchar*)buffer + pos)), NULL, &error); 200 break; 201 case TEST_DATA_INT64: 202 res = g_data_output_stream_put_int64 (G_DATA_OUTPUT_STREAM (stream), TEST_DATA_RETYPE_BUFF (data_type, ((guchar*)buffer + pos)), NULL, &error); 203 break; 204 case TEST_DATA_UINT64: 205 res = g_data_output_stream_put_uint64 (G_DATA_OUTPUT_STREAM (stream), TEST_DATA_RETYPE_BUFF (data_type, ((guchar*)buffer + pos)), NULL, &error); 206 break; 207 } 208 g_assert_no_error (error); 209 g_assert_cmpint (res, ==, TRUE); 210 pos += data_size; 211 } 212 213 214 /* Compare data back */ 215 pos = 0; 216 data = 0; 217 while (pos < len) 218 { 219 data = TEST_DATA_RETYPE_BUFF(data_type, ((guchar*)stream_data + pos)); 220 if (swap) 221 { 222 switch (data_type) 223 { 224 case TEST_DATA_BYTE: 225 break; 226 case TEST_DATA_UINT16: 227 case TEST_DATA_INT16: 228 data = TEST_DATA_RETYPE(data_type, GUINT16_SWAP_LE_BE(TEST_DATA_RETYPE(data_type, data))); 229 break; 230 case TEST_DATA_UINT32: 231 case TEST_DATA_INT32: 232 data = TEST_DATA_RETYPE(data_type, GUINT32_SWAP_LE_BE(TEST_DATA_RETYPE(data_type, data))); 233 break; 234 case TEST_DATA_UINT64: 235 case TEST_DATA_INT64: 236 data = TEST_DATA_RETYPE(data_type, GUINT64_SWAP_LE_BE(TEST_DATA_RETYPE(data_type, data))); 237 break; 238 } 239 } 240 g_assert_cmpint (data, ==, TEST_DATA_RETYPE_BUFF(data_type, ((guchar*)buffer + pos))); 241 break; 242 243 pos += data_size; 244 } 245 246 g_object_unref (base_stream); 247 g_object_unref (stream); 248 g_free (stream_data); 249 } 250 251 static void 252 test_read_int (void) 253 { 254 GRand *rand; 255 gpointer buffer; 256 int i; 257 258 rand = g_rand_new (); 259 buffer = g_malloc0(MAX_BYTES_BINARY); 260 261 /* Fill in some random data */ 262 for (i = 0; i < MAX_BYTES_BINARY; i++) 263 { 264 guchar x = 0; 265 while (! x) x = (guchar)g_rand_int (rand); 266 *(guchar*)((guchar*)buffer + sizeof (guchar) * i) = x; 267 } 268 269 for (i = 0; i < 3; i++) 270 { 271 int j; 272 for (j = 0; j <= TEST_DATA_UINT64; j++) 273 test_data_array (buffer, MAX_BYTES_BINARY, j, i); 274 } 275 276 g_rand_free (rand); 277 g_free (buffer); 278 } 279 280 int 281 main (int argc, 282 char *argv[]) 283 { 284 g_type_init (); 285 g_test_init (&argc, &argv, NULL); 286 287 g_test_add_func ("/data-input-stream/read-lines-LF", test_read_lines_LF); 288 g_test_add_func ("/data-input-stream/read-lines-CR", test_read_lines_CR); 289 g_test_add_func ("/data-input-stream/read-lines-CR-LF", test_read_lines_CR_LF); 290 g_test_add_func ("/data-input-stream/read-int", test_read_int); 291 292 return g_test_run(); 293 } 294