2 * WINGs WMData function library
4 * Copyright (c) 1999 Dan Pascu
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 typedef struct W_Data
{
28 unsigned length
; /* How many bytes we have */
29 unsigned capacity
; /* How many bytes it can hold */
30 unsigned growth
; /* How much to grow */
31 void *bytes
; /* Actual data */
33 unsigned freeData
:1; /* whether the data should be released */
39 /* Creating and destroying data objects */
42 WMCreateDataWithCapacity(unsigned capacity
) /*FOLD00*/
46 aData
= (WMData
*)wmalloc(sizeof(WMData
));
49 aData
->bytes
= wmalloc(capacity
);
52 aData
->capacity
= capacity
;
53 aData
->growth
= capacity
/2 > 0 ? capacity
/2 : 1;
55 aData
->retainCount
= 1;
63 WMCreateDataWithLength(unsigned length
) /*FOLD00*/
67 aData
= WMCreateDataWithCapacity(length
);
69 memset(aData
->bytes
, 0, length
);
70 aData
->length
= length
;
78 WMCreateDataWithBytes(void *bytes
, unsigned length
) /*FOLD00*/
82 aData
= WMCreateDataWithCapacity(length
);
83 aData
->length
= length
;
84 memcpy(aData
->bytes
, bytes
, length
);
91 WMCreateDataWithBytesNoCopy(void *bytes
, unsigned length
) /*FOLD00*/
95 aData
= (WMData
*)wmalloc(sizeof(WMData
));
96 aData
->length
= length
;
97 aData
->capacity
= length
;
98 aData
->growth
= length
/2 > 0 ? length
/2 : 1;
100 aData
->retainCount
= 1;
108 WMCreateDataWithData(WMData
*aData
) /*FOLD00*/
110 if (aData
->length
> 0)
111 return WMCreateDataWithBytes(aData
->bytes
, aData
->length
);
113 return WMCreateDataWithCapacity(0);
118 WMRetainData(WMData
*aData
) /*FOLD00*/
120 aData
->retainCount
++;
126 WMReleaseData(WMData
*aData
) /*FOLD00*/
128 aData
->retainCount
--;
129 if (aData
->retainCount
> 0)
131 if (aData
->bytes
&& aData
->freeData
)
138 /* Adjusting capacity */
141 WMSetDataCapacity(WMData
*aData
, unsigned capacity
) /*FOLD00*/
143 if (aData
->capacity
!= capacity
) {
144 aData
->bytes
= wrealloc(aData
->bytes
, capacity
);
145 aData
->capacity
= capacity
;
146 aData
->growth
= capacity
/2 > 0 ? capacity
/2 : 1;
148 if (aData
->length
> capacity
) {
149 aData
->length
= capacity
;
155 WMSetDataLength(WMData
*aData
, unsigned length
) /*FOLD00*/
157 if (length
> aData
->capacity
) {
158 WMSetDataCapacity(aData
, length
);
160 if (length
> aData
->length
) {
161 memset(aData
->bytes
+ aData
->length
, 0, length
- aData
->length
);
163 aData
->length
= length
;
168 WMIncreaseDataLengthBy(WMData
*aData
, unsigned extraLength
) /*FOLD00*/
170 WMSetDataLength(aData
, aData
->length
+ extraLength
);
177 WMDataBytes(WMData
*aData
) /*FOLD00*/
184 WMGetDataBytes(WMData
*aData
, void *buffer
) /*FOLD00*/
186 wassertr(aData
->length
> 0);
188 memcpy(buffer
, aData
->bytes
, aData
->length
);
193 WMGetDataBytesWithLength(WMData
*aData
, void *buffer
, unsigned length
) /*FOLD00*/
195 wassertr(aData
->length
> 0);
196 wassertr(length
<= aData
->length
);
198 memcpy(buffer
, aData
->bytes
, length
);
203 WMGetDataBytesWithRange(WMData
*aData
, void *buffer
, WMRange aRange
) /*FOLD00*/
205 wassertr(aRange
.position
< aData
->length
);
206 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
208 memcpy(buffer
, aData
->bytes
+ aRange
.position
, aRange
.count
);
213 WMGetSubdataWithRange(WMData
*aData
, WMRange aRange
) /*FOLD00*/
217 /* return an empty subdata instead if aRange.count is 0 ? */
218 wassertrv(aRange
.count
> 0, NULL
);
220 buffer
= wmalloc(aRange
.count
);
221 WMGetDataBytesWithRange(aData
, buffer
, aRange
);
222 return WMCreateDataWithBytesNoCopy(buffer
, aRange
.count
);
229 WMIsDataEqualToData(WMData
*aData
, WMData
*anotherData
) /*FOLD00*/
231 if (aData
->length
!= anotherData
->length
)
233 else if (!aData
->bytes
&& !anotherData
->bytes
) /* both are empty */
235 else if (!aData
->bytes
|| !anotherData
->bytes
) /* one of them is empty */
237 return (memcmp(aData
->bytes
, anotherData
->bytes
, aData
->length
)==0);
242 WMGetDataLength(WMData
*aData
) /*FOLD00*/
244 return aData
->length
;
249 WMGetDataHash(WMData
*aData
) /*FOLD00*/
251 return aData
->length
;
257 WMAppendDataBytes(WMData
*aData
, void *bytes
, unsigned length
) /*FOLD00*/
259 unsigned oldLength
= aData
->length
;
260 unsigned newLength
= oldLength
+ length
;
262 if (newLength
> aData
->capacity
) {
263 unsigned nextCapacity
= aData
->capacity
+ aData
->growth
;
264 unsigned nextGrowth
= aData
->capacity
? aData
->capacity
: 1;
266 while (nextCapacity
< newLength
) {
267 unsigned tmp
= nextCapacity
+ nextGrowth
;
269 nextGrowth
= nextCapacity
;
272 WMSetDataCapacity(aData
, nextCapacity
);
273 aData
->growth
= nextGrowth
;
275 memcpy(aData
->bytes
+ oldLength
, bytes
, length
);
276 aData
->length
= newLength
;
281 WMAppendData(WMData
*aData
, WMData
*anotherData
) /*FOLD00*/
283 if (anotherData
->length
> 0)
284 WMAppendDataBytes(aData
, anotherData
->bytes
, anotherData
->length
);
292 WMReplaceDataBytesInRange(WMData
*aData
, WMRange aRange
, void *bytes
) /*FOLD00*/
294 wassertr(aRange
.position
< aData
->length
);
295 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
297 memcpy(aData
->bytes
+ aRange
.position
, bytes
, aRange
.count
);
302 WMResetDataBytesInRange(WMData
*aData
, WMRange aRange
) /*FOLD00*/
304 wassertr(aRange
.position
< aData
->length
);
305 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
307 memset(aData
->bytes
+ aRange
.position
, 0, aRange
.count
);
312 WMSetData(WMData
*aData
, WMData
*anotherData
) /*FOLD00*/
314 unsigned length
= anotherData
->length
;
316 WMSetDataCapacity(aData
, length
);
318 memcpy(aData
->bytes
, anotherData
->bytes
, length
);
319 aData
->length
= length
;