1
2 #ifdef HAVE_CONFIG_H
3 #include "config.h"
4 #endif
5
6 #include <schroedinger/schrobuffer.h>
7 #include <schroedinger/schrodebug.h>
8 #include <schroedinger/schroorc.h>
9 #include <string.h>
10 #include <orc/orc.h>
11
12 static void schro_buffer_free_mem (SchroBuffer * buffer, void *);
13 static void schro_buffer_free_subbuffer (SchroBuffer * buffer, void *priv);
14
15
16 SchroBuffer *
schro_buffer_new(void)17 schro_buffer_new (void)
18 {
19 SchroBuffer *buffer;
20
21 buffer = schro_malloc0 (sizeof (SchroBuffer));
22 buffer->ref_count = 1;
23 return buffer;
24 }
25
26 SchroBuffer *
schro_buffer_new_and_alloc(int size)27 schro_buffer_new_and_alloc (int size)
28 {
29 SchroBuffer *buffer = schro_buffer_new ();
30
31 buffer->data = schro_malloc (size);
32 buffer->length = size;
33 buffer->free = schro_buffer_free_mem;
34
35 SCHRO_DEBUG ("%p %i", buffer, size);
36
37 return buffer;
38 }
39
40 SchroBuffer *
schro_buffer_new_with_data(void * data,int size)41 schro_buffer_new_with_data (void *data, int size)
42 {
43 SchroBuffer *buffer = schro_buffer_new ();
44
45 buffer->data = data;
46 buffer->length = size;
47
48 return buffer;
49 }
50
51 SchroBuffer *
schro_buffer_new_subbuffer(SchroBuffer * buffer,int offset,int length)52 schro_buffer_new_subbuffer (SchroBuffer * buffer, int offset, int length)
53 {
54 SchroBuffer *subbuffer = schro_buffer_new ();
55
56 if (buffer->parent) {
57 schro_buffer_ref (buffer->parent);
58 subbuffer->parent = buffer->parent;
59 } else {
60 schro_buffer_ref (buffer);
61 subbuffer->parent = buffer;
62 }
63 subbuffer->data = buffer->data + offset;
64 subbuffer->length = length;
65 subbuffer->free = schro_buffer_free_subbuffer;
66
67 return subbuffer;
68 }
69
70 SchroBuffer *
schro_buffer_ref(SchroBuffer * buffer)71 schro_buffer_ref (SchroBuffer * buffer)
72 {
73 buffer->ref_count++;
74 return buffer;
75 }
76
77 void
schro_buffer_unref(SchroBuffer * buffer)78 schro_buffer_unref (SchroBuffer * buffer)
79 {
80 SCHRO_ASSERT (buffer->ref_count > 0);
81 buffer->ref_count--;
82 if (buffer->ref_count == 0) {
83 SCHRO_DEBUG ("free %p", buffer);
84 if (buffer->free)
85 buffer->free (buffer, buffer->priv);
86 if (buffer->tag)
87 schro_tag_free (buffer->tag);
88 schro_free (buffer);
89 }
90 }
91
92 static void
schro_buffer_free_mem(SchroBuffer * buffer,void * priv)93 schro_buffer_free_mem (SchroBuffer * buffer, void *priv)
94 {
95 schro_free (buffer->data);
96 }
97
98 static void
schro_buffer_free_subbuffer(SchroBuffer * buffer,void * priv)99 schro_buffer_free_subbuffer (SchroBuffer * buffer, void *priv)
100 {
101 schro_buffer_unref (buffer->parent);
102 buffer->parent = NULL;
103 }
104
105 SchroBuffer *
schro_buffer_dup(SchroBuffer * buffer)106 schro_buffer_dup (SchroBuffer * buffer)
107 {
108 SchroBuffer *dup;
109
110 dup = schro_buffer_new_and_alloc (buffer->length);
111 orc_memcpy (dup->data, buffer->data, buffer->length);
112
113 return dup;
114 }
115
116
117 /**
118 * schro_tag_new:
119 * @value: initial value for the tag
120 * @free_func: function to free value, may be NULL. this function must
121 * allow being called as free_func(NULL).
122 *
123 * Returns: An a decoder tag structure, with an initial value
124 */
125 SchroTag *
schro_tag_new(void * value,void (* free_func)(void *))126 schro_tag_new (void *value, void (*free_func) (void *))
127 {
128 SchroTag *tag = schro_malloc0 (sizeof (*tag));
129
130 if (!tag) {
131 if (free_func) {
132 free_func (value);
133 }
134 return NULL;
135 }
136 tag->free = free_func;
137 tag->value = value;
138 return tag;
139 }
140
141 /**
142 * schro_tag_free:
143 *
144 * Frees storage associated with @tag. Calls tag's free_func to free
145 * private data if free_func is non zero.
146 */
147 void
schro_tag_free(SchroTag * tag)148 schro_tag_free (SchroTag * tag)
149 {
150 if (tag->free) {
151 tag->free (tag->value);
152 }
153 schro_free (tag);
154 }
155