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