Merge branch '0.8'
[swfdec.git] / test / swfdec_test_buffer.c
blob0fe124e371b1761918df9a72489e4545e73efa7e
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);
184 found = memchr (buffer->buffer->data, c, buffer->buffer->length);
185 if (found)
186 *retval = swfdec_as_value_from_integer (cx, found - buffer->buffer->data);
187 else
188 *retval = swfdec_as_value_from_integer (cx, -1);
191 SWFDEC_TEST_FUNCTION ("Buffer_load", swfdec_test_buffer_load)
192 void
193 swfdec_test_buffer_load (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
194 SwfdecAsValue *argv, SwfdecAsValue *retval)
196 SwfdecBuffer *b;
197 SwfdecTestBuffer *buffer;
198 const char *filename;
199 GError *error = NULL;
201 SWFDEC_AS_CHECK (0, NULL, "s", &filename);
203 b = swfdec_buffer_new_from_file (filename, &error);
204 if (b == NULL) {
205 swfdec_test_throw (cx, "%s", error->message);
206 g_error_free (error);
207 return;
210 buffer = swfdec_test_buffer_new (cx, b);
211 SWFDEC_AS_VALUE_SET_OBJECT (retval, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (buffer)));
214 SWFDEC_TEST_FUNCTION ("Buffer_sub", swfdec_test_buffer_sub)
215 void
216 swfdec_test_buffer_sub (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
217 SwfdecAsValue *argv, SwfdecAsValue *retval)
219 SwfdecBuffer *b;
220 SwfdecTestBuffer *buffer, *sub;
221 guint offset, length = 0;
223 SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_BUFFER, &buffer, "i|i", &offset, &length);
225 SWFDEC_AS_VALUE_SET_NULL (retval);
226 if (offset >= buffer->buffer->length)
227 return;
229 if (length == 0)
230 length = buffer->buffer->length - offset;
232 b = swfdec_buffer_new_subbuffer (buffer->buffer, offset, length);
233 sub = swfdec_test_buffer_new (cx, b);
234 SWFDEC_AS_VALUE_SET_OBJECT (retval, swfdec_as_relay_get_as_object (SWFDEC_AS_RELAY (sub)));
237 SWFDEC_TEST_FUNCTION ("Buffer_toString", swfdec_test_buffer_toString)
238 void
239 swfdec_test_buffer_toString (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
240 SwfdecAsValue *argv, SwfdecAsValue *retval)
242 SwfdecBuffer *b;
243 SwfdecTestBuffer *buffer;
244 const char *end;
245 char *s;
247 SWFDEC_AS_CHECK (SWFDEC_TYPE_TEST_BUFFER, &buffer, "");
249 b = buffer->buffer;
250 if (g_utf8_validate ((const char *) b->data, b->length, &end)) {
251 s = g_strndup ((const char *) b->data, b->length);
252 } else if ((size_t) (end - (char *) b->data) == b->length - 1) {
253 s = g_strdup ((const char *) b->data);
254 } else {
255 s = NULL;
257 if (s == NULL)
258 s = g_strdup ("[binary Buffer]");
259 SWFDEC_AS_VALUE_SET_STRING (retval, swfdec_as_context_give_string (cx, s));
262 SwfdecBuffer *
263 swfdec_test_buffer_from_args (SwfdecAsContext *cx, guint argc, SwfdecAsValue *argv)
265 SwfdecBufferQueue *queue;
266 SwfdecBuffer *buffer;
267 guint i;
269 queue = swfdec_buffer_queue_new ();
270 for (i = 0; i < argc; i++) {
271 SwfdecBuffer *b = NULL;
272 if (SWFDEC_AS_VALUE_IS_OBJECT (argv[i])) {
273 SwfdecAsObject *o = SWFDEC_AS_VALUE_GET_OBJECT (argv[i]);
274 if (SWFDEC_IS_TEST_BUFFER (o->relay))
275 b = swfdec_buffer_ref (SWFDEC_TEST_BUFFER (o->relay)->buffer);
276 } else if (SWFDEC_AS_VALUE_IS_NUMBER (argv[i])) {
277 b = swfdec_buffer_new (1);
278 b->data[0] = swfdec_as_value_to_integer (cx, argv[i]);
280 if (b == NULL) {
281 const char *s = swfdec_as_value_to_string (cx, argv[i]);
282 gsize len = strlen (s);
283 /* no terminating 0 byte on purpose here - use new Buffer (string, 0); to get that */
284 b = swfdec_buffer_new (len);
285 memcpy (b->data, s, len);
287 swfdec_buffer_queue_push (queue, b);
289 i = swfdec_buffer_queue_get_depth (queue);
290 buffer = swfdec_buffer_queue_pull (queue, i);
291 swfdec_buffer_queue_unref (queue);
293 return buffer;
296 SWFDEC_TEST_FUNCTION ("Buffer", swfdec_test_buffer_create)
297 void
298 swfdec_test_buffer_create (SwfdecAsContext *cx, SwfdecAsObject *object, guint argc,
299 SwfdecAsValue *argv, SwfdecAsValue *retval)
301 SwfdecTestBuffer *buffer;
303 if (!swfdec_as_context_is_constructing (cx))
304 return;
306 buffer = g_object_new (SWFDEC_TYPE_TEST_BUFFER, "context", cx, NULL);
307 buffer->buffer = swfdec_test_buffer_from_args (cx, argc, argv);
308 swfdec_as_object_set_relay (object, SWFDEC_AS_RELAY (buffer));
310 SWFDEC_AS_VALUE_SET_OBJECT (retval, object);