1 : /*
2 : * $Id: arraylist.c,v 1.4 2006/01/26 02:16:28 mclark Exp $
3 : *
4 : * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5 : * Michael Clark <michael@metaparadigm.com>
6 : *
7 : * This library is free software; you can redistribute it and/or modify
8 : * it under the terms of the MIT license. See COPYING for details.
9 : *
10 : */
11 :
12 : #include "config.h"
13 :
14 : #if STDC_HEADERS
15 : # include <stdlib.h>
16 : # include <string.h>
17 : #endif /* STDC_HEADERS */
18 :
19 : #if HAVE_STRINGS_H
20 : # include <strings.h>
21 : #endif /* HAVE_STRINGS_H */
22 :
23 : #include "bits.h"
24 : #include "arraylist.h"
25 :
26 : #include <cpl_port.h> /* MIN and MAX macros */
27 :
28 : struct array_list*
29 144 : array_list_new(array_list_free_fn *free_fn)
30 : {
31 : struct array_list *this;
32 :
33 144 : if((this = calloc(1, sizeof(struct array_list))) == NULL) return NULL;
34 :
35 144 : this->size = ARRAY_LIST_DEFAULT_SIZE;
36 144 : this->length = 0;
37 144 : this->free_fn = free_fn;
38 144 : if((this->array = calloc(sizeof(void*), this->size)) == NULL) {
39 0 : free(this);
40 0 : return NULL;
41 : }
42 144 : return this;
43 : }
44 :
45 : extern void
46 144 : array_list_free(struct array_list *this)
47 : {
48 : int i;
49 454 : for(i = 0; i < this->length; i++)
50 310 : if(this->array[i]) this->free_fn(this->array[i]);
51 144 : free(this->array);
52 144 : free(this);
53 144 : }
54 :
55 : void*
56 316 : array_list_get_idx(struct array_list *this, int i)
57 : {
58 316 : if(i >= this->length) return NULL;
59 316 : return this->array[i];
60 : }
61 :
62 310 : static int array_list_expand_internal(struct array_list *this, int max)
63 : {
64 : void *t;
65 : int new_size;
66 :
67 310 : if(max < this->size) return 0;
68 0 : new_size = MAX(this->size << 1, max);
69 0 : if((t = realloc(this->array, new_size*sizeof(void*))) == NULL) return -1;
70 0 : this->array = t;
71 0 : (void)memset(this->array + this->size, 0, (new_size-this->size)*sizeof(void*));
72 0 : this->size = new_size;
73 0 : return 0;
74 : }
75 :
76 : int
77 310 : array_list_put_idx(struct array_list *this, int idx, void *data)
78 : {
79 310 : if(array_list_expand_internal(this, idx)) return -1;
80 310 : if(this->array[idx]) this->free_fn(this->array[idx]);
81 310 : this->array[idx] = data;
82 310 : if(this->length <= idx) this->length = idx + 1;
83 310 : return 0;
84 : }
85 :
86 : int
87 310 : array_list_add(struct array_list *this, void *data)
88 : {
89 310 : return array_list_put_idx(this, this->length, data);
90 : }
91 :
92 : int
93 245 : array_list_length(struct array_list *this)
94 : {
95 245 : return this->length;
96 : }
|