📄 swfdec_buffer.c
字号:
/* Swfdec * Copyright (C) 2003-2006 David Schleef <ds@schleef.org> * 2005-2006 Eric Anholt <eric@anholt.net> * 2006-2007 Benjamin Otte <otte@gnome.org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA */#ifndef HAVE_CONFIG_H#include "config.h"#endif#include <swfdec_buffer.h>#include <glib.h>#include <string.h>#include <swfdec_debug.h>#include <liboil/liboil.h>/*** gtk-doc ***//** * SECTION:SwfdecBuffer * @title: SwfdecBuffer * @short_description: memory region handling * * This section describes how memory is to be handled when interacting with the * Swfdec library. Memory regions are refcounted and passed using a * #SwfdecBuffer. If large memory segments need to be handled that may span * multiple buffers, Swfdec uses a #SwfdecBufferQueue. *//*** SwfdecBuffer ***//** * SwfdecBuffer: * @data: the data. read-only * @length: number of bytes in @data. read-only * * To allow for easy sharing of memory regions, #SwfdecBuffer was created. * Every buffer refers to a memory region and its size and takes care of * freeing that region when the buffer is no longer needed. They are * reference countedto make it easy to refer to the same region from various * independant parts of your code. Buffers also support some advanced * functionalities like extracting parts of the buffer using * swfdec_buffer_new_subbuffer() or using mmapped files with * swfdec_buffer_new_from_file() without the need for a different API. */GTypeswfdec_buffer_get_type (void){ static GType type_swfdec_buffer = 0; if (!type_swfdec_buffer) type_swfdec_buffer = g_boxed_type_register_static ("SwfdecBuffer", (GBoxedCopyFunc) swfdec_buffer_ref, (GBoxedFreeFunc) swfdec_buffer_unref); return type_swfdec_buffer;}/** * swfdec_buffer_new: * * Creates a new #SwfdecBuffer to be filled by the user. Use like this: * <informalexample><programlisting>SwfdecBuffer *buffer = swfdec_buffer_new (); * buffer->data = mydata; * buffer->length = mydata_length; * buffer->free = mydata_freefunc;</programlisting></informalexample> * * Returns: a new #SwfdecBuffer referencing nothing. **/SwfdecBuffer *swfdec_buffer_new (void){ SwfdecBuffer *buffer; buffer = g_new0 (SwfdecBuffer, 1); buffer->ref_count = 1; return buffer;}static voidswfdec_buffer_free_mem (SwfdecBuffer * buffer, void *priv){ g_free (buffer->data);}/** * swfdec_buffer_new_and_alloc: * @size: amount of bytes to allocate * * Creates a new buffer and allocates new memory of @size bytes to be used with * the buffer. * * Returns: a new #SwfdecBuffer with buffer->data pointing to new data **/SwfdecBuffer *swfdec_buffer_new_and_alloc (guint size){ SwfdecBuffer *buffer = swfdec_buffer_new (); buffer->data = g_malloc (size); buffer->length = size; buffer->free = swfdec_buffer_free_mem; return buffer;}/** * swfdec_buffer_new_and_alloc0: * @size: amount of bytes to allocate * * Createsa new buffer just like swfdec_buffer_new_and_alloc(), but ensures * that the returned data gets initialized to be 0. * * Returns: a new #SwfdecBuffer with buffer->data pointing to new data **/SwfdecBuffer *swfdec_buffer_new_and_alloc0 (guint size){ SwfdecBuffer *buffer = swfdec_buffer_new (); buffer->data = g_malloc0 (size); buffer->length = size; buffer->free = swfdec_buffer_free_mem; return buffer;}/** * swfdec_buffer_new_for_data: * @data: memory region allocated with g_malloc() * @size: size of @data in bytes * * Takes ownership of @data and creates a new buffer managing it. * * Returns: a new #SwfdecBuffer pointing to @data **/SwfdecBuffer *swfdec_buffer_new_for_data (unsigned char *data, guint size){ SwfdecBuffer *buffer; g_return_val_if_fail (data != NULL, NULL); g_return_val_if_fail (size > 0, NULL); buffer = swfdec_buffer_new (); buffer->data = data; buffer->length = size; buffer->free = swfdec_buffer_free_mem; return buffer;}static voidswfdec_buffer_free_subbuffer (SwfdecBuffer * buffer, void *priv){ swfdec_buffer_unref (buffer->parent);}/** * swfdec_buffer_new_subbuffer: * @buffer: #SwfdecBuffer managing the region of memory * @offset: starting offset into data * @length: amount of bytes to manage * * Creates a #SwfdecBuffer for managing a partial section of the memory pointed * to by @buffer. * * Returns: a new #SwfdecBuffer managing the indicated region. **/SwfdecBuffer *swfdec_buffer_new_subbuffer (SwfdecBuffer * buffer, guint offset, guint length){ SwfdecBuffer *subbuffer; g_return_val_if_fail (buffer != NULL, NULL); g_return_val_if_fail (offset + length <= buffer->length, NULL); subbuffer = swfdec_buffer_new (); if (buffer->parent) { swfdec_buffer_ref (buffer->parent); subbuffer->parent = buffer->parent; } else { swfdec_buffer_ref (buffer); subbuffer->parent = buffer; } g_assert (subbuffer->parent->parent == NULL); subbuffer->data = buffer->data + offset; subbuffer->length = length; subbuffer->free = swfdec_buffer_free_subbuffer; return subbuffer;}static voidswfdec_buffer_free_mapped (SwfdecBuffer * buffer, void *priv){ g_mapped_file_free (priv);}/** * swfdec_buffer_new_from_file: * @filename: file to read * @error: return location for a #GError or %NULL * * Tries to create a buffer for the given @filename using a #GMappedFile. If * the creation fails, %NULL is returned and @error is set. The error can be * any of the errors that are valid from g_mapped_file_new(). * * Returns: a new #SwfdecBuffer or %NULL on failure **/SwfdecBuffer *swfdec_buffer_new_from_file (const char *filename, GError **error){ GMappedFile *file; SwfdecBuffer *buffer; g_return_val_if_fail (filename != NULL, NULL); file = g_mapped_file_new (filename, FALSE, error); if (file == NULL) { return NULL; } buffer = swfdec_buffer_new (); buffer->data = (unsigned char *) g_mapped_file_get_contents (file), buffer->length = g_mapped_file_get_length (file); buffer->free = swfdec_buffer_free_mapped; buffer->priv = file; return buffer;}/** * swfdec_buffer_ref: * @buffer: a #SwfdecBuffer * * increases the reference count of @buffer by one. * * Returns: The passed in @buffer. **/SwfdecBuffer *swfdec_buffer_ref (SwfdecBuffer * buffer){ g_return_val_if_fail (buffer != NULL, NULL); g_return_val_if_fail (buffer->ref_count > 0, NULL); buffer->ref_count++; return buffer;}/** * swfdec_buffer_unref: * @buffer: a #SwfdecBuffer * * Decreases the reference count of @buffer by one. If no reference to this * buffer exists anymore, the buffer and the memory it manages are freed. **/voidswfdec_buffer_unref (SwfdecBuffer * buffer){ g_return_if_fail (buffer != NULL); g_return_if_fail (buffer->ref_count > 0); buffer->ref_count--; if (buffer->ref_count == 0) { if (buffer->free) buffer->free (buffer, buffer->priv); g_free (buffer); }}/*** SwfdecBufferQueue ***//** * SwfdecBufferQueue: * * A #SwfdecBufferQueue is a queue of continuous buffers that allows reading * its data in chunks of pre-defined sizes. It is used to transform a data * stream that was provided by buffers of random sizes to buffers of the right
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -