1 /* GLib testing framework examples and tests
2 * Copyright (C) 2009 Red Hat, Inc.
3 * Authors: Alexander Larsson <alexl@redhat.com>
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.
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.
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.
23 #include <glib/glib.h>
28 #define G_TYPE_EXPANDER_CONVERTER (g_expander_converter_get_type ())
29 #define G_EXPANDER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_EXPANDER_CONVERTER, GExpanderConverter))
30 #define G_EXPANDER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_EXPANDER_CONVERTER, GExpanderConverterClass))
31 #define G_IS_EXPANDER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_EXPANDER_CONVERTER))
32 #define G_IS_EXPANDER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_EXPANDER_CONVERTER))
33 #define G_EXPANDER_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_EXPANDER_CONVERTER, GExpanderConverterClass))
35 typedef struct _GExpanderConverter GExpanderConverter;
36 typedef struct _GExpanderConverterClass GExpanderConverterClass;
38 struct _GExpanderConverterClass
40 GObjectClass parent_class;
43 GType g_expander_converter_get_type (void) G_GNUC_CONST;
44 GConverter *g_expander_converter_new (void);
48 static void g_expander_converter_iface_init (GConverterIface *iface);
50 struct _GExpanderConverter
52 GObject parent_instance;
55 G_DEFINE_TYPE_WITH_CODE (GExpanderConverter, g_expander_converter, G_TYPE_OBJECT,
56 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
57 g_expander_converter_iface_init))
60 g_expander_converter_class_init (GExpanderConverterClass *klass)
65 g_expander_converter_init (GExpanderConverter *local)
70 g_expander_converter_new (void)
74 conv = g_object_new (G_TYPE_EXPANDER_CONVERTER, NULL);
80 g_expander_converter_reset (GConverter *converter)
84 static GConverterResult
85 g_expander_converter_convert (GConverter *converter,
90 GConverterFlags flags,
95 const guint8 *in, *in_end;
102 in_end = in + inbuf_size;
111 block_size = v * 1000;
113 if (outbuf_size < block_size)
116 return G_CONVERTER_CONVERTED;
118 g_set_error_literal (error, G_IO_ERROR,
121 return G_CONVERTER_ERROR;
126 *bytes_written += block_size;
127 outbuf_size -= block_size;
128 for (i = 0; i < block_size; i++)
132 if (in == in_end && (flags & G_CONVERTER_INPUT_AT_END))
133 return G_CONVERTER_FINISHED;
134 return G_CONVERTER_CONVERTED;
138 g_expander_converter_iface_init (GConverterIface *iface)
140 iface->convert = g_expander_converter_convert;
141 iface->reset = g_expander_converter_reset;
144 #define G_TYPE_COMPRESSOR_CONVERTER (g_compressor_converter_get_type ())
145 #define G_COMPRESSOR_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverter))
146 #define G_COMPRESSOR_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverterClass))
147 #define G_IS_COMPRESSOR_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_COMPRESSOR_CONVERTER))
148 #define G_IS_COMPRESSOR_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_COMPRESSOR_CONVERTER))
149 #define G_COMPRESSOR_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverterClass))
151 typedef struct _GCompressorConverter GCompressorConverter;
152 typedef struct _GCompressorConverterClass GCompressorConverterClass;
154 struct _GCompressorConverterClass
156 GObjectClass parent_class;
159 GType g_compressor_converter_get_type (void) G_GNUC_CONST;
160 GConverter *g_compressor_converter_new (void);
164 static void g_compressor_converter_iface_init (GConverterIface *iface);
166 struct _GCompressorConverter
168 GObject parent_instance;
171 G_DEFINE_TYPE_WITH_CODE (GCompressorConverter, g_compressor_converter, G_TYPE_OBJECT,
172 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
173 g_compressor_converter_iface_init))
176 g_compressor_converter_class_init (GCompressorConverterClass *klass)
181 g_compressor_converter_init (GCompressorConverter *local)
186 g_compressor_converter_new (void)
190 conv = g_object_new (G_TYPE_COMPRESSOR_CONVERTER, NULL);
196 g_compressor_converter_reset (GConverter *converter)
200 static GConverterResult
201 g_compressor_converter_convert (GConverter *converter,
206 GConverterFlags flags,
208 gsize *bytes_written,
211 const guint8 *in, *in_end;
218 in_end = in + inbuf_size;
227 while (in+block_size < in_end && *(in+block_size) == 0)
231 block_size = v * 1000;
233 /* Not enough data */
234 if (in_end - in < block_size)
238 g_set_error_literal (error, G_IO_ERROR,
239 G_IO_ERROR_PARTIAL_INPUT,
241 return G_CONVERTER_ERROR;
244 for (i = 0; i < block_size; i++)
250 g_set_error_literal (error, G_IO_ERROR,
251 G_IO_ERROR_INVALID_DATA,
253 return G_CONVERTER_ERROR;
257 if (v == 0 && in_end - in == block_size && (flags & G_CONVERTER_INPUT_AT_END) == 0)
261 g_set_error_literal (error, G_IO_ERROR,
262 G_IO_ERROR_PARTIAL_INPUT,
264 return G_CONVERTER_ERROR;
269 *bytes_read += block_size;
273 if (in == in_end && (flags & G_CONVERTER_INPUT_AT_END))
274 return G_CONVERTER_FINISHED;
275 return G_CONVERTER_CONVERTED;
279 g_compressor_converter_iface_init (GConverterIface *iface)
281 iface->convert = g_compressor_converter_convert;
282 iface->reset = g_compressor_converter_reset;
285 guint8 unexpanded_data[] = { 0,1,3,4,5,6,7,3,12,0,0};
290 guint8 *converted1, *converted2, *ptr;
291 gsize n_read, n_written;
294 GConverterResult cres;
295 GInputStream *mem, *cstream;
296 GOutputStream *mem_out, *cstream_out;
297 GConverter *expander;
298 GConverter *converter;
302 expander = g_expander_converter_new ();
304 converted1 = g_malloc (100*1000); /* Large enough */
305 converted2 = g_malloc (100*1000); /* Large enough */
307 cres = g_converter_convert (expander,
308 unexpanded_data, sizeof(unexpanded_data),
309 converted1, 100*1000,
310 G_CONVERTER_INPUT_AT_END,
311 &n_read, &n_written, NULL);
313 g_assert (cres == G_CONVERTER_FINISHED);
314 g_assert (n_read == 11);
315 g_assert (n_written == 41030);
317 g_converter_reset (expander);
319 mem = g_memory_input_stream_new_from_data (unexpanded_data,
320 sizeof (unexpanded_data),
322 cstream = g_converter_input_stream_new (mem, expander);
323 g_assert (g_converter_input_stream_get_converter (G_CONVERTER_INPUT_STREAM (cstream)) == expander);
324 g_object_get (cstream, "converter", &converter, NULL);
325 g_assert (converter == expander);
326 g_object_unref (converter);
327 g_object_unref (mem);
334 res = g_input_stream_read (cstream,
337 g_assert (res != -1);
344 g_assert (total_read == n_written);
345 g_assert (memcmp (converted1, converted2, n_written) == 0);
347 g_converter_reset (expander);
349 mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
350 cstream_out = g_converter_output_stream_new (mem_out, expander);
351 g_assert (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (cstream_out)) == expander);
352 g_object_get (cstream_out, "converter", &converter, NULL);
353 g_assert (converter == expander);
354 g_object_unref (converter);
355 g_object_unref (mem_out);
357 for (i = 0; i < sizeof(unexpanded_data); i++)
360 res = g_output_stream_write (cstream_out,
361 unexpanded_data + i, 1,
363 g_assert (res != -1);
366 g_assert (i == sizeof(unexpanded_data) -1);
372 g_output_stream_close (cstream_out, NULL, NULL);
374 g_assert (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)) == n_written);
375 g_assert (memcmp (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)),
381 g_object_unref (cstream);
382 g_object_unref (cstream_out);
383 g_object_unref (expander);
387 test_compressor (void)
389 guint8 *converted, *expanded, *ptr;
390 gsize n_read, expanded_size;
393 GConverterResult cres;
394 GInputStream *mem, *cstream;
395 GOutputStream *mem_out, *cstream_out;
396 GConverter *expander, *compressor;
400 expander = g_expander_converter_new ();
401 expanded = g_malloc (100*1000); /* Large enough */
402 cres = g_converter_convert (expander,
403 unexpanded_data, sizeof(unexpanded_data),
405 G_CONVERTER_INPUT_AT_END,
406 &n_read, &expanded_size, NULL);
407 g_assert (cres == G_CONVERTER_FINISHED);
408 g_assert (n_read == 11);
409 g_assert (expanded_size == 41030);
411 compressor = g_compressor_converter_new ();
413 converted = g_malloc (100*1000); /* Large enough */
415 mem = g_memory_input_stream_new_from_data (expanded,
418 cstream = g_converter_input_stream_new (mem, compressor);
419 g_object_unref (mem);
426 res = g_input_stream_read (cstream,
429 g_assert (res != -1);
436 g_assert (total_read == n_read - 1); /* Last 2 zeros are combined */
437 g_assert (memcmp (converted, unexpanded_data, total_read) == 0);
439 g_object_unref (cstream);
441 g_converter_reset (compressor);
443 mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
444 cstream_out = g_converter_output_stream_new (mem_out, compressor);
445 g_object_unref (mem_out);
447 for (i = 0; i < expanded_size; i++)
450 res = g_output_stream_write (cstream_out,
453 g_assert (res != -1);
456 g_assert (i == expanded_size -1);
462 g_output_stream_close (cstream_out, NULL, NULL);
464 g_assert (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)) == n_read - 1); /* Last 2 zeros are combined */
465 g_assert (memcmp (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)),
467 g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out))) == 0);
469 g_object_unref (cstream_out);
471 g_converter_reset (compressor);
473 memset (expanded, 5, 5*1000*2);
475 mem = g_memory_input_stream_new_from_data (expanded,
478 cstream = g_converter_input_stream_new (mem, compressor);
479 g_object_unref (mem);
486 res = g_input_stream_read (cstream,
489 g_assert (res != -1);
496 g_assert (total_read == 1);
497 g_assert (*converted == 5);
499 g_object_unref (cstream);
501 mem = g_memory_input_stream_new_from_data (expanded,
504 cstream = g_converter_input_stream_new (mem, compressor);
505 g_object_unref (mem);
512 res = g_input_stream_read (cstream,
515 g_assert (res != -1);
522 g_assert (total_read == 2);
523 g_assert (converted[0] == 5);
524 g_assert (converted[1] == 5);
526 g_object_unref (cstream);
528 g_converter_reset (compressor);
530 mem = g_memory_input_stream_new_from_data (expanded,
533 cstream = g_converter_input_stream_new (mem, compressor);
534 g_object_unref (mem);
541 res = g_input_stream_read (cstream,
546 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT);
547 g_error_free (error);
556 g_assert (total_read == 1);
557 g_assert (converted[0] == 5);
559 g_object_unref (cstream);
563 g_object_unref (expander);
564 g_object_unref (compressor);
567 #define LEFTOVER_SHORT_READ_SIZE 512
569 #define G_TYPE_LEFTOVER_CONVERTER (g_leftover_converter_get_type ())
570 #define G_LEFTOVER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverter))
571 #define G_LEFTOVER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass))
572 #define G_IS_LEFTOVER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LEFTOVER_CONVERTER))
573 #define G_IS_LEFTOVER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LEFTOVER_CONVERTER))
574 #define G_LEFTOVER_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass))
576 typedef struct _GLeftoverConverter GLeftoverConverter;
577 typedef struct _GLeftoverConverterClass GLeftoverConverterClass;
579 struct _GLeftoverConverterClass
581 GObjectClass parent_class;
584 GType g_leftover_converter_get_type (void) G_GNUC_CONST;
585 GConverter *g_leftover_converter_new (void);
589 static void g_leftover_converter_iface_init (GConverterIface *iface);
591 struct _GLeftoverConverter
593 GObject parent_instance;
596 G_DEFINE_TYPE_WITH_CODE (GLeftoverConverter, g_leftover_converter, G_TYPE_OBJECT,
597 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
598 g_leftover_converter_iface_init))
601 g_leftover_converter_class_init (GLeftoverConverterClass *klass)
606 g_leftover_converter_init (GLeftoverConverter *local)
611 g_leftover_converter_new (void)
615 conv = g_object_new (G_TYPE_LEFTOVER_CONVERTER, NULL);
621 g_leftover_converter_reset (GConverter *converter)
625 static GConverterResult
626 g_leftover_converter_convert (GConverter *converter,
631 GConverterFlags flags,
633 gsize *bytes_written,
636 if (outbuf_size == LEFTOVER_SHORT_READ_SIZE)
638 g_set_error_literal (error,
640 G_IO_ERROR_PARTIAL_INPUT,
642 return G_CONVERTER_ERROR;
645 if (inbuf_size < 100)
646 *bytes_read = *bytes_written = MIN (inbuf_size, outbuf_size);
648 *bytes_read = *bytes_written = MIN (inbuf_size - 10, outbuf_size);
649 memcpy (outbuf, inbuf, *bytes_written);
651 if (*bytes_read == inbuf_size && (flags & G_CONVERTER_INPUT_AT_END))
652 return G_CONVERTER_FINISHED;
653 return G_CONVERTER_CONVERTED;
657 g_leftover_converter_iface_init (GConverterIface *iface)
659 iface->convert = g_leftover_converter_convert;
660 iface->reset = g_leftover_converter_reset;
663 #define LEFTOVER_BUFSIZE 8192
664 #define INTERNAL_BUFSIZE 4096
667 test_converter_leftover (void)
669 gchar *orig, *converted;
673 GInputStream *mem, *cstream;
674 GConverter *converter;
678 converter = g_leftover_converter_new ();
680 orig = g_malloc (LEFTOVER_BUFSIZE);
681 converted = g_malloc (LEFTOVER_BUFSIZE);
682 for (i = 0; i < LEFTOVER_BUFSIZE; i++)
683 orig[i] = i % 64 + 32;
685 mem = g_memory_input_stream_new_from_data (orig, LEFTOVER_BUFSIZE, NULL);
686 cstream = g_converter_input_stream_new (mem, G_CONVERTER (converter));
687 g_object_unref (mem);
692 res = g_input_stream_read (cstream,
693 converted, LEFTOVER_SHORT_READ_SIZE,
695 g_assert_cmpint (res, ==, LEFTOVER_SHORT_READ_SIZE);
698 offset = g_seekable_tell (G_SEEKABLE (mem));
699 g_assert_cmpint (offset, >, LEFTOVER_SHORT_READ_SIZE);
700 g_assert_cmpint (offset, <, LEFTOVER_BUFSIZE);
702 /* At this point, @cstream has both a non-empty input_buffer
703 * and a non-empty converted_buffer, which is the case
710 res = g_input_stream_read (cstream,
711 converted + total_read,
712 LEFTOVER_BUFSIZE - total_read,
720 g_assert_cmpint (total_read, ==, LEFTOVER_BUFSIZE);
721 g_assert (memcmp (converted, orig, LEFTOVER_BUFSIZE) == 0);
723 g_object_unref (cstream);
726 g_object_unref (converter);
729 #define DATA_LENGTH 1000000
733 GZlibCompressorFormat format;
738 test_roundtrip (gconstpointer data)
740 const CompressorTest *test = data;
741 GError *error = NULL;
742 guint32 *data0, *data1;
745 GInputStream *istream0, *istream1, *cistream1;
746 GOutputStream *ostream1, *ostream2, *costream1;
747 GConverter *compressor, *decompressor;
748 GZlibCompressorFormat fmt;
751 g_test_bug ("619945");
753 data0 = g_malloc (DATA_LENGTH * sizeof (guint32));
754 for (i = 0; i < DATA_LENGTH; i++)
755 data0[i] = g_random_int ();
757 istream0 = g_memory_input_stream_new_from_data (data0,
758 DATA_LENGTH * sizeof (guint32), NULL);
760 ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
761 compressor = G_CONVERTER (g_zlib_compressor_new (test->format, test->level));
762 costream1 = g_converter_output_stream_new (ostream1, compressor);
763 g_assert (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor);
765 g_output_stream_splice (costream1, istream0, 0, NULL, &error);
766 g_assert_no_error (error);
768 g_object_unref (costream1);
770 g_converter_reset (compressor);
771 g_object_get (compressor, "format", &fmt, "level", &lvl, NULL);
772 g_assert_cmpint (fmt, ==, test->format);
773 g_assert_cmpint (lvl, ==, test->level);
774 g_object_unref (compressor);
775 data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1));
776 data1_size = g_memory_output_stream_get_data_size (
777 G_MEMORY_OUTPUT_STREAM (ostream1));
778 g_object_unref (ostream1);
779 g_object_unref (istream0);
781 istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free);
782 decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format));
783 cistream1 = g_converter_input_stream_new (istream1, decompressor);
785 ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
787 g_output_stream_splice (ostream2, cistream1, 0, NULL, &error);
788 g_assert_no_error (error);
790 g_assert_cmpuint (DATA_LENGTH * sizeof (guint32), ==,
791 g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream2)));
792 g_assert (memcmp (data0, g_memory_output_stream_get_data (
793 G_MEMORY_OUTPUT_STREAM (ostream2)), DATA_LENGTH * sizeof (guint32)) == 0);
794 g_object_unref (istream1);
795 g_converter_reset (decompressor);
796 g_object_get (decompressor, "format", &fmt, NULL);
797 g_assert_cmpint (fmt, ==, test->format);
798 g_object_unref (decompressor);
799 g_object_unref (cistream1);
800 g_object_unref (ostream2);
806 const gchar *charset_in;
807 const gchar *text_in;
808 const gchar *charset_out;
809 const gchar *text_out;
814 test_charset (gconstpointer data)
816 const CharsetTest *test = data;
817 GInputStream *in, *in2;
825 conv = (GConverter *)g_charset_converter_new (test->charset_out, test->charset_in, NULL);
826 g_object_get (conv, "use-fallback", &fallback, NULL);
827 g_assert (!fallback);
829 in = g_memory_input_stream_new_from_data (test->text_in, -1, NULL);
830 in2 = g_converter_input_stream_new (in, conv);
832 count = 2 * strlen (test->text_out);
833 buffer = g_malloc0 (count);
835 g_input_stream_read_all (in2, buffer, count, &bytes_read, NULL, &error);
836 if (test->n_fallbacks == 0)
838 g_assert_no_error (error);
839 g_assert_cmpint (bytes_read, ==, strlen (test->text_out));
840 g_assert_cmpstr (buffer, ==, test->text_out);
844 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
845 g_error_free (error);
849 g_object_unref (in2);
852 if (test->n_fallbacks == 0)
854 g_object_unref (conv);
858 g_converter_reset (conv);
860 g_assert (!g_charset_converter_get_use_fallback (G_CHARSET_CONVERTER (conv)));
861 g_charset_converter_set_use_fallback (G_CHARSET_CONVERTER (conv), TRUE);
863 in = g_memory_input_stream_new_from_data (test->text_in, -1, NULL);
864 in2 = g_converter_input_stream_new (in, conv);
866 count = 2 * strlen (test->text_out);
867 buffer = g_malloc0 (count);
869 g_input_stream_read_all (in2, buffer, count, &bytes_read, NULL, &error);
870 g_assert_no_error (error);
871 g_assert_cmpstr (buffer, ==, test->text_out);
872 g_assert_cmpint (bytes_read, ==, strlen (test->text_out));
873 g_assert_cmpint (test->n_fallbacks, ==, g_charset_converter_get_num_fallbacks (G_CHARSET_CONVERTER (conv)));
876 g_object_unref (in2);
879 g_object_unref (conv);
884 client_connected (GObject *source,
885 GAsyncResult *result,
888 GSocketClient *client = G_SOCKET_CLIENT (source);
889 GSocketConnection **conn = user_data;
890 GError *error = NULL;
892 *conn = g_socket_client_connect_finish (client, result, &error);
893 g_assert_no_error (error);
897 server_connected (GObject *source,
898 GAsyncResult *result,
901 GSocketListener *listener = G_SOCKET_LISTENER (source);
902 GSocketConnection **conn = user_data;
903 GError *error = NULL;
905 *conn = g_socket_listener_accept_finish (listener, result, NULL, &error);
906 g_assert_no_error (error);
910 make_socketpair (GIOStream **left,
914 GSocketAddress *saddr, *effective_address;
915 GSocketListener *listener;
916 GSocketClient *client;
917 GError *error = NULL;
918 GSocketConnection *client_conn = NULL, *server_conn = NULL;
920 iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
921 saddr = g_inet_socket_address_new (iaddr, 0);
922 g_object_unref (iaddr);
924 listener = g_socket_listener_new ();
925 g_socket_listener_add_address (listener, saddr,
926 G_SOCKET_TYPE_STREAM,
927 G_SOCKET_PROTOCOL_TCP,
931 g_assert_no_error (error);
932 g_object_unref (saddr);
934 client = g_socket_client_new ();
936 g_socket_client_connect_async (client,
937 G_SOCKET_CONNECTABLE (effective_address),
938 NULL, client_connected, &client_conn);
939 g_socket_listener_accept_async (listener, NULL,
940 server_connected, &server_conn);
942 while (!client_conn || !server_conn)
943 g_main_context_iteration (NULL, TRUE);
945 g_object_unref (client);
946 g_object_unref (listener);
947 g_object_unref (effective_address);
949 *left = G_IO_STREAM (client_conn);
950 *right = G_IO_STREAM (server_conn);
954 test_converter_pollable (void)
956 GIOStream *left, *right;
957 guint8 *converted, *inptr;
958 guint8 *expanded, *outptr, *expanded_end;
959 gsize n_read, expanded_size;
962 gboolean is_readable;
963 GConverterResult cres;
964 GInputStream *cstream;
965 GPollableInputStream *pollable_in;
966 GOutputStream *socket_out, *mem_out, *cstream_out;
967 GPollableOutputStream *pollable_out;
968 GConverter *expander, *compressor;
972 expander = g_expander_converter_new ();
973 expanded = g_malloc (100*1000); /* Large enough */
974 cres = g_converter_convert (expander,
975 unexpanded_data, sizeof(unexpanded_data),
977 G_CONVERTER_INPUT_AT_END,
978 &n_read, &expanded_size, NULL);
979 g_assert (cres == G_CONVERTER_FINISHED);
980 g_assert (n_read == 11);
981 g_assert (expanded_size == 41030);
982 expanded_end = expanded + expanded_size;
984 make_socketpair (&left, &right);
986 compressor = g_compressor_converter_new ();
988 converted = g_malloc (100*1000); /* Large enough */
990 cstream = g_converter_input_stream_new (g_io_stream_get_input_stream (left),
992 pollable_in = G_POLLABLE_INPUT_STREAM (cstream);
993 g_assert (g_pollable_input_stream_can_poll (pollable_in));
995 socket_out = g_io_stream_get_output_stream (right);
1004 if (outptr < expanded_end)
1006 res = g_output_stream_write (socket_out,
1008 MIN (1000, (expanded_end - outptr)),
1010 g_assert_cmpint (res, >, 0);
1013 else if (socket_out)
1015 g_object_unref (right);
1019 is_readable = g_pollable_input_stream_is_readable (pollable_in);
1020 res = g_pollable_input_stream_read_nonblocking (pollable_in,
1024 /* is_readable can be a false positive, but not a false negative */
1026 g_assert_cmpint (res, ==, -1);
1028 /* After closing the write end, we can't get WOULD_BLOCK any more */
1030 g_assert_cmpint (res, !=, -1);
1034 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
1035 g_error_free (error);
1046 g_assert (total_read == n_read - 1); /* Last 2 zeros are combined */
1047 g_assert (memcmp (converted, unexpanded_data, total_read) == 0);
1049 g_object_unref (cstream);
1050 g_object_unref (left);
1052 g_converter_reset (compressor);
1054 /* This doesn't actually test the behavior on
1055 * G_IO_ERROR_WOULD_BLOCK; to do that we'd need to implement a
1056 * custom GOutputStream that we could control blocking on.
1059 mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
1060 cstream_out = g_converter_output_stream_new (mem_out, compressor);
1061 g_object_unref (mem_out);
1062 pollable_out = G_POLLABLE_OUTPUT_STREAM (cstream_out);
1064 for (i = 0; i < expanded_size; i++)
1067 res = g_pollable_output_stream_write_nonblocking (pollable_out,
1070 g_assert (res != -1);
1073 g_assert (i == expanded_size -1);
1076 g_assert (res == 1);
1079 g_output_stream_close (cstream_out, NULL, NULL);
1081 g_assert (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)) == n_read - 1); /* Last 2 zeros are combined */
1082 g_assert (memcmp (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)),
1084 g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out))) == 0);
1086 g_object_unref (cstream_out);
1090 g_object_unref (expander);
1091 g_object_unref (compressor);
1095 test_truncation (gconstpointer data)
1097 const CompressorTest *test = data;
1098 GError *error = NULL;
1099 guint32 *data0, *data1;
1102 GInputStream *istream0, *istream1, *cistream1;
1103 GOutputStream *ostream1, *ostream2, *costream1;
1104 GConverter *compressor, *decompressor;
1106 data0 = g_malloc (DATA_LENGTH * sizeof (guint32));
1107 for (i = 0; i < DATA_LENGTH; i++)
1108 data0[i] = g_random_int ();
1110 istream0 = g_memory_input_stream_new_from_data (data0,
1111 DATA_LENGTH * sizeof (guint32), NULL);
1113 ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
1114 compressor = G_CONVERTER (g_zlib_compressor_new (test->format, -1));
1115 costream1 = g_converter_output_stream_new (ostream1, compressor);
1116 g_assert (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor);
1118 g_output_stream_splice (costream1, istream0, 0, NULL, &error);
1119 g_assert_no_error (error);
1121 g_object_unref (costream1);
1122 g_object_unref (compressor);
1124 data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1));
1125 data1_size = g_memory_output_stream_get_data_size (
1126 G_MEMORY_OUTPUT_STREAM (ostream1));
1127 g_object_unref (ostream1);
1128 g_object_unref (istream0);
1133 istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free);
1134 decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format));
1135 cistream1 = g_converter_input_stream_new (istream1, decompressor);
1137 ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
1139 g_output_stream_splice (ostream2, cistream1, 0, NULL, &error);
1140 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT);
1141 g_error_free (error);
1143 g_object_unref (istream1);
1144 g_object_unref (decompressor);
1145 g_object_unref (cistream1);
1146 g_object_unref (ostream2);
1154 CompressorTest compressor_tests[] = {
1155 { "/converter-output-stream/roundtrip/zlib-0", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 },
1156 { "/converter-output-stream/roundtrip/zlib-9", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9 },
1157 { "/converter-output-stream/roundtrip/gzip-0", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 },
1158 { "/converter-output-stream/roundtrip/gzip-9", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 9 },
1159 { "/converter-output-stream/roundtrip/raw-0", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 },
1160 { "/converter-output-stream/roundtrip/raw-9", G_ZLIB_COMPRESSOR_FORMAT_RAW, 9 },
1162 CompressorTest truncation_tests[] = {
1163 { "/converter-input-stream/truncation/zlib", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 },
1164 { "/converter-input-stream/truncation/gzip", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 },
1165 { "/converter-input-stream/truncation/raw", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 },
1167 CharsetTest charset_tests[] = {
1168 { "/converter-input-stream/charset/utf8->latin1", "UTF-8", "\303\205rr Sant\303\251", "ISO-8859-1", "\305rr Sant\351", 0 },
1169 { "/converter-input-stream/charset/latin1->utf8", "ISO-8859-1", "\305rr Sant\351", "UTF-8", "\303\205rr Sant\303\251", 0 },
1170 { "/converter-input-stream/charset/fallbacks", "UTF-8", "Some characters just don't fit into latin1: πא", "ISO-8859-1", "Some characters just don't fit into latin1: \\CF\\80\\D7\\90", 4 },
1175 g_test_init (&argc, &argv, NULL);
1177 g_test_bug_base ("http://bugzilla.gnome.org/");
1179 g_test_add_func ("/converter-input-stream/expander", test_expander);
1180 g_test_add_func ("/converter-input-stream/compressor", test_compressor);
1182 for (i = 0; i < G_N_ELEMENTS (compressor_tests); i++)
1183 g_test_add_data_func (compressor_tests[i].path, &compressor_tests[i], test_roundtrip);
1185 for (i = 0; i < G_N_ELEMENTS (truncation_tests); i++)
1186 g_test_add_data_func (truncation_tests[i].path, &truncation_tests[i], test_truncation);
1188 for (i = 0; i < G_N_ELEMENTS (charset_tests); i++)
1189 g_test_add_data_func (charset_tests[i].path, &charset_tests[i], test_charset);
1191 g_test_add_func ("/converter-stream/pollable", test_converter_pollable);
1192 g_test_add_func ("/converter-stream/leftover", test_converter_leftover);
1194 return g_test_run();