Merge branch '0.8'
[swfdec.git] / test / swfdec_test_buffer.c
blob07928c9e5505b78c7bdc892f094825428bfdb564
1 /* Swfdec
2 * Copyright (C) 2008 Benjamin Otte <otte@gnome.org>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library 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. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301 USA
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
24 #include <string.h>
25 #include <unistd.h>
27 #include "swfdec_test_buffer.h"
28 #include "swfdec_test_function.h"
29 #include "swfdec_test_utils.h"
31 SwfdecTestBuffer *
32 swfdec_test_buffer_new (SwfdecAsContext *context, SwfdecBuffer *buffer)
34 SwfdecTestBuffer *ret;
35 SwfdecAsObject *object;
37 ret = g_object_new (SWFDEC_TYPE_TEST_BUFFER, "context", context, NULL);
38 ret->buffer = buffer;
40 object = swfdec_as_object_new (context, NULL);
41 swfdec_as_object_set_constructor_by_name (object,
42 swfdec_as_context_get_string (context, "Buffer"), NULL);
43 swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (ret));
45 return ret;
48 /*** SWFDEC_TEST_BUFFER ***/
50 G_DEFINE_TYPE (SwfdecTestBuffer, swfdec_test_buffer, SWFDEC_TYPE_AS_RELAY)
52 static void
53 swfdec_test_buffer_dispose (GObject *object)
55 SwfdecTestBuffer *buffer = SWFDEC_TEST_BUFFER (object);
57 if (buffer->buffer) {
58 swfdec_buffer_unref (buffer->buffer);
59 buffer->buffer = NULL;
62 G_OBJECT_CLASS (swfdec_test_buffer_parent_class)->dispose (object);
65 static void
66 swfdec_test_buffer_class_init (SwfdecTestBufferClass *klass)
68 GObjectClass *object_class = G_OBJECT_CLASS (klass);
70 object_class->dispose = swfdec_test_buffer_dispose;
73 static void
74 swfdec_test_buffer_init (SwfdecTestBuffer *buffer)
78 /*** AS CODE ***/
80 static char *
81 swfdec_test_diff_buffers (SwfdecBuffer *buf1, SwfdecBuffer *buf2, GError **error)
83 const char *command[] = { "diff", "-u", NULL, NULL, NULL };
84 char *file1, *file2, *diff;
85 int fd;
87 /* shortcut the (hopefully) common case of equality */
88 if (buf1->length == buf2->length &&
89 memcmp (buf1->data, buf2->data, buf1->length) == 0)
90 return NULL;
92 /* write the first buffer to a temporary file */
93 fd = g_file_open_tmp (NULL, &file1, error);
94 if (fd < 0)
95 return NULL;
96 if (write (fd, buf1->data, buf1->length) != (int) buf1->length) {
97 close (fd);
98 g_free (file1);
99 g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
100 "Could not write data to temporary file");
101 return NULL;
103 close (fd);
105 /* write the second buffer to a temporary file */
106 fd = g_file_open_tmp (NULL, &file2, error);
107 if (fd < 0) {
108 g_free (file1);
109 return NULL;
111 if (write (fd, buf2->data, buf2->length) != (int) buf2->length) {
112 close (fd);
113 g_free (file1);
114 g_free (file2);
115 g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
116 "Could not write data to temporary file");
117 return NULL;
119 close (fd);
121 /* run diff command */
122 command[2] = file1;
123 command[3] = file2;
124 if (!g_spawn_sync (NULL, (char **) command, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
125 &diff, NULL, NULL, error)) {
126 unlink (file1);
127 unlink (file2);
128 g_free (file1);
129 g_free (file2);
130 return NULL;
132 unlink (file1);
133 unlink (file2);
134 g_free (file1);
135 g_free (file2);
136 return diff;
139 SWFDEC_TEST_FUNCTION ("Buffer_diff", swfdec_test_buffer_diff)
140 void
141 swfdec_test_buffer_diff (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
142 SwfdecAsValue *argv, SwfdecAsValue *retval)
144 SwfdecTestBuffer *buffer, *compare = NULL;
145 SwfdecAsObject *compare_object;
146 GError *error = NULL;
147 char *ret;
149 SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_BUFFER, &buffer, "|o", &compare_object);
151 if (compare_object == NULL || !SWFDEC_IS_TEST_BUFFER (compare_object->relay)) {
152 swfdec_test_throw (cx, "must pass a buffer to Buffer.diff");
153 return;
155 compare = SWFDEC_TEST_BUFFER (compare_object->relay);
157 ret = swfdec_test_diff_buffers (compare->buffer, buffer->buffer, &error);
158 if (ret) {
159 SWFDEC_AS_VALUE_SET_STRING (retval,
160 swfdec_as_context_give_string (cx, ret));
161 } else {
162 if (error) {
163 swfdec_test_throw (cx, "s", error->message);
164 g_error_free (error);
165 } else {
166 SWFDEC_AS_VALUE_SET_STRING (retval,
167 swfdec_as_context_get_string (cx, ""));
172 SWFDEC_TEST_FUNCTION ("Buffer_find", swfdec_test_buffer_find)
173 void
174 swfdec_test_buffer_find (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
175 SwfdecAsValue *argv, SwfdecAsValue *retval)
177 int c;
178 SwfdecTestBuffer *buffer;
179 guchar *found;
181 SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_BUFFER, &buffer, "i", &c);
183 swfdec_as_value_set_integer (cx, retval, -1);
185 found = memchr (buffer->buffer->data, c, buffer->buffer->length);
186 if (found)
187 swfdec_as_value_set_integer (cx, retval, found - buffer->buffer->data);
190 SWFDEC_TEST_FUNCTION ("Buffer_load", swfdec_test_buffer_load)
191 void
192 swfdec_test_buffer_load (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
193 SwfdecAsValue *argv, SwfdecAsValue *retval)
195 SwfdecBuffer *b;
196 SwfdecTestBuffer *buffer;
197 const char *filename;
198 GError *error = NULL;
200 SWFDEC_AS_CHECK (0, NULL, "s", &filename);
202 b = swfdec_buffer_new_from_file (filename, &error);
203 if (b == NULL) {
204 swfdec_test_throw (cx, "%s", error->message);
205 g_error_free (error);
206 return;
209 buffer = swfdec_test_buffer_new (cx, b);
210 SWFDEC_AS_VALUE_SET_OBJECT (retval, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (buffer)));
213 SWFDEC_TEST_FUNCTION ("Buffer_sub", swfdec_test_buffer_sub)
214 void
215 swfdec_test_buffer_sub (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
216 SwfdecAsValue *argv, SwfdecAsValue *retval)
218 SwfdecBuffer *b;
219 SwfdecTestBuffer *buffer, *sub;
220 guint offset, length = 0;
222 SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_BUFFER, &buffer, "i|i", &offset, &length);
224 SWFDEC_AS_VALUE_SET_NULL (retval);
225 if (offset >= buffer->buffer->length)
226 return;
228 if (length == 0)
229 length = buffer->buffer->length - offset;
231 b = swfdec_buffer_new_subbuffer (buffer->buffer, offset, length);
232 sub = swfdec_test_buffer_new (cx, b);
233 SWFDEC_AS_VALUE_SET_OBJECT (retval, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sub)));
236 SWFDEC_TEST_FUNCTION ("Buffer_toString", swfdec_test_buffer_toString)
237 void
238 swfdec_test_buffer_toString (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
239 SwfdecAsValue *argv, SwfdecAsValue *retval)
241 SwfdecBuffer *b;
242 SwfdecTestBuffer *buffer;
243 const char *end;
244 char *s;
246 SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_BUFFER, &buffer, "");
248 b = buffer->buffer;
249 if (g_utf8_validate ((const char *) b->data, b->length, &end)) {
250 s = g_strndup ((const char *) b->data, b->length);
251 } else if ((size_t) (end - (char *) b->data) == b->length - 1) {
252 s = g_strdup ((const char *) b->data);
253 } else {
254 s = NULL;
256 if (s == NULL)
257 s = g_strdup ("[binary Buffer]");
258 SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_give_string (cx, s));
261 SwfdecBuffer *
262 swfdec_test_buffer_from_args (SwfdecAsContext *cx, guint argc, SwfdecAsValue *argv)
264 SwfdecBufferQueue *queue;
265 SwfdecBuffer *buffer;
266 guint i;
268 queue = swfdec_buffer_queue_new ();
269 for (i = 0; i < argc; i++) {
270 SwfdecBuffer *b = NULL;
271 if (SWFDEC_AS_VALUE_IS_OBJECT (&argv[i])) {
272 SwfdecAsObject *o = SWFDEC_AS_VALUE_GET_OBJECT (&argv[i]);
273 if (SWFDEC_IS_TEST_BUFFER (o->relay))
274 b = swfdec_buffer_ref (SWFDEC_TEST_BUFFER (o->relay)->buffer);
275 } else if (SWFDEC_AS_VALUE_IS_NUMBER (&argv[i])) {
276 b = swfdec_buffer_new (1);
277 b->data[0] = swfdec_as_value_to_integer (cx, &argv[i]);
279 if (b == NULL) {
280 const char *s = swfdec_as_value_to_string (cx, &argv[i]);
281 gsize len = strlen (s);
282 /* no terminating 0 byte on purpose here - use new Buffer (string, 0); to get that */
283 b = swfdec_buffer_new (len);
284 memcpy (b->data, s, len);
286 swfdec_buffer_queue_push (queue, b);
288 i = swfdec_buffer_queue_get_depth (queue);
289 buffer = swfdec_buffer_queue_pull (queue, i);
290 swfdec_buffer_queue_unref (queue);
292 return buffer;
295 SWFDEC_TEST_FUNCTION ("Buffer", swfdec_test_buffer_create)
296 void
297 swfdec_test_buffer_create (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
298 SwfdecAsValue *argv, SwfdecAsValue *retval)
300 SwfdecTestBuffer *buffer;
302 if (!swfdec_as_context_is_constructing (cx))
303 return;
305 buffer = g_object_new (SWFDEC_TYPE_TEST_BUFFER, "context", cx, NULL);
306 buffer->buffer = swfdec_test_buffer_from_args (cx, argc, argv);
307 swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (buffer));
309 SWFDEC_AS_VALUE_SET_OBJECT (retval, object);