1/*
2 * << Haru Free PDF Library >> -- hpdf_list.c
3 *
4 * URL: http://libharu.org
5 *
6 * Copyright (c) 1999-2006 Takeshi Kanno <takeshi_kanno@est.hi-ho.ne.jp>
7 * Copyright (c) 2007-2009 Antony Dovgal <tony@daylessday.org>
8 *
9 * Permission to use, copy, modify, distribute and sell this software
10 * and its documentation for any purpose is hereby granted without fee,
11 * provided that the above copyright notice appear in all copies and
12 * that both that copyright notice and this permission notice appear
13 * in supporting documentation.
14 * It is provided "as is" without express or implied warranty.
15 *
16 */
17
18#include "hpdf_conf.h"
19#include "hpdf_utils.h"
20#include "hpdf_consts.h"
21#include "hpdf_list.h"
22
23static HPDF_STATUS
24Resize (HPDF_List list,
25 HPDF_UINT count);
26
27
28/*
29 * HPDF_List_new
30 *
31 * mmgr : handle to a HPDF_MMgr object.
32 * items_per_block : number of increases of pointers.
33 *
34 * return: If HPDF_List_New success, it returns a handle to new HPDF_List
35 * object, otherwise it returns NULL.
36 *
37 */
38
39HPDF_List
40HPDF_List_New (HPDF_MMgr mmgr,
41 HPDF_UINT items_per_block)
42{
43 HPDF_List list;
44
45 HPDF_PTRACE((" HPDF_List_New\n"));
46
47 if (mmgr == NULL)
48 return NULL;
49
50 list = (HPDF_List)HPDF_GetMem (mmgr, sizeof(HPDF_List_Rec));
51 if (list) {
52 list->mmgr = mmgr;
53 list->error = mmgr->error;
54 list->block_siz = 0;
55 list->items_per_block =
56 (items_per_block <= 0 ? HPDF_DEF_ITEMS_PER_BLOCK : items_per_block);
57 list->count = 0;
58 list->obj = NULL;
59 }
60
61 return list;
62}
63
64/*
65 * HPDF_List_add
66 *
67 * list : Pointer to a HPDF_List object.
68 * item : Pointer to a object to be added.
69 *
70 * return: If HPDF_List_Add success, it returns HPDF_OK.
71 * HPDF_FAILD_TO_ALLOC_MEM is returned when the expansion of the
72 * object list is failed.
73 *
74 */
75
76HPDF_STATUS
77HPDF_List_Add (HPDF_List list,
78 void *item)
79{
80 HPDF_PTRACE((" HPDF_List_Add\n"));
81
82 if (list->count >= list->block_siz) {
83 HPDF_STATUS ret = Resize (list,
84 list->block_siz + list->items_per_block);
85
86 if (ret != HPDF_OK) {
87 return ret;
88 }
89 }
90
91 list->obj[list->count++] = item;
92 return HPDF_OK;
93}
94
95
96/*
97 * HPDF_List_Insert
98 *
99 * list : Pointer to a HPDF_List object.
100 * target : Pointer to the target object.
101 * item : Pointer to a object to be inserted.
102 *
103 * insert the item before the target.
104 *
105 * return: If HPDF_List_Add success, it returns HPDF_OK.
106 * HPDF_FAILD_TO_ALLOC_MEM is returned when the expansion of the
107 * object list is failed.
108 * HPDF_ITEM_NOT_FOUND is returned where the target object is not
109 * found.
110 *
111 */
112
113HPDF_STATUS
114HPDF_List_Insert (HPDF_List list,
115 void *target,
116 void *item)
117{
118 HPDF_INT target_idx = HPDF_List_Find (list, target);
119 void *last_item = list->obj[list->count - 1];
120 HPDF_INT i;
121
122 HPDF_PTRACE((" HPDF_List_Insert\n"));
123
124 if (target_idx < 0)
125 return HPDF_ITEM_NOT_FOUND;
126
127 /* move the item of the list to behind one by one. */
128 for (i = list->count - 2; i >= target_idx; i--)
129 list->obj[i + 1] = list->obj[i];
130
131 list->obj[target_idx] = item;
132
133 return HPDF_List_Add (list, last_item);
134}
135
136/*
137 * HPDF_List_Remove
138 *
139 * Remove the object specified by item parameter from the list object. The
140 * memory area that the object uses is not released.
141 *
142 * list : Pointer to a HPDF_List object.
143 * item : Pointer to a object to be remove.
144 *
145 * return: If HPDF_List_Remove success, it returns HPDF_OK.
146 * HPDF_ITEM_NOT_FOUND is returned when the object specified by item
147 * parameter is not found.
148 *
149 */
150
151HPDF_STATUS
152HPDF_List_Remove (HPDF_List list,
153 void *item)
154{
155 HPDF_UINT i;
156 void **obj = list->obj;
157
158 HPDF_PTRACE((" HPDF_List_Remove\n"));
159
160 for (i = 0; i < list->count; i++) {
161 if (*obj == item) {
162 HPDF_List_RemoveByIndex(list, i);
163 return HPDF_OK;
164 } else
165 obj++;
166 }
167
168 return HPDF_ITEM_NOT_FOUND;
169}
170
171/*
172 * HPDF_List_RemoveByIndex
173 *
174 * Remove the object by index number.
175 *
176 * list : Pointer to a HPDF_List object.
177 * index : Index of a object to be remove.
178 *
179 * return: If HPDF_List_RemoveByIndex success, it returns HPDF_OK.
180 * HPDF_ITEM_NOT_FOUND is returned when the value which is specified
181 * by index parameter is invalid.
182 *
183 */
184
185void*
186HPDF_List_RemoveByIndex (HPDF_List list,
187 HPDF_UINT index)
188{
189 void *tmp;
190
191 HPDF_PTRACE((" HPDF_List_RemoveByIndex\n"));
192
193 if (list->count <= index)
194 return NULL;
195
196 tmp = list->obj[index];
197
198 while (index < list->count - 1) {
199 list->obj[index] = list->obj[index + 1];
200 index++;
201 }
202
203 list->count--;
204
205 return tmp;
206}
207
208/*
209 * HPDF_List_ItemAt
210 *
211 * list : Pointer to a HPDF_List object.
212 * index : Index of a object.
213 *
214 * return: If HPDF_List_at success, it returns a pointer to the object.
215 * otherwise it returns NULL.
216 *
217 */
218
219void*
220HPDF_List_ItemAt (HPDF_List list,
221 HPDF_UINT index)
222{
223 HPDF_PTRACE((" HPDF_List_ItemAt\n"));
224
225 return (list->count <= index) ? NULL : list->obj[index];
226}
227
228/*
229 * HPDF_List_free
230 *
231 * list : Pointer to a HPDF_List object.
232 *
233 */
234
235void
236HPDF_List_Free (HPDF_List list)
237{
238 HPDF_PTRACE((" HPDF_List_Free\n"));
239
240 if (!list)
241 return ;
242
243 HPDF_List_Clear (list);
244 HPDF_FreeMem (list->mmgr, list);
245}
246
247/*
248 * HPDF_List_Clear
249 *
250 * list : Pointer to a HPDF_List object.
251 *
252 */
253
254void
255HPDF_List_Clear (HPDF_List list)
256{
257 HPDF_PTRACE((" HPDF_List_Clear\n"));
258
259 if (list->obj)
260 HPDF_FreeMem (list->mmgr, list->obj);
261
262 list->block_siz = 0;
263 list->count = 0;
264 list->obj = NULL;
265}
266
267/*
268 * Resize
269 *
270 * list : Pointer to a HPDF_List object.
271 * count : The size of array of pointers.
272 *
273 * return: If Resize success, it returns HPDF_OK.
274 * otherwise it returns error-code which is set by HPDF_MMgr object.
275 *
276 */
277
278static HPDF_STATUS
279Resize (HPDF_List list,
280 HPDF_UINT count)
281{
282 void **new_obj;
283
284 HPDF_PTRACE((" HPDF_List_Resize\n"));
285
286 if (list->count >= count) {
287 if (list->count == count)
288 return HPDF_OK;
289 else
290 return HPDF_INVALID_PARAMETER;
291 }
292
293 new_obj = (void **)HPDF_GetMem (list->mmgr, count * sizeof(void *));
294
295 if (!new_obj)
296 return HPDF_Error_GetCode (list->error);
297
298 if (list->obj)
299 HPDF_MemCpy ((HPDF_BYTE *)new_obj, (HPDF_BYTE *)list->obj,
300 list->block_siz * sizeof(void *));
301
302 list->block_siz = count;
303 if (list->obj)
304 HPDF_FreeMem (list->mmgr, list->obj);
305 list->obj = new_obj;
306
307 return HPDF_OK;
308}
309
310/*
311 * HPDF_List_Find
312 *
313 * list : Pointer to a HPDF_List object.
314 * count : the size of array of pointers.
315 *
316 * return: If HPDF_List_Find success, it returns index of the object.
317 * otherwise it returns negative value.
318 *
319 */
320
321HPDF_INT32
322HPDF_List_Find (HPDF_List list,
323 void *item)
324{
325 HPDF_UINT i;
326
327 HPDF_PTRACE((" HPDF_List_Find\n"));
328
329 for (i = 0; i < list->count; i++) {
330 if (list->obj[i] == item)
331 return i;
332 }
333
334 return -1;
335}
336
337