aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/pack.c')
-rw-r--r--src/plugins/pack.c343
1 files changed, 343 insertions, 0 deletions
diff --git a/src/plugins/pack.c b/src/plugins/pack.c
new file mode 100644
index 0000000..4f9e19d
--- /dev/null
+++ b/src/plugins/pack.c
@@ -0,0 +1,343 @@
1/*
2Catlib Copyright Notice
3
4The author of this software is Christopher Adam Telfer
5Copyright (c) 1998, 1999, 2000, 2001, 2002
6by Christopher Adam Telfer. All Rights Reserved.
7
8Permission to use, copy, modify, and distribute this software for any
9purpose without fee is hereby granted, provided that the above copyright
10notice, this paragraph, and the following two paragraphs appear in all
11copies, modifications, and distributions.
12
13IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
14SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
15ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
16THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17
18THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
19LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
21ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO
22OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
23MODIFICATIONS.
24
25*/
26
27#include "platform.h"
28#include "pack.h"
29
30#if ! (defined(_WIN32) && defined(cbNDRContext))
31typedef unsigned char byte;
32#endif
33typedef unsigned short half;
34typedef unsigned int word;
35typedef signed char sbyte;
36typedef signed short shalf;
37typedef signed int sword;
38
39
40int
41EXTRACTOR_common_cat_unpack (const void *buf,
42 const char *fmt,
43 ...)
44{
45 va_list ap;
46 word maxlen, len, *wordp;
47 void *arr;
48 byte *bp, *bytep, *newbuf;
49 half *halfp;
50 long long *ll;
51 sbyte *sbytep;
52 shalf *shalfp;
53 sword *swordp;
54 int npacked;
55 unsigned int nreps, i, isnonprefixed = 1; /* used for 'a' types only */
56 struct cat_bvec *cbvp;
57 char *cp;
58
59 bp = (byte *) buf;
60 npacked = 0;
61
62 va_start (ap, fmt);
63
64 while (*fmt)
65 {
66 nreps = 1;
67
68 if (isdigit ( (unsigned char) *fmt))
69 {
70 /* We use cp instead of format to keep the 'const' qualifier of fmt */
71 nreps = strtoul (fmt, &cp, 0);
72 fmt = cp;
73 if (*fmt == 'a')
74 isnonprefixed = 0;
75 }
76
77 switch (*fmt)
78 {
79 case 'B':
80 case 'b':
81 bytep = va_arg (ap, byte *);
82 for (i = 0; i < nreps; ++i)
83 {
84 *bytep = *bp++;
85 ++bytep;
86 npacked += 1;
87 }
88 break;
89
90
91 case 'h':
92 halfp = va_arg (ap, half *);
93 for (i = 0; i < nreps; ++i)
94 {
95 *halfp = *bp++;
96 *halfp |= *bp++ << 8;
97 ++halfp;
98 npacked += 2;
99 }
100 break;
101
102 case 'H':
103 halfp = va_arg (ap, half *);
104 for (i = 0; i < nreps; ++i)
105 {
106 *halfp = *bp++ << 8;
107 *halfp |= *bp++;
108 ++halfp;
109 npacked += 2;
110 }
111 break;
112
113
114 case 'w':
115 wordp = va_arg (ap, word *);
116 for (i = 0; i < nreps; ++i)
117 {
118 *wordp = *bp++;
119 *wordp |= *bp++ << 8;
120 *wordp |= *bp++ << 16;
121 *wordp |= *bp++ << 24;
122 ++wordp;
123 npacked += 4;
124 }
125 break;
126
127 case 'x':
128 ll = va_arg (ap, long long *);
129 for (i = 0; i < nreps; ++i)
130 {
131 *ll = ((long long) *bp++);
132 *ll |= ((long long) *bp++) << 8;
133 *ll |= ((long long) *bp++) << 16;
134 *ll |= ((long long) *bp++) << 24;
135 *ll |= ((long long) *bp++) << 32;
136 *ll |= ((long long) *bp++) << 40;
137 *ll |= ((long long) *bp++) << 48;
138 *ll |= ((long long) *bp++) << 56;
139 ++ll;
140 npacked += 8;
141 }
142 break;
143
144 case 'W':
145 wordp = va_arg (ap, word *);
146 for (i = 0; i < nreps; ++i)
147 {
148 *wordp = *bp++ << 24;
149 *wordp |= *bp++ << 16;
150 *wordp |= *bp++ << 8;
151 *wordp |= *bp++;
152 ++wordp;
153 npacked += 4;
154 }
155 break;
156
157 case 'X':
158 ll = va_arg (ap, long long *);
159 for (i = 0; i < nreps; ++i)
160 {
161 *ll = ((long long) *bp++) << 56;
162 *ll |= ((long long) *bp++) << 48;
163 *ll |= ((long long) *bp++) << 40;
164 *ll |= ((long long) *bp++) << 32;
165 *ll |= ((long long) *bp++) << 24;
166 *ll |= ((long long) *bp++) << 18;
167 *ll |= ((long long) *bp++) << 8;
168 *ll |= ((long long) *bp++);
169 ++ll;
170 npacked += 8;
171 }
172 break;
173
174
175 case 'A':
176 if (isnonprefixed)
177 {
178 maxlen = va_arg (ap, word);
179 arr = va_arg (ap, void *);
180
181 len = *bp++ << 24;
182 len |= *bp++ << 16;
183 len |= *bp++ << 8;
184 len |= *bp++;
185
186 if (len > maxlen)
187 {
188 va_end (ap);
189 return -1;
190 }
191
192 memmove (arr, bp, len);
193 bp += len;
194
195 npacked += len;
196 }
197 else
198 {
199 cbvp = va_arg (ap, struct cat_bvec *);
200 for (i = 0; i < nreps; ++i)
201 {
202 maxlen = cbvp->len;
203 arr = cbvp->data;
204
205 len = *bp++ << 24;
206 len |= *bp++ << 16;
207 len |= *bp++ << 8;
208 len |= *bp++;
209
210 if (len > maxlen)
211 return -1;
212
213 memmove (arr, bp, len);
214 cbvp->len = len;
215 bp += len;
216
217 ++cbvp;
218 npacked += len;
219 }
220 isnonprefixed = 1;
221 }
222 break;
223
224 case 'C':
225 case 'c':
226 sbytep = va_arg (ap, sbyte *);
227 for (i = 0; i < nreps; ++i)
228 {
229 *sbytep = *bp++;
230
231 if ((sizeof (sbyte) > 1) && (*sbytep & 0x80))
232 *sbytep |= (~0) << ((sizeof (sbyte) - 1) * 8);
233
234 ++sbytep;
235 npacked += 1;
236 }
237 break;
238
239
240 case 's':
241 shalfp = va_arg (ap, shalf *);
242 for (i = 0; i < nreps; ++i)
243 {
244 *shalfp = *bp++;
245 *shalfp |= *bp++ << 8;
246
247 if ((sizeof (shalf) > 2) && (*shalfp & 0x8000))
248 *shalfp |= (~0) << ((sizeof (shalf) - 2) * 8);
249
250 ++shalfp;
251 npacked += 2;
252 }
253 break;
254
255 case 'S':
256 shalfp = va_arg (ap, shalf *);
257 for (i = 0; i < nreps; ++i)
258 {
259 *shalfp = *bp++ << 8;
260 *shalfp |= *bp++;
261
262 if ((sizeof (shalf) > 2) && (*shalfp & 0x8000))
263 *shalfp |= (~0) << ((sizeof (shalf) - 2) * 8);
264
265 ++shalfp;
266 npacked += 2;
267 }
268 break;
269
270 case 'l':
271 swordp = va_arg (ap, sword *);
272 for (i = 0; i < nreps; ++i)
273 {
274 *swordp = *bp++;
275 *swordp |= *bp++ << 8;
276 *swordp |= *bp++ << 16;
277 *swordp |= *bp++ << 24;
278
279 if ((sizeof (swordp) > 4) && (*swordp & 0x80000000))
280 *swordp |= (~0) << ((sizeof (sword) - 4) * 8);
281
282 ++swordp;
283 npacked += 4;
284 }
285 break;
286
287 case 'L':
288 swordp = va_arg (ap, sword *);
289 for (i = 0; i < nreps; ++i)
290 {
291 *swordp = *bp++ << 24;
292 *swordp |= *bp++ << 16;
293 *swordp |= *bp++ << 8;
294 *swordp |= *bp++;
295
296 if ((sizeof (swordp) > 4) && (*swordp & 0x80000000))
297 *swordp |= (~0) << ((sizeof (sword) - 4) * 8);
298
299 ++swordp;
300 npacked += 4;
301 }
302 break;
303
304 case 'P':
305 cbvp = va_arg (ap, struct cat_bvec *);
306 for (i = 0; i < nreps; ++i)
307 {
308 len = *bp++ << 24;
309 len |= *bp++ << 16;
310 len |= *bp++ << 8;
311 len |= *bp++;
312
313 newbuf = (byte *) malloc (len);
314
315 if (! newbuf)
316 {
317 int j;
318 for (j = 0; j < i; j++)
319 free (cbvp[i].data);
320 va_end (ap);
321 return -1;
322 }
323
324 memmove (newbuf, bp, len);
325 cbvp[i].data = newbuf;
326 cbvp[i].len = len;
327
328 bp += len;
329 npacked += len;
330 }
331 break;
332
333 default:
334 va_end (ap);
335 return -1;
336 }
337
338 ++fmt;
339 }
340
341 va_end (ap);
342 return 0;
343}