Add missing files
[gmpc-magnatune.git] / src / axl / axl_factory.c
blob5f12027ffd2567e20afb39b98c111345dddcf6f0
1 /**
2 * LibAxl: Another XML library
3 * Copyright (C) 2006 Advanced Software Production Line, S.L.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this program; if not, write to the Free
17 * Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 * 02111-1307 USA
20 * You may find a copy of the license under this software is released
21 * at COPYING file. This is LGPL software: you are welcome to
22 * develop proprietary applications using this library without any
23 * royalty or fee but returning back any change, improvement or
24 * addition in the form of source code, project image, documentation
25 * patches, etc.
27 * For commercial support on build XML enabled solutions contact us:
29 * Postal address:
30 * Advanced Software Production Line, S.L.
31 * C/ Dr. Michavila NÂș 14
32 * Coslada 28820 Madrid
33 * Spain
35 * Email address:
36 * info@aspl.es - http://fact.aspl.es
38 #include <axl.h>
40 typedef struct _axlItemBlock axlItemBlock;
42 struct _axlItemBlock {
43 axlPointer items;
44 axlItemBlock * next;
47 struct _axlFactory {
48 int count;
49 int step;
50 int type_size;
51 axlItemBlock * block;
54 /**
55 * @internal Allows to create a new factory, for the provided
56 * type.
58 * This will cause the function to return an axlFactory with blocks
59 * initialized.
61 * @param type The type to initialize the factory created.
63 * @return A newly allocated factory.
65 axlFactory * axl_factory_create (int size_of_type)
67 axlFactory * result;
69 result = axl_new (axlFactory, 1);
70 result->type_size = size_of_type;
71 result->step = 256 / size_of_type;
73 result->block = axl_new (axlItemBlock, 1);
74 result->block->items = calloc (result->step, size_of_type);
76 return result;
78 } /* end axl_factory_create */
80 /**
81 * @internal Function that allows to get a block from the factory.
83 * @param factory The factory that is being used to allocate more
84 * memory.
86 * @return A reference to newly allocated memory.
88 axlPointer axl_factory_get (axlFactory * factory)
90 axlItemBlock * block;
92 /* update factory allocated elements */
93 factory->count++;
95 if ((factory->count) > factory->step) {
97 if (factory->step == (256 / factory->type_size))
98 factory->step = 512 / factory->type_size;
99 else if (factory->step == (512 / factory->type_size))
100 factory->step = 1024 / factory->type_size;
101 else if (factory->step == (1024 / factory->type_size))
102 factory->step = 2048 / factory->type_size;
104 block = axl_new (axlItemBlock, 1);
105 block->items = calloc (factory->step, factory->type_size);
106 factory->count = 1;
108 block->next = factory->block;
109 factory->block = block;
111 } /* end if */
113 return ((char *)factory->block->items) + ((factory->count - 1) * factory->type_size);
114 } /* end if */
116 /**
117 * @internal Allows to deallocate the axlFactory created.
119 * @param factory
121 void axl_factory_free (axlFactory * factory)
123 axlItemBlock * block;
124 axlItemBlock * aux;
126 /* do nothing if null received */
127 if (factory == NULL)
128 return;
130 /* get the first block */
131 block = factory->block;
133 while (block != NULL) {
135 /* get a reference to the next */
136 aux = block->next;
138 /* free items and the block */
139 axl_free (block->items);
140 axl_free (block);
142 /* get the next */
143 block = aux;
145 } /* end while */
147 axl_free (factory);
149 return;
152 typedef struct _axlStrBlock axlStrBlock;
154 struct _axlStrBlock {
155 char * buffer;
156 axlStrBlock * next;
159 struct _axlStrFactory {
160 int index;
161 int step;
162 int size;
163 axlStrBlock * block;
166 /**
167 * @internal Allows to create an string factory, an abstraction that
168 * allows to allocate string chuncks in a memory efficient way,
169 * according to the Axl Library allocation pattern.
171 * @return A reference to the newly allocated axlStrFactory.
173 axlStrFactory * axl_string_factory_create ()
175 axlStrFactory * factory;
177 /* create a factory */
178 factory = axl_new (axlStrFactory, 1);
179 factory->step = 1024;
180 factory->size = 1024;
181 factory->block = axl_new (axlStrBlock, 1);
182 factory->block->buffer = axl_new (char, factory->size);
184 /* return factory created */
185 return factory;
188 /**
189 * @internal Allows to allocate a new chunk from the axlStrFactory.
191 * @param factory The factory that will be used to allocate an string.
193 * @param size The size to allocate. The amount of memory to allocate
194 * to hold the string.
196 * @return A pointer to allocated memory to hold the exact amount of
197 * memory requested.
199 char * axl_string_factory_alloc (axlStrFactory * factory, int size)
201 axlStrBlock * block;
202 char * result;
204 /* check that we could satisfy the size request with current
205 * block */
206 if ((factory->size - factory->index - 1) < size ) {
208 /* alloc a new block */
209 block = axl_new (axlStrBlock, 1);
211 /* ensure the block can hold the string */
212 if (size > factory->size) {
213 block->buffer = axl_new (char, size + 1);
214 factory->size = size + 1;
215 } else {
216 /* store step allocation */
217 factory->size = factory->step;
218 block->buffer = axl_new (char, factory->size + 1);
221 /* configure the new block */
222 block->next = factory->block;
223 factory->block = block;
224 factory->index = 0;
225 } /* end if */
227 /* get current index available */
228 result = factory->block->buffer + factory->index;
230 /* nullify to normalize string */
231 result [ size ] = 0;
233 /* reserve size bytes */
234 factory->index += size + 1;
236 return result;
239 /**
240 * @internal Deallocs the axl stream factory and all chunks allocated.
242 * @param factory The factory to dealloc.
244 void axl_string_factory_free (axlStrFactory * factory)
246 axlStrBlock * block;
247 axlStrBlock * aux;
249 /* do nothing if null received */
250 if (factory == NULL)
251 return;
253 /* get the first block */
254 block = factory->block;
256 while (block != NULL) {
258 /* get a reference to the next */
259 aux = block->next;
261 /* free items and the block */
262 axl_free (block->buffer);
263 axl_free (block);
265 /* get the next */
266 block = aux;
268 } /* end while */
270 axl_free (factory);
272 return;