aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/old/pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/old/pack.c')
-rw-r--r--src/plugins/old/pack.c345
1 files changed, 345 insertions, 0 deletions
diff --git a/src/plugins/old/pack.c b/src/plugins/old/pack.c
new file mode 100644
index 0000000..968cf67
--- /dev/null
+++ b/src/plugins/old/pack.c
@@ -0,0 +1,345 @@
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
40
41int
42EXTRACTOR_common_cat_unpack (const void *buf,
43 const char *fmt,
44 ...)
45{
46 va_list ap;
47 word maxlen, len, *wordp;
48 void *arr;
49 byte *bp, *bytep, *newbuf;
50 half *halfp;
51 long long *ll;
52 sbyte *sbytep;
53 shalf *shalfp;
54 sword *swordp;
55 int npacked;
56 unsigned int nreps, i, isnonprefixed = 1; /* used for 'a' types only */
57 struct cat_bvec *cbvp;
58 char *cp;
59
60 bp = (byte *) buf;
61 npacked = 0;
62
63 va_start (ap, fmt);
64
65 while (*fmt)
66 {
67 nreps = 1;
68
69 if (isdigit ( (unsigned char) *fmt))
70 {
71 /* We use cp instead of format to keep the 'const' qualifier of fmt */
72 nreps = strtoul (fmt, &cp, 0);
73 fmt = cp;
74 if (*fmt == 'a')
75 isnonprefixed = 0;
76 }
77
78 switch (*fmt)
79 {
80 case 'B':
81 case 'b':
82 bytep = va_arg (ap, byte *);
83 for (i = 0; i < nreps; ++i)
84 {
85 *bytep = *bp++;
86 ++bytep;
87 npacked += 1;
88 }
89 break;
90
91
92
93 case 'h':
94 halfp = va_arg (ap, half *);
95 for (i = 0; i < nreps; ++i)
96 {
97 *halfp = *bp++;
98 *halfp |= *bp++ << 8;
99 ++halfp;
100 npacked += 2;
101 }
102 break;
103
104 case 'H':
105 halfp = va_arg (ap, half *);
106 for (i = 0; i < nreps; ++i)
107 {
108 *halfp = *bp++ << 8;
109 *halfp |= *bp++;
110 ++halfp;
111 npacked += 2;
112 }
113 break;
114
115
116 case 'w':
117 wordp = va_arg (ap, word *);
118 for (i = 0; i < nreps; ++i)
119 {
120 *wordp = *bp++;
121 *wordp |= *bp++ << 8;
122 *wordp |= *bp++ << 16;
123 *wordp |= *bp++ << 24;
124 ++wordp;
125 npacked += 4;
126 }
127 break;
128
129 case 'x':
130 ll = va_arg (ap, long long *);
131 for (i = 0; i < nreps; ++i)
132 {
133 *ll = ((long long) *bp++);
134 *ll |= ((long long) *bp++) << 8;
135 *ll |= ((long long) *bp++) << 16;
136 *ll |= ((long long) *bp++) << 24;
137 *ll |= ((long long) *bp++) << 32;
138 *ll |= ((long long) *bp++) << 40;
139 *ll |= ((long long) *bp++) << 48;
140 *ll |= ((long long) *bp++) << 56;
141 ++ll;
142 npacked += 8;
143 }
144 break;
145
146 case 'W':
147 wordp = va_arg (ap, word *);
148 for (i = 0; i < nreps; ++i)
149 {
150 *wordp = *bp++ << 24;
151 *wordp |= *bp++ << 16;
152 *wordp |= *bp++ << 8;
153 *wordp |= *bp++;
154 ++wordp;
155 npacked += 4;
156 }
157 break;
158
159 case 'X':
160 ll = va_arg (ap, long long *);
161 for (i = 0; i < nreps; ++i)
162 {
163 *ll = ((long long) *bp++) << 56;
164 *ll |= ((long long) *bp++) << 48;
165 *ll |= ((long long) *bp++) << 40;
166 *ll |= ((long long) *bp++) << 32;
167 *ll |= ((long long) *bp++) << 24;
168 *ll |= ((long long) *bp++) << 18;
169 *ll |= ((long long) *bp++) << 8;
170 *ll |= ((long long) *bp++);
171 ++ll;
172 npacked += 8;
173 }
174 break;
175
176
177 case 'A':
178 if (isnonprefixed)
179 {
180 maxlen = va_arg (ap, word);
181 arr = va_arg (ap, void *);
182
183 len = *bp++ << 24;
184 len |= *bp++ << 16;
185 len |= *bp++ << 8;
186 len |= *bp++;
187
188 if (len > maxlen)
189 {
190 va_end (ap);
191 return -1;
192 }
193
194 memmove (arr, bp, len);
195 bp += len;
196
197 npacked += len;
198 }
199 else
200 {
201 cbvp = va_arg (ap, struct cat_bvec *);
202 for (i = 0; i < nreps; ++i)
203 {
204 maxlen = cbvp->len;
205 arr = cbvp->data;
206
207 len = *bp++ << 24;
208 len |= *bp++ << 16;
209 len |= *bp++ << 8;
210 len |= *bp++;
211
212 if (len > maxlen)
213 return -1;
214
215 memmove (arr, bp, len);
216 cbvp->len = len;
217 bp += len;
218
219 ++cbvp;
220 npacked += len;
221 }
222 isnonprefixed = 1;
223 }
224 break;
225
226 case 'C':
227 case 'c':
228 sbytep = va_arg (ap, sbyte *);
229 for (i = 0; i < nreps; ++i)
230 {
231 *sbytep = *bp++;
232
233 if ((sizeof (sbyte) > 1) && (*sbytep & 0x80))
234 *sbytep |= (~0) << ((sizeof (sbyte) - 1) * 8);
235
236 ++sbytep;
237 npacked += 1;
238 }
239 break;
240
241
242 case 's':
243 shalfp = va_arg (ap, shalf *);
244 for (i = 0; i < nreps; ++i)
245 {
246 *shalfp = *bp++;
247 *shalfp |= *bp++ << 8;
248
249 if ((sizeof (shalf) > 2) && (*shalfp & 0x8000))
250 *shalfp |= (~0) << ((sizeof (shalf) - 2) * 8);
251
252 ++shalfp;
253 npacked += 2;
254 }
255 break;
256
257 case 'S':
258 shalfp = va_arg (ap, shalf *);
259 for (i = 0; i < nreps; ++i)
260 {
261 *shalfp = *bp++ << 8;
262 *shalfp |= *bp++;
263
264 if ((sizeof (shalf) > 2) && (*shalfp & 0x8000))
265 *shalfp |= (~0) << ((sizeof (shalf) - 2) * 8);
266
267 ++shalfp;
268 npacked += 2;
269 }
270 break;
271
272 case 'l':
273 swordp = va_arg (ap, sword *);
274 for (i = 0; i < nreps; ++i)
275 {
276 *swordp = *bp++;
277 *swordp |= *bp++ << 8;
278 *swordp |= *bp++ << 16;
279 *swordp |= *bp++ << 24;
280
281 if ((sizeof (swordp) > 4) && (*swordp & 0x80000000))
282 *swordp |= (~0) << ((sizeof (sword) - 4) * 8);
283
284 ++swordp;
285 npacked += 4;
286 }
287 break;
288
289 case 'L':
290 swordp = va_arg (ap, sword *);
291 for (i = 0; i < nreps; ++i)
292 {
293 *swordp = *bp++ << 24;
294 *swordp |= *bp++ << 16;
295 *swordp |= *bp++ << 8;
296 *swordp |= *bp++;
297
298 if ((sizeof (swordp) > 4) && (*swordp & 0x80000000))
299 *swordp |= (~0) << ((sizeof (sword) - 4) * 8);
300
301 ++swordp;
302 npacked += 4;
303 }
304 break;
305
306 case 'P':
307 cbvp = va_arg (ap, struct cat_bvec *);
308 for (i = 0; i < nreps; ++i)
309 {
310 len = *bp++ << 24;
311 len |= *bp++ << 16;
312 len |= *bp++ << 8;
313 len |= *bp++;
314
315 newbuf = (byte *) malloc (len);
316
317 if (!newbuf)
318 {
319 int j;
320 for (j = 0; j < i; j++)
321 free (cbvp[i].data);
322 va_end (ap);
323 return -1;
324 }
325
326 memmove (newbuf, bp, len);
327 cbvp[i].data = newbuf;
328 cbvp[i].len = len;
329
330 bp += len;
331 npacked += len;
332 }
333 break;
334
335 default:
336 va_end (ap);
337 return -1;
338 }
339
340 ++fmt;
341 }
342
343 va_end (ap);
344 return 0;
345}