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 WMFreeDataProc
*destructor
;
34 int format
; /* 0, 8, 16 or 32 */
35 unsigned freeData
:1; /* whether the data should be released */
41 /* Creating and destroying data objects */
44 WMCreateDataWithCapacity(unsigned capacity
) /*FOLD00*/
48 aData
= (WMData
*)wmalloc(sizeof(WMData
));
51 aData
->bytes
= wmalloc(capacity
);
54 aData
->capacity
= capacity
;
55 aData
->growth
= capacity
/2 > 0 ? capacity
/2 : 1;
57 aData
->retainCount
= 1;
60 aData
->destructor
= NULL
;
67 WMCreateDataWithLength(unsigned length
) /*FOLD00*/
71 aData
= WMCreateDataWithCapacity(length
);
73 memset(aData
->bytes
, 0, length
);
74 aData
->length
= length
;
82 WMCreateDataWithBytes(void *bytes
, unsigned length
) /*FOLD00*/
86 aData
= WMCreateDataWithCapacity(length
);
87 aData
->length
= length
;
88 memcpy(aData
->bytes
, bytes
, length
);
95 WMCreateDataWithBytesNoCopy(void *bytes
, unsigned length
) /*FOLD00*/
99 aData
= (WMData
*)wmalloc(sizeof(WMData
));
100 aData
->length
= length
;
101 aData
->capacity
= length
;
102 aData
->growth
= length
/2 > 0 ? length
/2 : 1;
103 aData
->bytes
= bytes
;
104 aData
->retainCount
= 1;
107 aData
->destructor
= NULL
;
114 WMCreateDataWithBytesAndDestructor(void *bytes
, unsigned length
,
115 WMFreeDataProc
*destructor
)
119 aData
= (WMData
*)wmalloc(sizeof(WMData
));
120 aData
->length
= length
;
121 aData
->capacity
= length
;
122 aData
->growth
= length
/2 > 0 ? length
/2 : 1;
123 aData
->bytes
= bytes
;
124 aData
->retainCount
= 1;
127 aData
->destructor
= destructor
;
134 WMCreateDataWithData(WMData
*aData
) /*FOLD00*/
137 if (aData
->length
> 0) {
138 newData
= WMCreateDataWithBytes(aData
->bytes
, aData
->length
);
140 newData
= WMCreateDataWithCapacity(0);
142 newData
->destructor
= aData
->destructor
;
143 newData
->format
= aData
->format
;
150 WMRetainData(WMData
*aData
) /*FOLD00*/
152 aData
->retainCount
++;
158 WMReleaseData(WMData
*aData
) /*FOLD00*/
160 aData
->retainCount
--;
161 if (aData
->retainCount
> 0)
163 if (aData
->bytes
&& aData
->freeData
) {
164 if (aData
->destructor
!= NULL
)
165 aData
->destructor(aData
->bytes
);
174 /* Adjusting capacity */
177 WMSetDataCapacity(WMData
*aData
, unsigned capacity
) /*FOLD00*/
179 if (aData
->capacity
!= capacity
) {
180 aData
->bytes
= wrealloc(aData
->bytes
, capacity
);
181 aData
->capacity
= capacity
;
182 aData
->growth
= capacity
/2 > 0 ? capacity
/2 : 1;
184 if (aData
->length
> capacity
) {
185 aData
->length
= capacity
;
191 WMSetDataLength(WMData
*aData
, unsigned length
) /*FOLD00*/
193 if (length
> aData
->capacity
) {
194 WMSetDataCapacity(aData
, length
);
196 if (length
> aData
->length
) {
197 unsigned char *dataBytes
= (unsigned char *)aData
->bytes
;
199 memset(dataBytes
+ aData
->length
, 0, length
- aData
->length
);
201 aData
->length
= length
;
206 WMSetDataFormat(WMData
*aData
, unsigned format
)
208 aData
->format
= format
;
213 WMIncreaseDataLengthBy(WMData
*aData
, unsigned extraLength
) /*FOLD00*/
215 WMSetDataLength(aData
, aData
->length
+ extraLength
);
222 WMDataBytes(WMData
*aData
) /*FOLD00*/
229 WMGetDataBytes(WMData
*aData
, void *buffer
) /*FOLD00*/
231 wassertr(aData
->length
> 0);
233 memcpy(buffer
, aData
->bytes
, aData
->length
);
238 WMGetDataFormat(WMData
*aData
)
240 return aData
->format
;
245 WMGetDataBytesWithLength(WMData
*aData
, void *buffer
, unsigned length
) /*FOLD00*/
247 wassertr(aData
->length
> 0);
248 wassertr(length
<= aData
->length
);
250 memcpy(buffer
, aData
->bytes
, length
);
255 WMGetDataBytesWithRange(WMData
*aData
, void *buffer
, WMRange aRange
) /*FOLD00*/
257 unsigned char *dataBytes
= (unsigned char *)aData
->bytes
;
259 wassertr(aRange
.position
< aData
->length
);
260 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
262 memcpy(buffer
,dataBytes
+ aRange
.position
, aRange
.count
);
267 WMGetSubdataWithRange(WMData
*aData
, WMRange aRange
) /*FOLD00*/
272 /* return an empty subdata instead if aRange.count is 0 ? */
273 wassertrv(aRange
.count
> 0, NULL
);
275 buffer
= wmalloc(aRange
.count
);
276 WMGetDataBytesWithRange(aData
, buffer
, aRange
);
277 newData
= WMCreateDataWithBytesNoCopy(buffer
, aRange
.count
);
278 newData
->destructor
= aData
->destructor
;
279 newData
->format
= aData
->format
;
288 WMIsDataEqualToData(WMData
*aData
, WMData
*anotherData
) /*FOLD00*/
290 if (aData
->length
!= anotherData
->length
)
292 else if (!aData
->bytes
&& !anotherData
->bytes
) /* both are empty */
294 else if (!aData
->bytes
|| !anotherData
->bytes
) /* one of them is empty */
296 return (memcmp(aData
->bytes
, anotherData
->bytes
, aData
->length
)==0);
301 WMGetDataLength(WMData
*aData
) /*FOLD00*/
303 return aData
->length
;
309 WMAppendDataBytes(WMData
*aData
, void *bytes
, unsigned length
) /*FOLD00*/
311 unsigned oldLength
= aData
->length
;
312 unsigned newLength
= oldLength
+ length
;
313 unsigned char *dataBytes
= (unsigned char *)aData
->bytes
;
315 if (newLength
> aData
->capacity
) {
316 unsigned nextCapacity
= aData
->capacity
+ aData
->growth
;
317 unsigned nextGrowth
= aData
->capacity
? aData
->capacity
: 1;
319 while (nextCapacity
< newLength
) {
320 unsigned tmp
= nextCapacity
+ nextGrowth
;
322 nextGrowth
= nextCapacity
;
325 WMSetDataCapacity(aData
, nextCapacity
);
326 aData
->growth
= nextGrowth
;
328 memcpy(dataBytes
+ oldLength
, bytes
, length
);
329 aData
->length
= newLength
;
334 WMAppendData(WMData
*aData
, WMData
*anotherData
) /*FOLD00*/
336 if (anotherData
->length
> 0)
337 WMAppendDataBytes(aData
, anotherData
->bytes
, anotherData
->length
);
345 WMReplaceDataBytesInRange(WMData
*aData
, WMRange aRange
, void *bytes
) /*FOLD00*/
347 unsigned char *dataBytes
= (unsigned char *)aData
->bytes
;
349 wassertr(aRange
.position
< aData
->length
);
350 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
352 memcpy(dataBytes
+ aRange
.position
, bytes
, aRange
.count
);
357 WMResetDataBytesInRange(WMData
*aData
, WMRange aRange
) /*FOLD00*/
359 unsigned char *dataBytes
= (unsigned char *)aData
->bytes
;
361 wassertr(aRange
.position
< aData
->length
);
362 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
364 memset(dataBytes
+ aRange
.position
, 0, aRange
.count
);
369 WMSetData(WMData
*aData
, WMData
*anotherData
) /*FOLD00*/
371 unsigned length
= anotherData
->length
;
373 WMSetDataCapacity(aData
, length
);
375 memcpy(aData
->bytes
, anotherData
->bytes
, length
);
376 aData
->length
= length
;