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.
24 typedef struct W_Data
{
25 unsigned length
; /* How many bytes we have */
26 unsigned capacity
; /* How many bytes it can hold */
27 unsigned growth
; /* How much to grow */
28 void *bytes
; /* Actual data */
30 WMFreeDataProc
*destructor
;
31 int format
; /* 0, 8, 16 or 32 */
34 /* Creating and destroying data objects */
36 WMData
*WMCreateDataWithCapacity(unsigned capacity
)
40 aData
= (WMData
*) wmalloc(sizeof(WMData
));
43 aData
->bytes
= wmalloc(capacity
);
47 aData
->capacity
= capacity
;
48 aData
->growth
= capacity
/ 2 > 0 ? capacity
/ 2 : 1;
50 aData
->retainCount
= 1;
52 aData
->destructor
= wfree
;
57 WMData
*WMCreateDataWithLength(unsigned length
)
61 aData
= WMCreateDataWithCapacity(length
);
63 memset(aData
->bytes
, 0, length
);
64 aData
->length
= length
;
70 WMData
*WMCreateDataWithBytes(void *bytes
, unsigned length
)
74 aData
= WMCreateDataWithCapacity(length
);
75 aData
->length
= length
;
76 memcpy(aData
->bytes
, bytes
, length
);
81 WMData
*WMCreateDataWithBytesNoCopy(void *bytes
, unsigned length
, WMFreeDataProc
* destructor
)
85 aData
= (WMData
*) wmalloc(sizeof(WMData
));
86 aData
->length
= length
;
87 aData
->capacity
= length
;
88 aData
->growth
= length
/ 2 > 0 ? length
/ 2 : 1;
90 aData
->retainCount
= 1;
92 aData
->destructor
= destructor
;
97 WMData
*WMCreateDataWithData(WMData
* aData
)
101 if (aData
->length
> 0) {
102 newData
= WMCreateDataWithBytes(aData
->bytes
, aData
->length
);
104 newData
= WMCreateDataWithCapacity(0);
106 newData
->format
= aData
->format
;
111 WMData
*WMRetainData(WMData
* aData
)
113 aData
->retainCount
++;
117 void WMReleaseData(WMData
* aData
)
119 aData
->retainCount
--;
120 if (aData
->retainCount
> 0)
122 if (aData
->bytes
!= NULL
&& aData
->destructor
!= NULL
) {
123 aData
->destructor(aData
->bytes
);
128 /* Adjusting capacity */
130 void WMSetDataCapacity(WMData
* aData
, unsigned capacity
)
132 if (aData
->capacity
!= capacity
) {
133 aData
->bytes
= wrealloc(aData
->bytes
, capacity
);
134 aData
->capacity
= capacity
;
135 aData
->growth
= capacity
/ 2 > 0 ? capacity
/ 2 : 1;
137 if (aData
->length
> capacity
) {
138 aData
->length
= capacity
;
142 void WMSetDataLength(WMData
* aData
, unsigned length
)
144 if (length
> aData
->capacity
) {
145 WMSetDataCapacity(aData
, length
);
147 if (length
> aData
->length
) {
148 memset((unsigned char *)aData
->bytes
+ aData
->length
, 0, length
- aData
->length
);
150 aData
->length
= length
;
153 void WMSetDataFormat(WMData
* aData
, unsigned format
)
155 aData
->format
= format
;
158 void WMIncreaseDataLengthBy(WMData
* aData
, unsigned extraLength
)
160 WMSetDataLength(aData
, aData
->length
+ extraLength
);
165 const void *WMDataBytes(WMData
* aData
)
170 void WMGetDataBytes(WMData
* aData
, void *buffer
)
172 wassertr(aData
->length
> 0);
174 memcpy(buffer
, aData
->bytes
, aData
->length
);
177 unsigned WMGetDataFormat(WMData
* aData
)
179 return aData
->format
;
182 void WMGetDataBytesWithLength(WMData
* aData
, void *buffer
, unsigned length
)
184 wassertr(aData
->length
> 0);
185 wassertr(length
<= aData
->length
);
187 memcpy(buffer
, aData
->bytes
, length
);
190 void WMGetDataBytesWithRange(WMData
* aData
, void *buffer
, WMRange aRange
)
192 wassertr(aRange
.position
< aData
->length
);
193 wassertr(aRange
.count
<= aData
->length
- aRange
.position
);
195 memcpy(buffer
, (unsigned char *)aData
->bytes
+ aRange
.position
, aRange
.count
);
198 WMData
*WMGetSubdataWithRange(WMData
* aData
, WMRange aRange
)
203 if (aRange
.count
<= 0)
204 return WMCreateDataWithCapacity(0);
206 buffer
= wmalloc(aRange
.count
);
207 WMGetDataBytesWithRange(aData
, buffer
, aRange
);
208 newData
= WMCreateDataWithBytesNoCopy(buffer
, aRange
.count
, wfree
);
209 newData
->format
= aData
->format
;
216 Bool
WMIsDataEqualToData(WMData
* aData
, WMData
* anotherData
)
218 if (aData
->length
!= anotherData
->length
)
220 else if (!aData
->bytes
&& !anotherData
->bytes
) /* both are empty */
222 else if (!aData
->bytes
|| !anotherData
->bytes
) /* one of them is empty */
224 return (memcmp(aData
->bytes
, anotherData
->bytes
, aData
->length
) == 0);
227 unsigned WMGetDataLength(WMData
* aData
)
229 return aData
->length
;
233 void WMAppendDataBytes(WMData
* aData
, void *bytes
, unsigned length
)
235 unsigned oldLength
= aData
->length
;
236 unsigned newLength
= oldLength
+ length
;
238 if (newLength
> aData
->capacity
) {
239 unsigned nextCapacity
= aData
->capacity
+ aData
->growth
;
240 unsigned nextGrowth
= aData
->capacity
? aData
->capacity
: 1;
242 while (nextCapacity
< newLength
) {
243 unsigned tmp
= nextCapacity
+ nextGrowth
;
245 nextGrowth
= nextCapacity
;
248 WMSetDataCapacity(aData
, nextCapacity
);
249 aData
->growth
= nextGrowth
;
251 memcpy((unsigned char *)aData
->bytes
+ oldLength
, bytes
, length
);
252 aData
->length
= newLength
;
255 void WMAppendData(WMData
* aData
, WMData
* anotherData
)
257 if (anotherData
->length
> 0)
258 WMAppendDataBytes(aData
, anotherData
->bytes
, anotherData
->length
);
263 void WMReplaceDataBytesInRange(WMData
* aData
, WMRange aRange
, void *bytes
)
265 wassertr(aRange
.position
< aData
->length
);
266 wassertr(aRange
.count
<= aData
->length
- aRange
.position
);
268 memcpy((unsigned char *)aData
->bytes
+ aRange
.position
, bytes
, aRange
.count
);
271 void WMResetDataBytesInRange(WMData
* aData
, WMRange aRange
)
273 wassertr(aRange
.position
< aData
->length
);
274 wassertr(aRange
.count
<= aData
->length
- aRange
.position
);
276 memset((unsigned char *)aData
->bytes
+ aRange
.position
, 0, aRange
.count
);
279 void WMSetData(WMData
* aData
, WMData
* anotherData
)
281 unsigned length
= anotherData
->length
;
283 WMSetDataCapacity(aData
, length
);
285 memcpy(aData
->bytes
, anotherData
->bytes
, length
);
286 aData
->length
= length
;