2 * Copyright © 2009 Codethink Limited
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published
6 * by the Free Software Foundation; either version 2 of the licence or (at
7 * your option) any later version.
9 * See the included COPYING file for more information.
11 * Author: Ryan Lortie <desrt@desrt.ca>
17 #define MAX_PIECE_SIZE 100
23 char buffer
[MAX_PIECE_SIZE
* 2];
26 symbols
= g_test_rand_int_range (1, MAX_PIECE_SIZE
+ 1);
30 gint c
= g_test_rand_int_range (0, 30);
47 buffer
[i
++] = c
+ 'a';
51 g_assert_cmpint (i
, <=, sizeof buffer
);
54 return g_strndup (buffer
, i
);
63 pieces
= g_test_rand_int_range (0, MAX_PIECES
+ 1);
64 array
= g_new (char *, pieces
+ 1);
68 array
[pieces
] = cook_piece ();
75 GInputStream parent_instance
;
77 gboolean built_to_fail
;
84 typedef GInputStreamClass SleepyStreamClass
;
86 GType
sleepy_stream_get_type (void);
88 G_DEFINE_TYPE (SleepyStream
, sleepy_stream
, G_TYPE_INPUT_STREAM
)
91 sleepy_stream_read (GInputStream
*stream
,
94 GCancellable
*cancellable
,
97 SleepyStream
*sleepy
= (SleepyStream
*) stream
;
99 if (sleepy
->pieces
[sleepy
->index
] == NULL
)
101 if (sleepy
->built_to_fail
)
103 g_set_error (error
, G_IO_ERROR
, G_IO_ERROR_FAILED
, "fail");
111 if (!sleepy
->current
)
112 sleepy
->current
= sleepy
->pieces
[sleepy
->index
++];
114 length
= MIN (strlen (sleepy
->current
), length
);
115 memcpy (buffer
, sleepy
->current
, length
);
117 sleepy
->current
+= length
;
118 if (*sleepy
->current
== '\0')
119 sleepy
->current
= NULL
;
126 sleepy_stream_init (SleepyStream
*sleepy
)
128 sleepy
->pieces
= cook_pieces ();
129 sleepy
->built_to_fail
= FALSE
;
134 sleepy_stream_finalize (GObject
*object
)
136 SleepyStream
*sleepy
= (SleepyStream
*) object
;
138 g_strfreev (sleepy
->pieces
);
139 G_OBJECT_CLASS (sleepy_stream_parent_class
)
144 sleepy_stream_class_init (SleepyStreamClass
*class)
146 G_OBJECT_CLASS (class)->finalize
= sleepy_stream_finalize
;
147 class->read_fn
= sleepy_stream_read
;
149 /* no read_async implementation.
150 * main thread will sleep while read runs in a worker.
154 static SleepyStream
*
155 sleepy_stream_new (void)
157 return g_object_new (sleepy_stream_get_type (), NULL
);
161 read_line (GDataInputStream
*stream
,
169 str
= g_data_input_stream_read_line (stream
, &length
, NULL
, error
);
174 g_assert (strstr (str
, eol
) == NULL
);
175 g_assert (strlen (str
) == length
);
177 g_string_append (string
, str
);
178 g_string_append (string
, eol
);
185 build_comparison (GString
*str
,
186 SleepyStream
*stream
)
188 /* build this for comparison */
191 for (i
= 0; stream
->pieces
[i
]; i
++)
192 g_string_append (str
, stream
->pieces
[i
]);
194 if (str
->len
&& str
->str
[str
->len
- 1] != '\n')
195 g_string_append_c (str
, '\n');
202 SleepyStream
*stream
= sleepy_stream_new ();
203 GDataInputStream
*data
;
204 GError
*error
= NULL
;
208 one
= g_string_new (NULL
);
209 two
= g_string_new (NULL
);
211 data
= g_data_input_stream_new (G_INPUT_STREAM (stream
));
212 g_data_input_stream_set_newline_type (data
, G_DATA_STREAM_NEWLINE_TYPE_LF
);
213 build_comparison (one
, stream
);
215 while (read_line (data
, two
, "\n", &error
));
217 g_assert_cmpstr (one
->str
, ==, two
->str
);
218 g_string_free (one
, TRUE
);
219 g_string_free (two
, TRUE
);
220 g_object_unref (stream
);
221 g_object_unref (data
);
224 static GDataInputStream
*data
;
225 static GString
*one
, *two
;
226 static GMainLoop
*loop
;
227 static const gchar
*eol
;
230 asynch_ready (GObject
*object
,
231 GAsyncResult
*result
,
234 GError
*error
= NULL
;
238 g_assert (data
== G_DATA_INPUT_STREAM (object
));
240 str
= g_data_input_stream_read_line_finish (data
, result
, &length
, &error
);
244 g_main_loop_quit (loop
);
246 g_error_free (error
);
250 g_assert (length
== strlen (str
));
251 g_string_append (two
, str
);
252 g_string_append (two
, eol
);
256 g_data_input_stream_read_line_async (data
, 0, NULL
, asynch_ready
, NULL
);
264 SleepyStream
*sleepy
= sleepy_stream_new ();
266 data
= g_data_input_stream_new (G_INPUT_STREAM (sleepy
));
267 one
= g_string_new (NULL
);
268 two
= g_string_new (NULL
);
271 build_comparison (one
, sleepy
);
272 g_data_input_stream_read_line_async (data
, 0, NULL
, asynch_ready
, NULL
);
273 g_main_loop_run (loop
= g_main_loop_new (NULL
, FALSE
));
275 g_assert_cmpstr (one
->str
, ==, two
->str
);
276 g_string_free (one
, TRUE
);
277 g_string_free (two
, TRUE
);
278 g_object_unref (sleepy
);
279 g_object_unref (data
);
283 main (int argc
, char **argv
)
285 g_test_init (&argc
, &argv
, NULL
);
286 g_test_bug_base ("http://bugzilla.gnome.org/");
288 g_test_add_func ("/filter-stream/input", test
);
289 g_test_add_func ("/filter-stream/async", asynch
);