2 * WINGs WMData function library
4 * Copyright (c) 1999-2003 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 */
40 /* Creating and destroying data objects */
43 WMCreateDataWithCapacity(unsigned capacity
)
47 aData
= (WMData
*)wmalloc(sizeof(WMData
));
50 aData
->bytes
= wmalloc(capacity
);
54 aData
->capacity
= capacity
;
55 aData
->growth
= capacity
/2 > 0 ? capacity
/2 : 1;
57 aData
->retainCount
= 1;
59 aData
->destructor
= wfree
;
66 WMCreateDataWithLength(unsigned length
)
70 aData
= WMCreateDataWithCapacity(length
);
72 memset(aData
->bytes
, 0, length
);
73 aData
->length
= length
;
81 WMCreateDataWithBytes(void *bytes
, unsigned length
)
85 aData
= WMCreateDataWithCapacity(length
);
86 aData
->length
= length
;
87 memcpy(aData
->bytes
, bytes
, length
);
94 WMCreateDataWithBytesNoCopy(void *bytes
, unsigned length
,
95 WMFreeDataProc
*destructor
)
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;
106 aData
->destructor
= destructor
;
113 WMCreateDataWithData(WMData
*aData
)
117 if (aData
->length
> 0) {
118 newData
= WMCreateDataWithBytes(aData
->bytes
, aData
->length
);
120 newData
= WMCreateDataWithCapacity(0);
122 newData
->format
= aData
->format
;
129 WMRetainData(WMData
*aData
)
131 aData
->retainCount
++;
137 WMReleaseData(WMData
*aData
)
139 aData
->retainCount
--;
140 if (aData
->retainCount
> 0)
142 if (aData
->bytes
!=NULL
&& aData
->destructor
!=NULL
) {
143 aData
->destructor(aData
->bytes
);
150 /* Adjusting capacity */
153 WMSetDataCapacity(WMData
*aData
, unsigned capacity
)
155 if (aData
->capacity
!= capacity
) {
156 aData
->bytes
= wrealloc(aData
->bytes
, capacity
);
157 aData
->capacity
= capacity
;
158 aData
->growth
= capacity
/2 > 0 ? capacity
/2 : 1;
160 if (aData
->length
> capacity
) {
161 aData
->length
= capacity
;
167 WMSetDataLength(WMData
*aData
, unsigned length
)
169 if (length
> aData
->capacity
) {
170 WMSetDataCapacity(aData
, length
);
172 if (length
> aData
->length
) {
173 memset((unsigned char*)aData
->bytes
+ aData
->length
, 0,
174 length
- aData
->length
);
176 aData
->length
= length
;
181 WMSetDataFormat(WMData
*aData
, unsigned format
)
183 aData
->format
= format
;
188 WMIncreaseDataLengthBy(WMData
*aData
, unsigned extraLength
)
190 WMSetDataLength(aData
, aData
->length
+ extraLength
);
197 WMDataBytes(WMData
*aData
)
204 WMGetDataBytes(WMData
*aData
, void *buffer
)
206 wassertr(aData
->length
> 0);
208 memcpy(buffer
, aData
->bytes
, aData
->length
);
213 WMGetDataFormat(WMData
*aData
)
215 return aData
->format
;
220 WMGetDataBytesWithLength(WMData
*aData
, void *buffer
, unsigned length
)
222 wassertr(aData
->length
> 0);
223 wassertr(length
<= aData
->length
);
225 memcpy(buffer
, aData
->bytes
, length
);
230 WMGetDataBytesWithRange(WMData
*aData
, void *buffer
, WMRange aRange
)
232 wassertr(aRange
.position
< aData
->length
);
233 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
235 memcpy(buffer
, (unsigned char*)aData
->bytes
+ aRange
.position
,
241 WMGetSubdataWithRange(WMData
*aData
, WMRange aRange
)
246 if (aRange
.count
<= 0)
247 return WMCreateDataWithCapacity(0);
249 buffer
= wmalloc(aRange
.count
);
250 WMGetDataBytesWithRange(aData
, buffer
, aRange
);
251 newData
= WMCreateDataWithBytesNoCopy(buffer
, aRange
.count
, wfree
);
252 newData
->format
= aData
->format
;
261 WMIsDataEqualToData(WMData
*aData
, WMData
*anotherData
)
263 if (aData
->length
!= anotherData
->length
)
265 else if (!aData
->bytes
&& !anotherData
->bytes
) /* both are empty */
267 else if (!aData
->bytes
|| !anotherData
->bytes
) /* one of them is empty */
269 return (memcmp(aData
->bytes
, anotherData
->bytes
, aData
->length
)==0);
274 WMGetDataLength(WMData
*aData
)
276 return aData
->length
;
282 WMAppendDataBytes(WMData
*aData
, void *bytes
, unsigned length
)
284 unsigned oldLength
= aData
->length
;
285 unsigned newLength
= oldLength
+ length
;
287 if (newLength
> aData
->capacity
) {
288 unsigned nextCapacity
= aData
->capacity
+ aData
->growth
;
289 unsigned nextGrowth
= aData
->capacity
? aData
->capacity
: 1;
291 while (nextCapacity
< newLength
) {
292 unsigned tmp
= nextCapacity
+ nextGrowth
;
294 nextGrowth
= nextCapacity
;
297 WMSetDataCapacity(aData
, nextCapacity
);
298 aData
->growth
= nextGrowth
;
300 memcpy((unsigned char*)aData
->bytes
+ oldLength
, bytes
, length
);
301 aData
->length
= newLength
;
306 WMAppendData(WMData
*aData
, WMData
*anotherData
)
308 if (anotherData
->length
> 0)
309 WMAppendDataBytes(aData
, anotherData
->bytes
, anotherData
->length
);
317 WMReplaceDataBytesInRange(WMData
*aData
, WMRange aRange
, void *bytes
)
319 wassertr(aRange
.position
< aData
->length
);
320 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
322 memcpy((unsigned char*)aData
->bytes
+ aRange
.position
, bytes
, aRange
.count
);
327 WMResetDataBytesInRange(WMData
*aData
, WMRange aRange
)
329 wassertr(aRange
.position
< aData
->length
);
330 wassertr(aRange
.count
<= aData
->length
-aRange
.position
);
332 memset((unsigned char*)aData
->bytes
+ aRange
.position
, 0, aRange
.count
);
337 WMSetData(WMData
*aData
, WMData
*anotherData
)
339 unsigned length
= anotherData
->length
;
341 WMSetDataCapacity(aData
, length
);
343 memcpy(aData
->bytes
, anotherData
->bytes
, length
);
344 aData
->length
= length
;