fix build for --disable-gtk-doc
[swfdec.git] / swfdec / swfdec_constant_pool.c
blobc7df4f9ca9361d396eaf0cd0a180dbc7c34d1395
1 /* Swfdec
2 * Copyright (C) 2007-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 "swfdec_constant_pool.h"
25 #include "swfdec_as_strings.h"
26 #include "swfdec_bits.h"
27 #include "swfdec_debug.h"
29 struct _SwfdecConstantPool {
30 SwfdecAsContext * context; /* context we are attached to or NULL */
31 SwfdecBuffer * buffer; /* the buffer the strings were read from */
32 guint refcount; /* reference count */
33 guint n_strings; /* number of strings */
34 char * strings[1]; /* n_strings strings */
37 /**
38 * swfdec_constant_pool_new:
39 * @context: a context to attach strings to or %NULL
40 * @buffer: buffer to read constant pool from
41 * @version: the Flash version to use when reading the strings
43 * Creates a new constant pool from the given @buffer. If the buffer is in the
44 * wrong format, %NULL is returned. If a @context was given, the strings are
45 * added to the context. This means the strings in the pool will be
46 * garbage-collected already. When using a non-%NULL @context, the pool does
47 * will not add a reference to the context. It is your responsibility to hold a
48 * reference to the context while you use the pool.
50 * Returns: a new constant pool or %NULL
51 **/
52 SwfdecConstantPool *
53 swfdec_constant_pool_new (SwfdecAsContext *context, SwfdecBuffer *buffer, guint version)
55 guint i, n;
56 gsize size;
57 SwfdecBits bits;
58 SwfdecConstantPool *pool;
60 g_return_val_if_fail (context == NULL || SWFDEC_IS_AS_CONTEXT (context), NULL);
61 g_return_val_if_fail (buffer != NULL, NULL);
63 /* try to find the pool in the context's cache */
64 if (context) {
65 pool = g_hash_table_lookup (context->constant_pools, buffer->data);
66 if (pool)
67 return swfdec_constant_pool_ref (pool);
70 swfdec_bits_init (&bits, buffer);
72 n = swfdec_bits_get_u16 (&bits);
74 size = sizeof (SwfdecConstantPool) + (MAX (1, n) - 1) * sizeof (char *);
75 pool = g_slice_alloc0 (size);
76 pool->n_strings = n;
77 for (i = 0; i < n && swfdec_bits_left (&bits); i++) {
78 pool->strings[i] = swfdec_bits_get_string (&bits, version);
79 if (pool->strings[i] == NULL) {
80 SWFDEC_ERROR ("constant pool index %u invalid, using empty string instead.", i);
81 pool->strings[i] = context ? (char *) SWFDEC_AS_STR_EMPTY : g_strdup ("");
82 } else if (context) {
83 pool->strings[i] = (char *) swfdec_as_context_give_string (context, pool->strings[i]);
86 if (swfdec_bits_left (&bits)) {
87 SWFDEC_WARNING ("constant pool didn't consume whole buffer (%u bytes leftover)", swfdec_bits_left (&bits) / 8);
89 pool->buffer = swfdec_buffer_ref (buffer);
90 pool->refcount = 1;
91 /* put pool into the context's cache */
92 if (context) {
93 pool->context = context;
94 g_hash_table_insert (context->constant_pools, buffer->data, pool);
95 swfdec_constant_pool_ref (pool);
97 return pool;
101 * swfdec_constant_pool_ref:
102 * @pool: a constant pool
104 * Increases the constant pool's reference by one.
106 * Returns: the passed in @pool.
108 SwfdecConstantPool *
109 swfdec_constant_pool_ref (SwfdecConstantPool *pool)
111 g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), NULL);
113 pool->refcount++;
115 return pool;
119 * swfdec_constant_pool_unref:
120 * @pool: the pool to unref
122 * Removes a reference from the pool. If no more references are left, the pool
123 * will be freed.
125 void
126 swfdec_constant_pool_unref (SwfdecConstantPool *pool)
128 g_return_if_fail (SWFDEC_IS_CONSTANT_POOL (pool));
129 g_return_if_fail (pool->refcount > 0);
131 pool->refcount--;
132 if (pool->refcount)
133 return;
135 if (pool->context == NULL) {
136 guint i;
137 for (i = 0; i < pool->n_strings; i++) {
138 g_free (pool->strings[i]);
141 swfdec_buffer_unref (pool->buffer);
142 g_slice_free1 (sizeof (SwfdecConstantPool) + (MAX (1, pool->n_strings) - 1) * sizeof (char *), pool);
145 gboolean
146 swfdec_constant_pool_collect (SwfdecConstantPool *pool)
148 if (pool->refcount) {
149 swfdec_constant_pool_unref (pool);
150 return TRUE;
152 return FALSE;
156 * swfdec_constant_pool_size:
157 * @pool: a pool
159 * Queries the number of strings in this pool.
161 * Returns: The number of strings in this @pool
163 guint
164 swfdec_constant_pool_size (SwfdecConstantPool *pool)
166 g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), 0);
168 return pool->n_strings;
172 * swfdec_constant_pool_get:
173 * @pool: a pool
174 * @i: index of the string to get
176 * Gets the requested string from the pool. The index must not excess the
177 * number of elements in the pool. If the constant pool was created with a
178 * context attached, the returned string will be garbage-collected already.
180 * Returns: the string at position @i
182 const char *
183 swfdec_constant_pool_get (SwfdecConstantPool *pool, guint i)
185 g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), NULL);
186 g_return_val_if_fail (i < pool->n_strings, NULL);
188 return pool->strings[i];
192 * swfdec_constant_pool_get_buffer:
193 * @pool: a constant pool
195 * Gets the buffer the pool was created from
197 * Returns: the buffer this pool was created from.
199 SwfdecBuffer *
200 swfdec_constant_pool_get_buffer (SwfdecConstantPool *pool)
202 g_return_val_if_fail (SWFDEC_IS_CONSTANT_POOL (pool), NULL);
204 return pool->buffer;