2 * XML Security Library (http://www.aleksey.com/xmlsec).
6 * This is free software; see Copyright file in the source
7 * distribution for preciese wording.
9 * Copyright (C) 2002-2003 Aleksey Sanin <aleksey@aleksey.com>
16 #include <libxml/tree.h>
18 #include <xmlsec/xmlsec.h>
19 #include <xmlsec/list.h>
20 #include <xmlsec/errors.h>
23 static int xmlSecPtrListEnsureSize (xmlSecPtrListPtr list,
26 static xmlSecAllocMode gAllocMode = xmlSecAllocModeDouble;
27 static xmlSecSize gInitialSize = 64;
30 * xmlSecPtrListSetDefaultAllocMode:
31 * @defAllocMode: the new default memory allocation mode.
32 * @defInitialSize: the new default minimal initial size.
34 * Sets new default allocation mode and minimal initial list size.
37 xmlSecPtrListSetDefaultAllocMode(xmlSecAllocMode defAllocMode, xmlSecSize defInitialSize) {
38 xmlSecAssert(defInitialSize > 0);
40 gAllocMode = defAllocMode;
41 gInitialSize = defInitialSize;
45 * xmlSecPtrListCreate:
46 * @id: the list klass.
48 * Creates new list object. Caller is responsible for freeing returned list
49 * by calling #xmlSecPtrListDestroy function.
51 * Returns: pointer to newly allocated list or NULL if an error occurs.
54 xmlSecPtrListCreate(xmlSecPtrListId id) {
55 xmlSecPtrListPtr list;
58 xmlSecAssert2(id != xmlSecPtrListIdUnknown, NULL);
60 /* Allocate a new xmlSecPtrList and fill the fields. */
61 list = (xmlSecPtrListPtr)xmlMalloc(sizeof(xmlSecPtrList));
63 xmlSecError(XMLSEC_ERRORS_HERE,
64 xmlSecErrorsSafeString(xmlSecPtrListKlassGetName(id)),
66 XMLSEC_ERRORS_R_MALLOC_FAILED,
67 "sizeof(xmlSecPtrList)=%d",
68 sizeof(xmlSecPtrList));
72 ret = xmlSecPtrListInitialize(list, id);
74 xmlSecError(XMLSEC_ERRORS_HERE,
75 xmlSecErrorsSafeString(xmlSecPtrListKlassGetName(id)),
76 "xmlSecPtrListInitialize",
77 XMLSEC_ERRORS_R_XMLSEC_FAILED,
78 XMLSEC_ERRORS_NO_MESSAGE);
87 * xmlSecPtrListDestroy:
88 * @list: the pointer to list.
90 * Destroys @list created with #xmlSecPtrListCreate function.
93 xmlSecPtrListDestroy(xmlSecPtrListPtr list) {
94 xmlSecAssert(xmlSecPtrListIsValid(list));
95 xmlSecPtrListFinalize(list);
100 * xmlSecPtrListInitialize:
101 * @list: the pointer to list.
102 * @id: the list klass.
104 * Initializes the list of given klass. Caller is responsible
105 * for cleaning up by calling #xmlSecPtrListFinalize function.
107 * Returns: 0 on success or a negative value if an error occurs.
110 xmlSecPtrListInitialize(xmlSecPtrListPtr list, xmlSecPtrListId id) {
111 xmlSecAssert2(id != xmlSecPtrListIdUnknown, -1);
112 xmlSecAssert2(list != NULL, -1);
114 memset(list, 0, sizeof(xmlSecPtrList));
116 list->allocMode = gAllocMode;
122 * xmlSecPtrListFinalize:
123 * @list: the pointer to list.
125 * Cleans up the list initialized with #xmlSecPtrListInitialize
129 xmlSecPtrListFinalize(xmlSecPtrListPtr list) {
130 xmlSecAssert(xmlSecPtrListIsValid(list));
132 xmlSecPtrListEmpty(list);
133 memset(list, 0, sizeof(xmlSecPtrList));
137 * xmlSecPtrListEmpty:
138 * @list: the pointer to list.
140 * Remove all items from @list (if any).
143 xmlSecPtrListEmpty(xmlSecPtrListPtr list) {
144 xmlSecAssert(xmlSecPtrListIsValid(list));
146 if(list->id->destroyItem != NULL) {
149 for(pos = 0; pos < list->use; ++pos) {
150 xmlSecAssert(list->data != NULL);
151 if(list->data[pos] != NULL) {
152 list->id->destroyItem(list->data[pos]);
157 xmlSecAssert(list->data != NULL);
159 memset(list->data, 0, sizeof(xmlSecPtr) * list->use);
162 list->max = list->use = 0;
168 * @dst: the pointer to destination list.
169 * @src: the pointer to source list.
171 * Copies @src list items to @dst list using #duplicateItem method
172 * of the list klass. If #duplicateItem method is NULL then
173 * we jsut copy pointers to items.
175 * Returns: 0 on success or a negative value if an error occurs.
178 xmlSecPtrListCopy(xmlSecPtrListPtr dst, xmlSecPtrListPtr src) {
182 xmlSecAssert2(xmlSecPtrListIsValid(dst), -1);
183 xmlSecAssert2(xmlSecPtrListIsValid(src), -1);
184 xmlSecAssert2(dst->id == src->id, -1);
186 /* allocate memory */
187 ret = xmlSecPtrListEnsureSize(dst, dst->use + src->use);
189 xmlSecError(XMLSEC_ERRORS_HERE,
190 xmlSecErrorsSafeString(xmlSecPtrListGetName(src)),
191 "xmlSecPtrListEnsureSize",
192 XMLSEC_ERRORS_R_XMLSEC_FAILED,
193 "size=%d", src->use);
197 /* copy one item after another */
198 for(i = 0; i < src->use; ++i, ++dst->use) {
199 xmlSecAssert2(src->data != NULL, -1);
200 xmlSecAssert2(dst->data != NULL, -1);
202 if((dst->id->duplicateItem != NULL) && (src->data[i] != NULL)) {
203 dst->data[dst->use] = dst->id->duplicateItem(src->data[i]);
204 if(dst->data[dst->use] == NULL) {
205 xmlSecError(XMLSEC_ERRORS_HERE,
206 xmlSecErrorsSafeString(xmlSecPtrListGetName(src)),
208 XMLSEC_ERRORS_R_XMLSEC_FAILED,
209 XMLSEC_ERRORS_NO_MESSAGE);
213 dst->data[dst->use] = src->data[i];
221 * xmlSecPtrListDuplicate:
222 * @list: the pointer to list.
224 * Creates a new copy of @list and all its items.
226 * Returns: pointer to newly allocated list or NULL if an error occurs.
229 xmlSecPtrListDuplicate(xmlSecPtrListPtr list) {
230 xmlSecPtrListPtr newList;
233 xmlSecAssert2(xmlSecPtrListIsValid(list), NULL);
235 newList = xmlSecPtrListCreate(list->id);
236 if(newList == NULL) {
237 xmlSecError(XMLSEC_ERRORS_HERE,
238 xmlSecErrorsSafeString(xmlSecPtrListGetName(list)),
239 "xmlSecPtrListCreate",
240 XMLSEC_ERRORS_R_XMLSEC_FAILED,
241 XMLSEC_ERRORS_NO_MESSAGE);
245 ret = xmlSecPtrListCopy(newList, list);
247 xmlSecError(XMLSEC_ERRORS_HERE,
248 xmlSecErrorsSafeString(xmlSecPtrListGetName(list)),
250 XMLSEC_ERRORS_R_XMLSEC_FAILED,
251 XMLSEC_ERRORS_NO_MESSAGE);
252 xmlSecPtrListDestroy(newList);
259 * xmlSecPtrListGetSize:
260 * @list: the pointer to list.
264 * Returns: the number of itmes in @list.
267 xmlSecPtrListGetSize(xmlSecPtrListPtr list) {
268 xmlSecAssert2(xmlSecPtrListIsValid(list), 0);
274 * xmlSecPtrListGetItem:
275 * @list: the pointer to list.
276 * @pos: the item position.
278 * Gets item from the list.
280 * Returns: the list item at position @pos or NULL if @pos is greater
281 * than the number of items in the list or an error occurs.
284 xmlSecPtrListGetItem(xmlSecPtrListPtr list, xmlSecSize pos) {
285 xmlSecAssert2(xmlSecPtrListIsValid(list), NULL);
286 xmlSecAssert2(list->data != NULL, NULL);
287 xmlSecAssert2(pos < list->use, NULL);
289 return(list->data[pos]);
294 * @list: the pointer to list.
297 * Adds @item to the end of the @list.
299 * Returns: 0 on success or a negative value if an error occurs.
302 xmlSecPtrListAdd(xmlSecPtrListPtr list, xmlSecPtr item) {
305 xmlSecAssert2(xmlSecPtrListIsValid(list), -1);
307 ret = xmlSecPtrListEnsureSize(list, list->use + 1);
309 xmlSecError(XMLSEC_ERRORS_HERE,
310 xmlSecErrorsSafeString(xmlSecPtrListGetName(list)),
312 XMLSEC_ERRORS_R_XMLSEC_FAILED,
313 "size=%d", list->use + 1);
317 list->data[list->use++] = item;
323 * @list: the pointer to list.
327 * Sets the value of list item at position @pos. The old value
330 * Returns: 0 on success or a negative value if an error occurs.
333 xmlSecPtrListSet(xmlSecPtrListPtr list, xmlSecPtr item, xmlSecSize pos) {
334 xmlSecAssert2(xmlSecPtrListIsValid(list), -1);
335 xmlSecAssert2(list->data != NULL, -1);
336 xmlSecAssert2(pos < list->use, -1);
338 if((list->id->destroyItem != NULL) && (list->data[pos] != NULL)) {
339 list->id->destroyItem(list->data[pos]);
341 list->data[pos] = item;
346 * xmlSecPtrListRemove:
347 * @list: the pointer to list.
348 * @pos: the position.
350 * Destroys list item at the position @pos and sets it value to NULL.
352 * Returns: 0 on success or a negative value if an error occurs.
355 xmlSecPtrListRemove(xmlSecPtrListPtr list, xmlSecSize pos) {
356 xmlSecAssert2(xmlSecPtrListIsValid(list), -1);
357 xmlSecAssert2(list->data != NULL, -1);
358 xmlSecAssert2(pos < list->use, -1);
360 if((list->id->destroyItem != NULL) && (list->data[pos] != NULL)) {
361 list->id->destroyItem(list->data[pos]);
363 list->data[pos] = NULL;
364 if(pos == list->use - 1) {
371 * xmlSecPtrListDebugDump:
372 * @list: the pointer to list.
373 * @output: the pointer to output FILE.
375 * Prints debug information about @list to the @output.
378 xmlSecPtrListDebugDump(xmlSecPtrListPtr list, FILE* output) {
379 xmlSecAssert(xmlSecPtrListIsValid(list));
380 xmlSecAssert(output != NULL);
382 fprintf(output, "=== list size: %d\n", list->use);
383 if(list->id->debugDumpItem != NULL) {
386 for(pos = 0; pos < list->use; ++pos) {
387 xmlSecAssert(list->data != NULL);
388 if(list->data[pos] != NULL) {
389 list->id->debugDumpItem(list->data[pos], output);
396 * xmlSecPtrListDebugXmlDump:
397 * @list: the pointer to list.
398 * @output: the pointer to output FILE.
400 * Prints debug information about @list to the @output in XML format.
403 xmlSecPtrListDebugXmlDump(xmlSecPtrListPtr list, FILE* output) {
404 xmlSecAssert(xmlSecPtrListIsValid(list));
405 xmlSecAssert(output != NULL);
407 fprintf(output, "<List size=\"%d\">\n", list->use);
408 if(list->id->debugXmlDumpItem != NULL) {
411 for(pos = 0; pos < list->use; ++pos) {
412 xmlSecAssert(list->data != NULL);
413 if(list->data[pos] != NULL) {
414 list->id->debugXmlDumpItem(list->data[pos], output);
418 fprintf(output, "</List>\n");
422 xmlSecPtrListEnsureSize(xmlSecPtrListPtr list, xmlSecSize size) {
424 xmlSecSize newSize = 0;
426 xmlSecAssert2(xmlSecPtrListIsValid(list), -1);
428 if(size < list->max) {
432 switch(list->allocMode) {
433 case xmlSecAllocModeExact:
436 case xmlSecAllocModeDouble:
437 newSize = 2 * size + 32;
441 if(newSize < gInitialSize) {
442 newSize = gInitialSize;
445 if(list->data != NULL) {
446 newData = (xmlSecPtr*)xmlRealloc(list->data, sizeof(xmlSecPtr) * newSize);
448 newData = (xmlSecPtr*)xmlMalloc(sizeof(xmlSecPtr) * newSize);
450 if(newData == NULL) {
451 xmlSecError(XMLSEC_ERRORS_HERE,
452 xmlSecErrorsSafeString(xmlSecPtrListGetName(list)),
454 XMLSEC_ERRORS_R_MALLOC_FAILED,
455 "sizeof(xmlSecPtr)*%d=%d",
456 newSize, sizeof(xmlSecPtr) * newSize);
460 list->data = newData;
466 /***********************************************************************
470 **********************************************************************/
471 static xmlSecPtr xmlSecStringListDuplicateItem (xmlSecPtr ptr);
472 static void xmlSecStringListDestroyItem (xmlSecPtr ptr);
474 static xmlSecPtrListKlass xmlSecStringListKlass = {
475 BAD_CAST "strings-list",
476 xmlSecStringListDuplicateItem, /* xmlSecPtrDuplicateItemMethod duplicateItem; */
477 xmlSecStringListDestroyItem, /* xmlSecPtrDestroyItemMethod destroyItem; */
478 NULL, /* xmlSecPtrDebugDumpItemMethod debugDumpItem; */
479 NULL, /* xmlSecPtrDebugDumpItemMethod debugXmlDumpItem; */
483 * xmlSecStringListGetKlass:
485 * The strins list class.
487 * Returns: strings list klass.
490 xmlSecStringListGetKlass(void) {
491 return(&xmlSecStringListKlass);
495 xmlSecStringListDuplicateItem(xmlSecPtr ptr) {
496 xmlSecAssert2(ptr != NULL, NULL);
498 return(xmlStrdup((xmlChar*)ptr));
502 xmlSecStringListDestroyItem(xmlSecPtr ptr) {
503 xmlSecAssert(ptr != NULL);