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