1 /* GLib testing framework examples and tests
2 * Copyright (C) 2009 Red Hat, Inc.
3 * Authors: Alexander Larsson <alexl@redhat.com>
5 * SPDX-License-Identifier: LicenseRef-old-glib-tests
7 * This work is provided "as is"; redistribution and modification
8 * in whole or in part, in any medium, physical or electronic is
9 * permitted without restriction.
11 * This work is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 * In no event shall the authors or contributors be liable for any
16 * direct, indirect, incidental, special, exemplary, or consequential
17 * damages (including, but not limited to, procurement of substitute
18 * goods or services; loss of use, data, or profits; or business
19 * interruption) however caused and on any theory of liability, whether
20 * in contract, strict liability, or tort (including negligence or
21 * otherwise) arising in any way out of the use of this software, even
22 * if advised of the possibility of such damage.
25 #include <glib/glib.h>
30 #define G_TYPE_EXPANDER_CONVERTER (g_expander_converter_get_type ())
31 #define G_EXPANDER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_EXPANDER_CONVERTER, GExpanderConverter))
32 #define G_EXPANDER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_EXPANDER_CONVERTER, GExpanderConverterClass))
33 #define G_IS_EXPANDER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_EXPANDER_CONVERTER))
34 #define G_IS_EXPANDER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_EXPANDER_CONVERTER))
35 #define G_EXPANDER_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_EXPANDER_CONVERTER, GExpanderConverterClass))
37 typedef struct _GExpanderConverter GExpanderConverter;
38 typedef struct _GExpanderConverterClass GExpanderConverterClass;
40 struct _GExpanderConverterClass
42 GObjectClass parent_class;
45 GType g_expander_converter_get_type (void) G_GNUC_CONST;
46 GConverter *g_expander_converter_new (void);
50 static void g_expander_converter_iface_init (GConverterIface *iface);
52 struct _GExpanderConverter
54 GObject parent_instance;
57 G_DEFINE_TYPE_WITH_CODE (GExpanderConverter, g_expander_converter, G_TYPE_OBJECT,
58 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
59 g_expander_converter_iface_init))
62 g_expander_converter_class_init (GExpanderConverterClass *klass)
67 g_expander_converter_init (GExpanderConverter *local)
72 g_expander_converter_new (void)
76 conv = g_object_new (G_TYPE_EXPANDER_CONVERTER, NULL);
82 g_expander_converter_reset (GConverter *converter)
86 static GConverterResult
87 g_expander_converter_convert (GConverter *converter,
92 GConverterFlags flags,
97 const guint8 *in, *in_end;
104 in_end = in + inbuf_size;
113 block_size = v * 1000;
115 if (outbuf_size < block_size)
118 return G_CONVERTER_CONVERTED;
120 g_set_error_literal (error, G_IO_ERROR,
123 return G_CONVERTER_ERROR;
128 *bytes_written += block_size;
129 outbuf_size -= block_size;
130 for (i = 0; i < block_size; i++)
134 if (in == in_end && (flags & G_CONVERTER_INPUT_AT_END))
135 return G_CONVERTER_FINISHED;
136 return G_CONVERTER_CONVERTED;
140 g_expander_converter_iface_init (GConverterIface *iface)
142 iface->convert = g_expander_converter_convert;
143 iface->reset = g_expander_converter_reset;
146 #define G_TYPE_COMPRESSOR_CONVERTER (g_compressor_converter_get_type ())
147 #define G_COMPRESSOR_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverter))
148 #define G_COMPRESSOR_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverterClass))
149 #define G_IS_COMPRESSOR_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_COMPRESSOR_CONVERTER))
150 #define G_IS_COMPRESSOR_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_COMPRESSOR_CONVERTER))
151 #define G_COMPRESSOR_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_COMPRESSOR_CONVERTER, GCompressorConverterClass))
153 typedef struct _GCompressorConverter GCompressorConverter;
154 typedef struct _GCompressorConverterClass GCompressorConverterClass;
156 struct _GCompressorConverterClass
158 GObjectClass parent_class;
161 GType g_compressor_converter_get_type (void) G_GNUC_CONST;
162 GConverter *g_compressor_converter_new (void);
166 static void g_compressor_converter_iface_init (GConverterIface *iface);
168 struct _GCompressorConverter
170 GObject parent_instance;
173 G_DEFINE_TYPE_WITH_CODE (GCompressorConverter, g_compressor_converter, G_TYPE_OBJECT,
174 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
175 g_compressor_converter_iface_init))
178 g_compressor_converter_class_init (GCompressorConverterClass *klass)
183 g_compressor_converter_init (GCompressorConverter *local)
188 g_compressor_converter_new (void)
192 conv = g_object_new (G_TYPE_COMPRESSOR_CONVERTER, NULL);
198 g_compressor_converter_reset (GConverter *converter)
202 static GConverterResult
203 g_compressor_converter_convert (GConverter *converter,
208 GConverterFlags flags,
210 gsize *bytes_written,
213 const guint8 *in, *in_end;
220 in_end = in + inbuf_size;
229 while (in+block_size < in_end && *(in+block_size) == 0)
233 block_size = v * 1000;
235 /* Not enough data */
236 if ((gsize) (in_end - in) < block_size)
240 g_set_error_literal (error, G_IO_ERROR,
241 G_IO_ERROR_PARTIAL_INPUT,
243 return G_CONVERTER_ERROR;
246 for (i = 0; i < block_size; i++)
252 g_set_error_literal (error, G_IO_ERROR,
253 G_IO_ERROR_INVALID_DATA,
255 return G_CONVERTER_ERROR;
259 if (v == 0 && (gsize) (in_end - in) == block_size && (flags & G_CONVERTER_INPUT_AT_END) == 0)
263 g_set_error_literal (error, G_IO_ERROR,
264 G_IO_ERROR_PARTIAL_INPUT,
266 return G_CONVERTER_ERROR;
271 *bytes_read += block_size;
275 if (in == in_end && (flags & G_CONVERTER_INPUT_AT_END))
276 return G_CONVERTER_FINISHED;
277 return G_CONVERTER_CONVERTED;
281 g_compressor_converter_iface_init (GConverterIface *iface)
283 iface->convert = g_compressor_converter_convert;
284 iface->reset = g_compressor_converter_reset;
287 guint8 unexpanded_data[] = { 0,1,3,4,5,6,7,3,12,0,0};
292 guint8 *converted1, *converted2, *ptr;
293 gsize n_read, n_written;
296 GConverterResult cres;
297 GInputStream *mem, *cstream;
298 GOutputStream *mem_out, *cstream_out;
299 GConverter *expander;
300 GConverter *converter;
304 expander = g_expander_converter_new ();
306 converted1 = g_malloc (100*1000); /* Large enough */
307 converted2 = g_malloc (100*1000); /* Large enough */
309 cres = g_converter_convert (expander,
310 unexpanded_data, sizeof(unexpanded_data),
311 converted1, 100*1000,
312 G_CONVERTER_INPUT_AT_END,
313 &n_read, &n_written, NULL);
315 g_assert_cmpint (cres, ==, G_CONVERTER_FINISHED);
316 g_assert_cmpuint (n_read, ==, 11);
317 g_assert_cmpuint (n_written, ==, 41030);
319 g_converter_reset (expander);
321 mem = g_memory_input_stream_new_from_data (unexpanded_data,
322 sizeof (unexpanded_data),
324 cstream = g_converter_input_stream_new (mem, expander);
325 g_assert_true (g_converter_input_stream_get_converter (G_CONVERTER_INPUT_STREAM (cstream)) == expander);
326 g_object_get (cstream, "converter", &converter, NULL);
327 g_assert_true (converter == expander);
328 g_object_unref (converter);
329 g_object_unref (mem);
336 res = g_input_stream_read (cstream,
339 g_assert_cmpint (res, !=, -1);
346 g_assert_cmpmem (converted1, n_written, converted2, total_read);
348 g_converter_reset (expander);
350 mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
351 cstream_out = g_converter_output_stream_new (mem_out, expander);
352 g_assert_true (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (cstream_out)) == expander);
353 g_object_get (cstream_out, "converter", &converter, NULL);
354 g_assert_true (converter == expander);
355 g_object_unref (converter);
356 g_object_unref (mem_out);
358 for (i = 0; i < sizeof(unexpanded_data); i++)
361 res = g_output_stream_write (cstream_out,
362 unexpanded_data + i, 1,
364 g_assert_cmpint (res, !=, -1);
367 g_assert_cmpuint (i, ==, sizeof(unexpanded_data) -1);
370 g_assert_cmpint (res, ==, 1);
373 g_output_stream_close (cstream_out, NULL, NULL);
375 g_assert_cmpmem (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)),
376 g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)),
377 converted1, n_written);
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_cmpint (cres, ==, G_CONVERTER_FINISHED);
408 g_assert_cmpuint (n_read, ==, 11);
409 g_assert_cmpuint (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_cmpint (res, !=, -1);
436 /* "n_read - 1" because last 2 zeros are combined */
437 g_assert_cmpmem (unexpanded_data, n_read - 1, converted, total_read);
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_cmpint (res, !=, -1);
456 g_assert_cmpuint (i, ==, expanded_size -1);
459 g_assert_cmpint (res, ==, 1);
462 g_output_stream_close (cstream_out, NULL, NULL);
464 /* "n_read - 1" because last 2 zeros are combined */
465 g_assert_cmpmem (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)),
466 g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)),
470 g_object_unref (cstream_out);
472 g_converter_reset (compressor);
474 memset (expanded, 5, 5*1000*2);
476 mem = g_memory_input_stream_new_from_data (expanded,
479 cstream = g_converter_input_stream_new (mem, compressor);
480 g_object_unref (mem);
487 res = g_input_stream_read (cstream,
490 g_assert_cmpint (res, !=, -1);
497 g_assert_cmpuint (total_read, ==, 1);
498 g_assert_cmpuint (*converted, ==, 5);
500 g_object_unref (cstream);
502 mem = g_memory_input_stream_new_from_data (expanded,
505 cstream = g_converter_input_stream_new (mem, compressor);
506 g_object_unref (mem);
513 res = g_input_stream_read (cstream,
516 g_assert_cmpint (res, !=, -1);
523 g_assert_cmpuint (total_read, ==, 2);
524 g_assert_cmpuint (converted[0], ==, 5);
525 g_assert_cmpuint (converted[1], ==, 5);
527 g_object_unref (cstream);
529 g_converter_reset (compressor);
531 mem = g_memory_input_stream_new_from_data (expanded,
534 cstream = g_converter_input_stream_new (mem, compressor);
535 g_object_unref (mem);
542 res = g_input_stream_read (cstream,
547 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT);
548 g_error_free (error);
552 g_assert_cmpint (res, !=, 0);
557 g_assert_cmpuint (total_read, ==, 1);
558 g_assert_cmpuint (converted[0], ==, 5);
560 g_object_unref (cstream);
564 g_object_unref (expander);
565 g_object_unref (compressor);
568 #define LEFTOVER_SHORT_READ_SIZE 512
570 #define G_TYPE_LEFTOVER_CONVERTER (g_leftover_converter_get_type ())
571 #define G_LEFTOVER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverter))
572 #define G_LEFTOVER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass))
573 #define G_IS_LEFTOVER_CONVERTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_LEFTOVER_CONVERTER))
574 #define G_IS_LEFTOVER_CONVERTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_LEFTOVER_CONVERTER))
575 #define G_LEFTOVER_CONVERTER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_LEFTOVER_CONVERTER, GLeftoverConverterClass))
577 typedef struct _GLeftoverConverter GLeftoverConverter;
578 typedef struct _GLeftoverConverterClass GLeftoverConverterClass;
580 struct _GLeftoverConverterClass
582 GObjectClass parent_class;
585 GType g_leftover_converter_get_type (void) G_GNUC_CONST;
586 GConverter *g_leftover_converter_new (void);
590 static void g_leftover_converter_iface_init (GConverterIface *iface);
592 struct _GLeftoverConverter
594 GObject parent_instance;
597 G_DEFINE_TYPE_WITH_CODE (GLeftoverConverter, g_leftover_converter, G_TYPE_OBJECT,
598 G_IMPLEMENT_INTERFACE (G_TYPE_CONVERTER,
599 g_leftover_converter_iface_init))
602 g_leftover_converter_class_init (GLeftoverConverterClass *klass)
607 g_leftover_converter_init (GLeftoverConverter *local)
612 g_leftover_converter_new (void)
616 conv = g_object_new (G_TYPE_LEFTOVER_CONVERTER, NULL);
622 g_leftover_converter_reset (GConverter *converter)
626 static GConverterResult
627 g_leftover_converter_convert (GConverter *converter,
632 GConverterFlags flags,
634 gsize *bytes_written,
637 if (outbuf_size == LEFTOVER_SHORT_READ_SIZE)
639 g_set_error_literal (error,
641 G_IO_ERROR_PARTIAL_INPUT,
643 return G_CONVERTER_ERROR;
646 if (inbuf_size < 100)
647 *bytes_read = *bytes_written = MIN (inbuf_size, outbuf_size);
649 *bytes_read = *bytes_written = MIN (inbuf_size - 10, outbuf_size);
650 memcpy (outbuf, inbuf, *bytes_written);
652 if (*bytes_read == inbuf_size && (flags & G_CONVERTER_INPUT_AT_END))
653 return G_CONVERTER_FINISHED;
654 return G_CONVERTER_CONVERTED;
658 g_leftover_converter_iface_init (GConverterIface *iface)
660 iface->convert = g_leftover_converter_convert;
661 iface->reset = g_leftover_converter_reset;
664 #define LEFTOVER_BUFSIZE 8192
665 #define INTERNAL_BUFSIZE 4096
668 test_converter_leftover (void)
670 gchar *orig, *converted;
674 GInputStream *mem, *cstream;
675 GConverter *converter;
679 converter = g_leftover_converter_new ();
681 orig = g_malloc (LEFTOVER_BUFSIZE);
682 converted = g_malloc (LEFTOVER_BUFSIZE);
683 for (i = 0; i < LEFTOVER_BUFSIZE; i++)
684 orig[i] = i % 64 + 32;
686 mem = g_memory_input_stream_new_from_data (orig, LEFTOVER_BUFSIZE, NULL);
687 cstream = g_converter_input_stream_new (mem, G_CONVERTER (converter));
688 g_object_unref (mem);
693 res = g_input_stream_read (cstream,
694 converted, LEFTOVER_SHORT_READ_SIZE,
696 g_assert_cmpint (res, ==, LEFTOVER_SHORT_READ_SIZE);
699 offset = g_seekable_tell (G_SEEKABLE (mem));
700 g_assert_cmpint (offset, >, LEFTOVER_SHORT_READ_SIZE);
701 g_assert_cmpint (offset, <, LEFTOVER_BUFSIZE);
703 /* At this point, @cstream has both a non-empty input_buffer
704 * and a non-empty converted_buffer, which is the case
711 res = g_input_stream_read (cstream,
712 converted + total_read,
713 LEFTOVER_BUFSIZE - total_read,
715 g_assert_cmpint (res, >=, 0);
721 g_assert_cmpmem (orig, LEFTOVER_BUFSIZE, converted, total_read);
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;
753 g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=619945");
755 data0 = g_malloc (DATA_LENGTH * sizeof (guint32));
756 for (i = 0; i < DATA_LENGTH; i++)
757 data0[i] = g_random_int ();
759 istream0 = g_memory_input_stream_new_from_data (data0,
760 DATA_LENGTH * sizeof (guint32), NULL);
762 ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
763 compressor = G_CONVERTER (g_zlib_compressor_new (test->format, test->level));
764 info = g_file_info_new ();
765 g_file_info_set_name (info, "foo");
766 g_object_set (compressor, "file-info", info, NULL);
767 info2 = g_zlib_compressor_get_file_info (G_ZLIB_COMPRESSOR (compressor));
768 g_assert_true (info == info2);
769 g_object_unref (info);
770 costream1 = g_converter_output_stream_new (ostream1, compressor);
771 g_assert_true (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor);
773 g_output_stream_splice (costream1, istream0, 0, NULL, &error);
774 g_assert_no_error (error);
776 g_object_unref (costream1);
778 g_converter_reset (compressor);
779 g_object_get (compressor, "format", &fmt, "level", &lvl, NULL);
780 g_assert_cmpint (fmt, ==, test->format);
781 g_assert_cmpint (lvl, ==, test->level);
782 g_object_unref (compressor);
783 data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1));
784 data1_size = g_memory_output_stream_get_data_size (
785 G_MEMORY_OUTPUT_STREAM (ostream1));
786 g_object_unref (ostream1);
787 g_object_unref (istream0);
789 istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free);
790 decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format));
791 cistream1 = g_converter_input_stream_new (istream1, decompressor);
793 ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
795 g_output_stream_splice (ostream2, cistream1, 0, NULL, &error);
796 g_assert_no_error (error);
798 g_assert_cmpmem (data0, DATA_LENGTH * sizeof (guint32),
799 g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (ostream2)),
800 g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (ostream2)));
801 g_object_unref (istream1);
802 g_converter_reset (decompressor);
803 g_object_get (decompressor, "format", &fmt, NULL);
804 g_assert_cmpint (fmt, ==, test->format);
805 g_object_unref (decompressor);
806 g_object_unref (cistream1);
807 g_object_unref (ostream2);
813 const gchar *charset_in;
814 const gchar *text_in;
815 const gchar *charset_out;
816 const gchar *text_out;
821 test_charset (gconstpointer data)
823 const CharsetTest *test = data;
824 GInputStream *in, *in2;
832 conv = (GConverter *)g_charset_converter_new (test->charset_out, test->charset_in, NULL);
833 g_object_get (conv, "use-fallback", &fallback, NULL);
834 g_assert_false (fallback);
836 in = g_memory_input_stream_new_from_data (test->text_in, -1, NULL);
837 in2 = g_converter_input_stream_new (in, conv);
839 count = 2 * strlen (test->text_out);
840 buffer = g_malloc0 (count);
842 g_input_stream_read_all (in2, buffer, count, &bytes_read, NULL, &error);
843 if (test->n_fallbacks == 0)
845 g_assert_no_error (error);
846 g_assert_cmpint (bytes_read, ==, strlen (test->text_out));
847 g_assert_cmpstr (buffer, ==, test->text_out);
851 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA);
852 g_error_free (error);
856 g_object_unref (in2);
859 if (test->n_fallbacks == 0)
861 g_object_unref (conv);
865 g_converter_reset (conv);
867 g_assert_false (g_charset_converter_get_use_fallback (G_CHARSET_CONVERTER (conv)));
868 g_charset_converter_set_use_fallback (G_CHARSET_CONVERTER (conv), TRUE);
870 in = g_memory_input_stream_new_from_data (test->text_in, -1, NULL);
871 in2 = g_converter_input_stream_new (in, conv);
873 count = 2 * strlen (test->text_out);
874 buffer = g_malloc0 (count);
876 g_input_stream_read_all (in2, buffer, count, &bytes_read, NULL, &error);
877 g_assert_no_error (error);
878 g_assert_cmpstr (buffer, ==, test->text_out);
879 g_assert_cmpint (bytes_read, ==, strlen (test->text_out));
880 g_assert_cmpint (test->n_fallbacks, ==, g_charset_converter_get_num_fallbacks (G_CHARSET_CONVERTER (conv)));
883 g_object_unref (in2);
886 g_object_unref (conv);
891 client_connected (GObject *source,
892 GAsyncResult *result,
895 GSocketClient *client = G_SOCKET_CLIENT (source);
896 GSocketConnection **conn = user_data;
897 GError *error = NULL;
899 *conn = g_socket_client_connect_finish (client, result, &error);
900 g_assert_no_error (error);
904 server_connected (GObject *source,
905 GAsyncResult *result,
908 GSocketListener *listener = G_SOCKET_LISTENER (source);
909 GSocketConnection **conn = user_data;
910 GError *error = NULL;
912 *conn = g_socket_listener_accept_finish (listener, result, NULL, &error);
913 g_assert_no_error (error);
917 make_socketpair (GIOStream **left,
921 GSocketAddress *saddr, *effective_address;
922 GSocketListener *listener;
923 GSocketClient *client;
924 GError *error = NULL;
925 GSocketConnection *client_conn = NULL, *server_conn = NULL;
927 iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
928 saddr = g_inet_socket_address_new (iaddr, 0);
929 g_object_unref (iaddr);
931 listener = g_socket_listener_new ();
932 g_socket_listener_add_address (listener, saddr,
933 G_SOCKET_TYPE_STREAM,
934 G_SOCKET_PROTOCOL_TCP,
938 g_assert_no_error (error);
939 g_object_unref (saddr);
941 client = g_socket_client_new ();
943 g_socket_client_connect_async (client,
944 G_SOCKET_CONNECTABLE (effective_address),
945 NULL, client_connected, &client_conn);
946 g_socket_listener_accept_async (listener, NULL,
947 server_connected, &server_conn);
949 while (!client_conn || !server_conn)
950 g_main_context_iteration (NULL, TRUE);
952 g_object_unref (client);
953 g_object_unref (listener);
954 g_object_unref (effective_address);
956 *left = G_IO_STREAM (client_conn);
957 *right = G_IO_STREAM (server_conn);
961 test_converter_pollable (void)
963 GIOStream *left, *right;
964 guint8 *converted, *inptr;
965 guint8 *expanded, *outptr, *expanded_end;
966 gsize n_read, expanded_size;
969 gboolean is_readable;
970 GConverterResult cres;
971 GInputStream *cstream;
972 GPollableInputStream *pollable_in;
973 GOutputStream *socket_out, *mem_out, *cstream_out;
974 GPollableOutputStream *pollable_out;
975 GConverter *expander, *compressor;
979 expander = g_expander_converter_new ();
980 expanded = g_malloc (100*1000); /* Large enough */
981 cres = g_converter_convert (expander,
982 unexpanded_data, sizeof(unexpanded_data),
984 G_CONVERTER_INPUT_AT_END,
985 &n_read, &expanded_size, NULL);
986 g_assert_cmpint (cres, ==, G_CONVERTER_FINISHED);
987 g_assert_cmpuint (n_read, ==, 11);
988 g_assert_cmpuint (expanded_size, ==, 41030);
989 expanded_end = expanded + expanded_size;
991 make_socketpair (&left, &right);
993 compressor = g_compressor_converter_new ();
995 converted = g_malloc (100*1000); /* Large enough */
997 cstream = g_converter_input_stream_new (g_io_stream_get_input_stream (left),
999 pollable_in = G_POLLABLE_INPUT_STREAM (cstream);
1000 g_assert_true (g_pollable_input_stream_can_poll (pollable_in));
1002 socket_out = g_io_stream_get_output_stream (right);
1011 if (outptr < expanded_end)
1013 res = g_output_stream_write (socket_out,
1015 MIN (1000, (expanded_end - outptr)),
1017 g_assert_cmpint (res, >, 0);
1020 else if (socket_out)
1022 g_output_stream_close (socket_out, NULL, NULL);
1023 g_object_unref (right);
1027 /* Wait a few ticks to check for the pipe to propagate the
1028 * write. We can’t wait on a GSource as that might affect the stream under
1029 * test, so just poll. */
1030 while (!g_pollable_input_stream_is_readable (pollable_in))
1033 is_readable = g_pollable_input_stream_is_readable (pollable_in);
1034 res = g_pollable_input_stream_read_nonblocking (pollable_in,
1038 /* is_readable can be a false positive, but not a false negative */
1040 g_assert_cmpint (res, ==, -1);
1042 /* Even after closing the write end, we can get WOULD_BLOCK (particularly
1043 * on FreeBSD), so we can’t make any assertions based on `!socket_out`.
1044 * This is because the FIN packets may still be in the out buffer of one
1045 * half of the socket pair, while the in buffer of the other half has some
1046 * data, but not enough for a full block for the converter to consume. */
1050 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK);
1051 g_error_free (error);
1062 /* "n_read - 1" because last 2 zeros are combined */
1063 g_assert_cmpmem (unexpanded_data, n_read - 1, converted, total_read);
1065 g_object_unref (cstream);
1066 g_object_unref (left);
1068 g_converter_reset (compressor);
1070 /* This doesn't actually test the behavior on
1071 * G_IO_ERROR_WOULD_BLOCK; to do that we'd need to implement a
1072 * custom GOutputStream that we could control blocking on.
1075 mem_out = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
1076 cstream_out = g_converter_output_stream_new (mem_out, compressor);
1077 g_object_unref (mem_out);
1078 pollable_out = G_POLLABLE_OUTPUT_STREAM (cstream_out);
1079 g_assert_true (g_pollable_output_stream_can_poll (pollable_out));
1080 g_assert_true (g_pollable_output_stream_is_writable (pollable_out));
1082 for (i = 0; i < expanded_size; i++)
1085 res = g_pollable_output_stream_write_nonblocking (pollable_out,
1088 g_assert_cmpint (res, !=, -1);
1091 g_assert_cmpuint (i, ==, expanded_size -1);
1094 g_assert_cmpint (res, ==, 1);
1097 g_output_stream_close (cstream_out, NULL, NULL);
1099 /* "n_read - 1" because last 2 zeros are combined */
1100 g_assert_cmpmem (g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mem_out)),
1101 g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mem_out)),
1105 g_object_unref (cstream_out);
1109 g_object_unref (expander);
1110 g_object_unref (compressor);
1114 test_truncation (gconstpointer data)
1116 const CompressorTest *test = data;
1117 GError *error = NULL;
1118 guint32 *data0, *data1;
1121 GInputStream *istream0, *istream1, *cistream1;
1122 GOutputStream *ostream1, *ostream2, *costream1;
1123 GConverter *compressor, *decompressor;
1125 data0 = g_malloc (DATA_LENGTH * sizeof (guint32));
1126 for (i = 0; i < DATA_LENGTH; i++)
1127 data0[i] = g_random_int ();
1129 istream0 = g_memory_input_stream_new_from_data (data0,
1130 DATA_LENGTH * sizeof (guint32), NULL);
1132 ostream1 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
1133 compressor = G_CONVERTER (g_zlib_compressor_new (test->format, -1));
1134 costream1 = g_converter_output_stream_new (ostream1, compressor);
1135 g_assert_true (g_converter_output_stream_get_converter (G_CONVERTER_OUTPUT_STREAM (costream1)) == compressor);
1137 g_output_stream_splice (costream1, istream0, 0, NULL, &error);
1138 g_assert_no_error (error);
1140 g_object_unref (costream1);
1141 g_object_unref (compressor);
1143 data1 = g_memory_output_stream_steal_data (G_MEMORY_OUTPUT_STREAM (ostream1));
1144 data1_size = g_memory_output_stream_get_data_size (
1145 G_MEMORY_OUTPUT_STREAM (ostream1));
1146 g_object_unref (ostream1);
1147 g_object_unref (istream0);
1152 istream1 = g_memory_input_stream_new_from_data (data1, data1_size, g_free);
1153 decompressor = G_CONVERTER (g_zlib_decompressor_new (test->format));
1154 cistream1 = g_converter_input_stream_new (istream1, decompressor);
1156 ostream2 = g_memory_output_stream_new (NULL, 0, g_realloc, g_free);
1158 g_output_stream_splice (ostream2, cistream1, 0, NULL, &error);
1159 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT);
1160 g_error_free (error);
1162 g_object_unref (istream1);
1163 g_object_unref (decompressor);
1164 g_object_unref (cistream1);
1165 g_object_unref (ostream2);
1170 test_converter_basics (void)
1172 GConverter *converter;
1173 GError *error = NULL;
1177 converter = (GConverter *)g_charset_converter_new ("utf-8", "latin1", &error);
1178 g_assert_no_error (error);
1179 g_object_get (converter,
1181 "from-charset", &from,
1184 g_assert_cmpstr (to, ==, "utf-8");
1185 g_assert_cmpstr (from, ==, "latin1");
1189 g_object_unref (converter);
1196 CompressorTest compressor_tests[] = {
1197 { "/converter-output-stream/roundtrip/zlib-0", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 },
1198 { "/converter-output-stream/roundtrip/zlib-9", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 9 },
1199 { "/converter-output-stream/roundtrip/gzip-0", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 },
1200 { "/converter-output-stream/roundtrip/gzip-9", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 9 },
1201 { "/converter-output-stream/roundtrip/raw-0", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 },
1202 { "/converter-output-stream/roundtrip/raw-9", G_ZLIB_COMPRESSOR_FORMAT_RAW, 9 },
1204 CompressorTest truncation_tests[] = {
1205 { "/converter-input-stream/truncation/zlib", G_ZLIB_COMPRESSOR_FORMAT_ZLIB, 0 },
1206 { "/converter-input-stream/truncation/gzip", G_ZLIB_COMPRESSOR_FORMAT_GZIP, 0 },
1207 { "/converter-input-stream/truncation/raw", G_ZLIB_COMPRESSOR_FORMAT_RAW, 0 },
1209 CharsetTest charset_tests[] = {
1210 { "/converter-input-stream/charset/utf8->latin1", "UTF-8", "\303\205rr Sant\303\251", "ISO-8859-1", "\305rr Sant\351", 0 },
1211 { "/converter-input-stream/charset/latin1->utf8", "ISO-8859-1", "\305rr Sant\351", "UTF-8", "\303\205rr Sant\303\251", 0 },
1212 { "/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 },
1217 g_test_init (&argc, &argv, NULL);
1219 g_test_add_func ("/converter/basics", test_converter_basics);
1220 g_test_add_func ("/converter-input-stream/expander", test_expander);
1221 g_test_add_func ("/converter-input-stream/compressor", test_compressor);
1223 for (i = 0; i < G_N_ELEMENTS (compressor_tests); i++)
1224 g_test_add_data_func (compressor_tests[i].path, &compressor_tests[i], test_roundtrip);
1226 for (i = 0; i < G_N_ELEMENTS (truncation_tests); i++)
1227 g_test_add_data_func (truncation_tests[i].path, &truncation_tests[i], test_truncation);
1229 for (i = 0; i < G_N_ELEMENTS (charset_tests); i++)
1230 g_test_add_data_func (charset_tests[i].path, &charset_tests[i], test_charset);
1232 g_test_add_func ("/converter-stream/pollable", test_converter_pollable);
1233 g_test_add_func ("/converter-stream/leftover", test_converter_leftover);
1235 return g_test_run();