aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/pack.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2005-01-21 16:42:45 +0000
committerChristian Grothoff <christian@grothoff.org>2005-01-21 16:42:45 +0000
commit7166eaa7ff40782f89aca81bf30e2e4ceac7fb76 (patch)
tree146f465aaa565a327fb3a3dd85c3b5eb7900d497 /src/plugins/pack.c
downloadlibextractor-7166eaa7ff40782f89aca81bf30e2e4ceac7fb76.tar.gz
libextractor-7166eaa7ff40782f89aca81bf30e2e4ceac7fb76.zip
Importing libextractor.
Diffstat (limited to 'src/plugins/pack.c')
-rw-r--r--src/plugins/pack.c469
1 files changed, 469 insertions, 0 deletions
diff --git a/src/plugins/pack.c b/src/plugins/pack.c
new file mode 100644
index 0000000..e7bae79
--- /dev/null
+++ b/src/plugins/pack.c
@@ -0,0 +1,469 @@
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
30typedef unsigned char byte;
31typedef unsigned short half;
32typedef unsigned long word;
33typedef signed char sbyte;
34typedef signed short shalf;
35typedef signed long sword;
36
37
38/*
39 "bhwAcslPBHWCSL"
40
41 Small letters: do not convert (not implemented for arrays and P)
42 Captial letters: convert from network byte order to host byte order
43
44 b - byte
45 h - half-word
46 w - word
47 a - array (32-byte unsigned long + that many bytes)
48 c - signed 8 bit value
49 s - signed 16 bit value
50 l - signed 32 bit value
51 p - (unpack only) value is a pointer to a pointer. Generate the buffer
52 to hold the data.
53
54 prefixing with a number K means that the argument will be an array of K
55 of the arguments specified by the letter
56 */
57
58int cat_pack(void * buf,
59 const char *fmt,
60 ...) {
61 va_list ap;
62 word blen, val;
63 int npacked;
64 unsigned int nreps, i;
65 byte *bp, *bytep;
66 half *halfp;
67 word *wordp;
68 void * arr;
69 struct cat_bvec *cbvp;
70 char *cp;
71
72 va_start(ap, fmt);
73
74 npacked = 0;
75 bp = (byte *)buf;
76
77 while( *fmt ) {
78 nreps = 0;
79
80 if ( isdigit(*fmt) ) {
81 /* We use cp instead of fmt to keep the 'const' qualifier of fmt */
82 nreps = strtoul(fmt, &cp, 0);
83 fmt = cp;
84 }
85
86 switch(*fmt) {
87 case 'B':
88 case 'b':
89 case 'C':
90 case 'c':
91 if ( ! nreps ) {
92 *bp++ = va_arg(ap, int);
93 npacked += 1;
94 } else {
95 bytep = va_arg(ap, byte*);
96 for ( i = 0 ; i < nreps ; ++i ) {
97 *bp++ = bytep[i];
98 npacked += 1;
99 }
100 }
101 break;
102
103 case 'h':
104 case 's':
105 if ( ! nreps ) {
106 val = va_arg(ap, int);
107 *bp++ = val & 0xFF;
108 *bp++ = val >> 8;
109 npacked += 2;
110 } else {
111 halfp = va_arg(ap, half*);
112 for ( i = 0 ; i < nreps ; ++i ) {
113 val = halfp[i];
114 *bp++ = val & 0xFF;
115 *bp++ = val >> 8;
116 npacked += 2;
117 }
118 }
119 break;
120
121 case 'H':
122 case 'S':
123 if ( ! nreps ) {
124 val = va_arg(ap, int);
125 *bp++ = val >> 8;
126 *bp++ = val & 0xFF;
127 npacked += 2;
128 } else {
129 halfp = va_arg(ap, half*);
130 for ( i = 0 ; i < nreps ; ++i ) {
131 val = halfp[i];
132 *bp++ = val >> 8;
133 *bp++ = val & 0xFF;
134 npacked += 2;
135 }
136 }
137 break;
138
139 case 'l':
140 case 'w':
141 if ( ! nreps ) {
142 val = va_arg(ap, word);
143 *bp++ = val & 0xFF;
144 *bp++ = val >> 8;
145 *bp++ = val >> 16;
146 *bp++ = val >> 24;
147 npacked += 4;
148 } else {
149 wordp = va_arg(ap, word*);
150 for ( i = 0 ; i < nreps ; ++i ) {
151 val = wordp[i];
152 *bp++ = val & 0xFF;
153 *bp++ = val >> 8;
154 *bp++ = val >> 16;
155 *bp++ = val >> 24;
156 npacked += 4;
157 }
158 }
159 break;
160
161 case 'L':
162 case 'W':
163 if ( ! nreps ) {
164 val = va_arg(ap, word);
165 *bp++ = val >> 24;
166 *bp++ = val >> 16;
167 *bp++ = val >> 8;
168 *bp++ = val & 0xFF;
169 npacked += 4;
170 } else {
171 wordp = va_arg(ap, word*);
172 for ( i = 0 ; i < nreps ; ++i ) {
173 val = wordp[i];
174 *bp++ = val >> 24;
175 *bp++ = val >> 16;
176 *bp++ = val >> 8;
177 *bp++ = val & 0xFF;
178 npacked += 4;
179 }
180 }
181 break;
182
183 case 'A':
184 if ( ! nreps ) {
185 blen = va_arg(ap, word);
186 arr = va_arg(ap, void *);
187 *bp++ = blen >> 24;
188 *bp++ = blen >> 16;
189 *bp++ = blen >> 8;
190 *bp++ = blen & 0xFF;
191 memmove(bp, arr, blen);
192 bp += blen;
193 npacked += blen + 4; /* +4 for the 32 bits of length field */
194 } else {
195 cbvp = va_arg(ap, struct cat_bvec*);
196 for ( i = 0 ; i < nreps ; ++i ) {
197 blen = cbvp[i].len;
198 arr = cbvp[i].data;
199 *bp++ = blen >> 24;
200 *bp++ = blen >> 16;
201 *bp++ = blen >> 8;
202 *bp++ = blen & 0xFF;
203 memmove(bp, arr, blen);
204 bp += blen;
205 npacked += blen + 4; /* see above */
206 }
207 }
208 break;
209
210 default:
211 va_end(ap);
212 return -1;
213 }
214 ++fmt;
215 }
216
217 va_end(ap);
218 return npacked;
219}
220
221
222
223int cat_unpack(const void * buf,
224 const char *fmt,
225 ...) {
226 va_list ap;
227 word maxlen, len, *wordp;
228 void * arr;
229 byte *bp, *bytep, *newbuf;
230 half *halfp;
231 sbyte *sbytep;
232 shalf *shalfp;
233 sword *swordp;
234 int npacked;
235 unsigned int nreps, i, isnonprefixed = 1; /* used for 'a' types only */
236 struct cat_bvec *cbvp;
237 char *cp;
238
239 bp = (byte *)buf;
240 npacked = 0;
241
242 va_start(ap, fmt);
243
244 while ( *fmt ) {
245 nreps = 1;
246
247 if ( isdigit(*fmt) ) {
248 /* We use cp instead of format to keep the 'const' qualifier of fmt */
249 nreps = strtoul(fmt, &cp, 0);
250 fmt = cp;
251 if ( *fmt == 'a' )
252 isnonprefixed = 0;
253 }
254
255 switch (*fmt) {
256 case 'B':
257 case 'b':
258 bytep = va_arg(ap, byte*);
259 for ( i = 0 ; i < nreps ; ++i ) {
260 *bytep = *bp++;
261 ++bytep;
262 npacked += 1;
263 }
264 break;
265
266
267
268 case 'h':
269 halfp = va_arg(ap, half*);
270 for ( i = 0 ; i < nreps ; ++i ) {
271 *halfp = *bp++;
272 *halfp |= *bp++ << 8;
273 ++halfp;
274 npacked += 2;
275 }
276 break;
277
278 case 'H':
279 halfp = va_arg(ap, half*);
280 for ( i = 0 ; i < nreps ; ++i ) {
281 *halfp = *bp++ << 8;
282 *halfp |= *bp++;
283 ++halfp;
284 npacked += 2;
285 }
286 break;
287
288
289 case 'w':
290 wordp = va_arg(ap, word*);
291 for ( i = 0 ; i < nreps ; ++i ) {
292 *wordp = *bp++;
293 *wordp |= *bp++ << 8;
294 *wordp |= *bp++ << 16;
295 *wordp |= *bp++ << 24;
296 ++wordp;
297 npacked += 4;
298 }
299 break;
300
301 case 'W':
302 wordp = va_arg(ap, word*);
303 for ( i = 0 ; i < nreps ; ++i ) {
304 *wordp = *bp++ << 24;
305 *wordp |= *bp++ << 16;
306 *wordp |= *bp++ << 8;
307 *wordp |= *bp++;
308 ++wordp;
309 npacked += 4;
310 }
311 break;
312
313 case 'A':
314 if ( isnonprefixed ) {
315 maxlen = va_arg(ap, word);
316 arr = va_arg(ap, void *);
317
318 len = *bp++ << 24;
319 len |= *bp++ << 16;
320 len |= *bp++ << 8;
321 len |= *bp++;
322
323 if ( len > maxlen )
324 return -1;
325
326 memmove(arr, bp, len);
327 bp += len;
328
329 npacked += len;
330 } else {
331 cbvp = va_arg(ap, struct cat_bvec *);
332 for ( i = 0 ; i < nreps ; ++i ) {
333 maxlen = cbvp->len;
334 arr = cbvp->data;
335
336 len = *bp++ << 24;
337 len |= *bp++ << 16;
338 len |= *bp++ << 8;
339 len |= *bp++;
340
341 if ( len > maxlen )
342 return -1;
343
344 memmove(arr, bp, len);
345 cbvp->len = len;
346 bp += len;
347
348 ++cbvp;
349 npacked += len;
350 }
351 isnonprefixed = 1;
352 }
353 break;
354
355 case 'C':
356 case 'c':
357 sbytep = va_arg(ap, sbyte*);
358 for ( i = 0 ; i < nreps ; ++i ) {
359 *sbytep = *bp++;
360
361 if ( (sizeof(sbyte) > 1) && (*sbytep & 0x80) )
362 *sbytep |= (~0) << ((sizeof(sbyte)-1) * 8);
363
364 ++sbytep;
365 npacked += 1;
366 }
367 break;
368
369
370 case 's':
371 shalfp = va_arg(ap, shalf*);
372 for ( i = 0 ; i < nreps ; ++i ) {
373 *shalfp = *bp++;
374 *shalfp |= *bp++ << 8;
375
376 if ( (sizeof(shalf) > 2) && (*shalfp & 0x8000) )
377 *shalfp |= (~0) << ((sizeof(shalf)-2) * 8);
378
379 ++shalfp;
380 npacked += 2;
381 }
382 break;
383
384 case 'S':
385 shalfp = va_arg(ap, shalf*);
386 for ( i = 0 ; i < nreps ; ++i ) {
387 *shalfp = *bp++ << 8;
388 *shalfp |= *bp++;
389
390 if ( (sizeof(shalf) > 2) && (*shalfp & 0x8000) )
391 *shalfp |= (~0) << ((sizeof(shalf)-2) * 8);
392
393 ++shalfp;
394 npacked += 2;
395 }
396 break;
397
398 case 'l':
399 swordp = va_arg(ap, sword*);
400 for ( i = 0 ; i < nreps ; ++i ) {
401 *swordp = *bp++;
402 *swordp |= *bp++ << 8;
403 *swordp |= *bp++ << 16;
404 *swordp |= *bp++ << 24;
405
406 if ( (sizeof(swordp) > 4) && (*swordp & 0x80000000) )
407 *swordp |= (~0) << ((sizeof(sword)-4) * 8);
408
409 ++swordp;
410 npacked += 4;
411 }
412 break;
413
414 case 'L':
415 swordp = va_arg(ap, sword*);
416 for ( i = 0 ; i < nreps ; ++i ) {
417 *swordp = *bp++ << 24;
418 *swordp |= *bp++ << 16;
419 *swordp |= *bp++ << 8;
420 *swordp |= *bp++;
421
422 if ( (sizeof(swordp) > 4) && (*swordp & 0x80000000) )
423 *swordp |= (~0) << ((sizeof(sword)-4) * 8);
424
425 ++swordp;
426 npacked += 4;
427 }
428 break;
429
430 case 'P':
431 cbvp = va_arg(ap, struct cat_bvec *);
432 for ( i = 0 ; i < nreps ; ++i ) {
433 len = *bp++ << 24;
434 len |= *bp++ << 16;
435 len |= *bp++ << 8;
436 len |= *bp++;
437
438 newbuf = (byte *)malloc(len);
439
440 if ( ! newbuf ) {
441 int j;
442 for ( j = 0 ; j < i ; j++ )
443 free(cbvp[i].data);
444 return -1;
445 }
446
447 memmove(newbuf, bp, len);
448 cbvp[i].data = newbuf;
449 cbvp[i].len = len;
450
451 bp += len;
452 npacked += len;
453 }
454 break;
455
456 default:
457 va_end(ap);
458 return -1;
459 }
460
461 ++fmt;
462 }
463
464 va_end(ap);
465 return 0;
466}
467
468
469