1 /*
2 * Copyright (C) 1997-2005, R3vis Corporation.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18 *
19 * Original Contributor:
20 * Wes Bethel, R3vis Corporation, Marin County, California
21 * Additional Contributor(s):
22 *
23 * The OpenRM project is located at http://openrm.sourceforge.net/.
24 */
25 /*
26 * $Id: rmarray.c,v 1.1 2005/02/19 16:36:40 wes Exp $
27 * Version: $Name: OpenRM-1-6-0-2-RC2 $
28 * $Revision: 1.1 $
29 * $Log: rmarray.c,v $
30 * Revision 1.1 2005/02/19 16:36:40 wes
31 * Distro merge and consolidation.
32 *
33 */
34
35 #include <rm/rm.h>
36 #include "rmprivat.h"
37
38 static RMenum
private_rmArrayRealloc(RMarray * a)39 private_rmArrayRealloc(RMarray *a)
40 {
41 char *t;
42 size_t newSize;
43
44 newSize = a->currentArraySize*a->elementSize + a->elementSize * a->chunkSize;
45
46 #if 1
47 t = (void *)realloc(a->data, newSize);
48 if (t == NULL)
49 {
50 char buf[512];
51 sprintf(buf, "private_rmArrayRealloc error: unable to realloc an array of size %ld bytes. ", (long)newSize);
52 rmError(buf);
53 return RM_WHACKED;
54 }
55 #else
56 /* manual realloc */
57 t = (char *)malloc(newSize);
58 memcpy(t, a->data, a->currentArraySize*a->elementSize);
59 free((void *)(a->data));
60 #endif
61 a->data = t;
62 a->currentArraySize += a->chunkSize;
63
64 return RM_CHILL;
65 }
66
67 RMenum
rmArrayDelete(RMarray ** a)68 rmArrayDelete(RMarray **a)
69 {
70 void *data;
71
72 if ((RM_ASSERT(a, "rmArrayDelete error - the input array object handle is NULL.") == RM_WHACKED) ||
73 (RM_ASSERT(*a,"rmArrayDelete error - the input array object is NULL") == RM_WHACKED))
74 return RM_WHACKED;
75
76 data = (*a)->data;
77
78 if (data != NULL)
79 free(data);
80
81 free((void *)*a);
82 *a = NULL;
83
84 return RM_CHILL;
85 }
86
87 RMarray *
rmArrayNew(int initSize,int chunkSize,int elementSize)88 rmArrayNew(int initSize,
89 int chunkSize,
90 int elementSize)
91 {
92 /* creates a new array object */
93 /* RMarray *t = (RMarray *)calloc(1, sizeof(RMarray)); */
94 RMarray *t = (RMarray *)malloc(sizeof(RMarray));
95 memset(t, 0, sizeof(RMarray));
96
97 t->nItems = 0;
98 t->chunkSize = chunkSize;
99 t->elementSize = elementSize;
100 t->currentArraySize = initSize;
101
102 if (initSize != 0)
103 {
104 t->data = (char *)malloc(sizeof(char)*(initSize* elementSize));
105 memset(t->data, 0, sizeof(char)*(initSize* elementSize));
106 /* t->data = (char *)calloc(initSize, elementSize); */
107 }
108
109 return t;
110 }
111
112 void *
rmArrayGet(const RMarray * toQuery,int indx)113 rmArrayGet(const RMarray *toQuery,
114 int indx)
115 {
116 /* get a handle to an item in the array */
117 off_t offset;
118
119 char *t;
120
121 if (RM_ASSERT(toQuery, "rmArrayGet error - the input RMarray object is NULL.") == RM_WHACKED)
122 return NULL;
123
124 if (indx >= toQuery->nItems)
125 {
126 char buf[512];
127 sprintf(buf,"rmArrayGet warning - request for item #%d, but there are only %d items in the array.", indx, toQuery->nItems);
128 return NULL;
129 }
130
131 t = toQuery->data;
132 offset = indx * toQuery->elementSize;
133 return (void *)(t+offset);
134 }
135
136 RMenum
rmArrayAdd(RMarray * toModify,void * newData)137 rmArrayAdd(RMarray *toModify,
138 void *newData)
139 {
140 off_t offset;
141 char *dest;
142
143 if (RM_ASSERT(toModify, "rmArrayAdd error - the input RMarray object is NULL.") == RM_WHACKED)
144 return RM_WHACKED;
145
146 /* see if there's enough room to add one more thingamajig to the array */
147 if ((toModify->nItems + 1) >= toModify->currentArraySize)
148 {
149 if (private_rmArrayRealloc(toModify) != RM_CHILL)
150 {
151 rmError("rmArrayAdd() - unable to realloc sufficient space to add more items to the input array. Action fails. ");
152 return RM_WHACKED;
153 }
154 }
155
156 offset = toModify->nItems * toModify->elementSize;
157 dest = (char *)(toModify->data) + offset;
158 memcpy((void *)dest, newData, toModify->elementSize);
159
160 toModify->nItems += 1;
161
162 return RM_CHILL;
163 }
164
165 int
rmArrayNumItems(const RMarray * toQuery)166 rmArrayNumItems(const RMarray *toQuery)
167 {
168 if (RM_ASSERT(toQuery, "rmArrayNumItems error - the input array object is NULL") == RM_WHACKED)
169 return -1;
170
171 return toQuery->nItems;
172 }
173
174 #if 0
175 /* we might implement this if needed */
176 RMenum
177 rmArraySet(RMarray *toModify,
178 int indx,
179 void *data)
180 {
181 /* set an item in the array */
182 }
183 #endif
184
185 void
rmArraySort(RMarray * a,int (* compareFunc)(const void * a,const void * b))186 rmArraySort(RMarray *a,
187 int (*compareFunc)(const void *a, const void *b))
188 {
189 int nItems = rmArrayNumItems(a);
190 qsort(a->data, nItems, a->elementSize, compareFunc);
191 }
192
193 /* EOF */
194