~ubuntu-branches/ubuntu/natty/libextractor/natty

« back to all changes in this revision

Viewing changes to src/common/pack.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2009-11-17 20:27:32 UTC
  • mfrom: (1.10.4 upstream) (5.2.5 sid)
  • Revision ID: james.westby@ubuntu.com-20091117202732-ipm2h3gks5bdw2vx
Tags: 0.5.23+dfsg-3
* Building against libltdl7.
* Updating to standards version 3.8.3.
* Adding maintainer homepage field to control.
* Marking maintainer homepage field to be also included in binary
  packages and changelog.
* Adding README.source.
* Simplifying autotools handling in rules.
* Updating README.source.
* Moving maintainer homepage field from control to copyright.
* Dropping la files.
* Simplyfing debhelper install files.
* Bumping versioned build-depends on debhelper.
* Adding depends to dpkg install info.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Catlib Copyright Notice
 
3
 
 
4
The author of this software is Christopher Adam Telfer
 
5
Copyright (c) 1998, 1999, 2000, 2001, 2002
 
6
by Christopher Adam Telfer.  All Rights Reserved.
 
7
 
 
8
Permission to use, copy, modify, and distribute this software for any
 
9
purpose without fee is hereby granted, provided that the above copyright
 
10
notice, this paragraph, and the following two paragraphs appear in all
 
11
copies, modifications, and distributions.
 
12
 
 
13
IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 
14
SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 
15
ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 
16
THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
17
 
 
18
THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
 
19
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 
20
PARTICULAR PURPOSE.  THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF
 
21
ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS".   THE AUTHOR HAS NO
 
22
OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
 
23
MODIFICATIONS.
 
24
 
 
25
*/
 
26
 
 
27
#include "platform.h"
 
28
#include "pack.h"
 
29
 
 
30
typedef unsigned char byte;
 
31
typedef unsigned short half;
 
32
typedef unsigned int word;
 
33
typedef signed char sbyte;
 
34
typedef signed short shalf;
 
35
typedef signed int 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
 
 
58
int
 
59
EXTRACTOR_common_cat_pack (void *buf, 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
    {
 
79
      nreps = 0;
 
80
 
 
81
      if (isdigit (*fmt))
 
82
        {
 
83
          /* We use cp instead of fmt to keep the 'const' qualifier of fmt */
 
84
          nreps = strtoul (fmt, &cp, 0);
 
85
          fmt = cp;
 
86
        }
 
87
 
 
88
      switch (*fmt)
 
89
        {
 
90
        case 'B':
 
91
        case 'b':
 
92
        case 'C':
 
93
        case 'c':
 
94
          if (!nreps)
 
95
            {
 
96
              *bp++ = va_arg (ap, int);
 
97
              npacked += 1;
 
98
            }
 
99
          else
 
100
            {
 
101
              bytep = va_arg (ap, byte *);
 
102
              for (i = 0; i < nreps; ++i)
 
103
                {
 
104
                  *bp++ = bytep[i];
 
105
                  npacked += 1;
 
106
                }
 
107
            }
 
108
          break;
 
109
 
 
110
        case 'h':
 
111
        case 's':
 
112
          if (!nreps)
 
113
            {
 
114
              val = va_arg (ap, int);
 
115
              *bp++ = val & 0xFF;
 
116
              *bp++ = val >> 8;
 
117
              npacked += 2;
 
118
            }
 
119
          else
 
120
            {
 
121
              halfp = va_arg (ap, half *);
 
122
              for (i = 0; i < nreps; ++i)
 
123
                {
 
124
                  val = halfp[i];
 
125
                  *bp++ = val & 0xFF;
 
126
                  *bp++ = val >> 8;
 
127
                  npacked += 2;
 
128
                }
 
129
            }
 
130
          break;
 
131
 
 
132
        case 'H':
 
133
        case 'S':
 
134
          if (!nreps)
 
135
            {
 
136
              val = va_arg (ap, int);
 
137
              *bp++ = val >> 8;
 
138
              *bp++ = val & 0xFF;
 
139
              npacked += 2;
 
140
            }
 
141
          else
 
142
            {
 
143
              halfp = va_arg (ap, half *);
 
144
              for (i = 0; i < nreps; ++i)
 
145
                {
 
146
                  val = halfp[i];
 
147
                  *bp++ = val >> 8;
 
148
                  *bp++ = val & 0xFF;
 
149
                  npacked += 2;
 
150
                }
 
151
            }
 
152
          break;
 
153
 
 
154
        case 'l':
 
155
        case 'w':
 
156
          if (!nreps)
 
157
            {
 
158
              val = va_arg (ap, word);
 
159
              *bp++ = val & 0xFF;
 
160
              *bp++ = val >> 8;
 
161
              *bp++ = val >> 16;
 
162
              *bp++ = val >> 24;
 
163
              npacked += 4;
 
164
            }
 
165
          else
 
166
            {
 
167
              wordp = va_arg (ap, word *);
 
168
              for (i = 0; i < nreps; ++i)
 
169
                {
 
170
                  val = wordp[i];
 
171
                  *bp++ = val & 0xFF;
 
172
                  *bp++ = val >> 8;
 
173
                  *bp++ = val >> 16;
 
174
                  *bp++ = val >> 24;
 
175
                  npacked += 4;
 
176
                }
 
177
            }
 
178
          break;
 
179
 
 
180
        case 'L':
 
181
        case 'W':
 
182
          if (!nreps)
 
183
            {
 
184
              val = va_arg (ap, word);
 
185
              *bp++ = val >> 24;
 
186
              *bp++ = val >> 16;
 
187
              *bp++ = val >> 8;
 
188
              *bp++ = val & 0xFF;
 
189
              npacked += 4;
 
190
            }
 
191
          else
 
192
            {
 
193
              wordp = va_arg (ap, word *);
 
194
              for (i = 0; i < nreps; ++i)
 
195
                {
 
196
                  val = wordp[i];
 
197
                  *bp++ = val >> 24;
 
198
                  *bp++ = val >> 16;
 
199
                  *bp++ = val >> 8;
 
200
                  *bp++ = val & 0xFF;
 
201
                  npacked += 4;
 
202
                }
 
203
            }
 
204
          break;
 
205
 
 
206
        case 'A':
 
207
          if (!nreps)
 
208
            {
 
209
              blen = va_arg (ap, word);
 
210
              arr = va_arg (ap, void *);
 
211
              *bp++ = blen >> 24;
 
212
              *bp++ = blen >> 16;
 
213
              *bp++ = blen >> 8;
 
214
              *bp++ = blen & 0xFF;
 
215
              memmove (bp, arr, blen);
 
216
              bp += blen;
 
217
              npacked += blen + 4;      /* +4 for the 32 bits of length field */
 
218
            }
 
219
          else
 
220
            {
 
221
              cbvp = va_arg (ap, struct cat_bvec *);
 
222
              for (i = 0; i < nreps; ++i)
 
223
                {
 
224
                  blen = cbvp[i].len;
 
225
                  arr = cbvp[i].data;
 
226
                  *bp++ = blen >> 24;
 
227
                  *bp++ = blen >> 16;
 
228
                  *bp++ = blen >> 8;
 
229
                  *bp++ = blen & 0xFF;
 
230
                  memmove (bp, arr, blen);
 
231
                  bp += blen;
 
232
                  npacked += blen + 4;  /* see above */
 
233
                }
 
234
            }
 
235
          break;
 
236
 
 
237
        default:
 
238
          va_end (ap);
 
239
          return -1;
 
240
        }
 
241
      ++fmt;
 
242
    }
 
243
 
 
244
  va_end (ap);
 
245
  return npacked;
 
246
}
 
247
 
 
248
 
 
249
 
 
250
int
 
251
EXTRACTOR_common_cat_unpack (const void *buf, const char *fmt, ...)
 
252
{
 
253
  va_list ap;
 
254
  word maxlen, len, *wordp;
 
255
  void *arr;
 
256
  byte *bp, *bytep, *newbuf;
 
257
  half *halfp;
 
258
  sbyte *sbytep;
 
259
  shalf *shalfp;
 
260
  sword *swordp;
 
261
  int npacked;
 
262
  unsigned int nreps, i, isnonprefixed = 1;     /* used for 'a' types only */
 
263
  struct cat_bvec *cbvp;
 
264
  char *cp;
 
265
 
 
266
  bp = (byte *) buf;
 
267
  npacked = 0;
 
268
 
 
269
  va_start (ap, fmt);
 
270
 
 
271
  while (*fmt)
 
272
    {
 
273
      nreps = 1;
 
274
 
 
275
      if (isdigit (*fmt))
 
276
        {
 
277
          /* We use cp instead of format to keep the 'const' qualifier of fmt */
 
278
          nreps = strtoul (fmt, &cp, 0);
 
279
          fmt = cp;
 
280
          if (*fmt == 'a')
 
281
            isnonprefixed = 0;
 
282
        }
 
283
 
 
284
      switch (*fmt)
 
285
        {
 
286
        case 'B':
 
287
        case 'b':
 
288
          bytep = va_arg (ap, byte *);
 
289
          for (i = 0; i < nreps; ++i)
 
290
            {
 
291
              *bytep = *bp++;
 
292
              ++bytep;
 
293
              npacked += 1;
 
294
            }
 
295
          break;
 
296
 
 
297
 
 
298
 
 
299
        case 'h':
 
300
          halfp = va_arg (ap, half *);
 
301
          for (i = 0; i < nreps; ++i)
 
302
            {
 
303
              *halfp = *bp++;
 
304
              *halfp |= *bp++ << 8;
 
305
              ++halfp;
 
306
              npacked += 2;
 
307
            }
 
308
          break;
 
309
 
 
310
        case 'H':
 
311
          halfp = va_arg (ap, half *);
 
312
          for (i = 0; i < nreps; ++i)
 
313
            {
 
314
              *halfp = *bp++ << 8;
 
315
              *halfp |= *bp++;
 
316
              ++halfp;
 
317
              npacked += 2;
 
318
            }
 
319
          break;
 
320
 
 
321
 
 
322
        case 'w':
 
323
          wordp = va_arg (ap, word *);
 
324
          for (i = 0; i < nreps; ++i)
 
325
            {
 
326
              *wordp = *bp++;
 
327
              *wordp |= *bp++ << 8;
 
328
              *wordp |= *bp++ << 16;
 
329
              *wordp |= *bp++ << 24;
 
330
              ++wordp;
 
331
              npacked += 4;
 
332
            }
 
333
          break;
 
334
 
 
335
        case 'W':
 
336
          wordp = va_arg (ap, word *);
 
337
          for (i = 0; i < nreps; ++i)
 
338
            {
 
339
              *wordp = *bp++ << 24;
 
340
              *wordp |= *bp++ << 16;
 
341
              *wordp |= *bp++ << 8;
 
342
              *wordp |= *bp++;
 
343
              ++wordp;
 
344
              npacked += 4;
 
345
            }
 
346
          break;
 
347
 
 
348
        case 'A':
 
349
          if (isnonprefixed)
 
350
            {
 
351
              maxlen = va_arg (ap, word);
 
352
              arr = va_arg (ap, void *);
 
353
 
 
354
              len = *bp++ << 24;
 
355
              len |= *bp++ << 16;
 
356
              len |= *bp++ << 8;
 
357
              len |= *bp++;
 
358
 
 
359
              if (len > maxlen)
 
360
                {
 
361
                  va_end (ap);
 
362
                  return -1;
 
363
                }
 
364
 
 
365
              memmove (arr, bp, len);
 
366
              bp += len;
 
367
 
 
368
              npacked += len;
 
369
            }
 
370
          else
 
371
            {
 
372
              cbvp = va_arg (ap, struct cat_bvec *);
 
373
              for (i = 0; i < nreps; ++i)
 
374
                {
 
375
                  maxlen = cbvp->len;
 
376
                  arr = cbvp->data;
 
377
 
 
378
                  len = *bp++ << 24;
 
379
                  len |= *bp++ << 16;
 
380
                  len |= *bp++ << 8;
 
381
                  len |= *bp++;
 
382
 
 
383
                  if (len > maxlen)
 
384
                    return -1;
 
385
 
 
386
                  memmove (arr, bp, len);
 
387
                  cbvp->len = len;
 
388
                  bp += len;
 
389
 
 
390
                  ++cbvp;
 
391
                  npacked += len;
 
392
                }
 
393
              isnonprefixed = 1;
 
394
            }
 
395
          break;
 
396
 
 
397
        case 'C':
 
398
        case 'c':
 
399
          sbytep = va_arg (ap, sbyte *);
 
400
          for (i = 0; i < nreps; ++i)
 
401
            {
 
402
              *sbytep = *bp++;
 
403
 
 
404
              if ((sizeof (sbyte) > 1) && (*sbytep & 0x80))
 
405
                *sbytep |= (~0) << ((sizeof (sbyte) - 1) * 8);
 
406
 
 
407
              ++sbytep;
 
408
              npacked += 1;
 
409
            }
 
410
          break;
 
411
 
 
412
 
 
413
        case 's':
 
414
          shalfp = va_arg (ap, shalf *);
 
415
          for (i = 0; i < nreps; ++i)
 
416
            {
 
417
              *shalfp = *bp++;
 
418
              *shalfp |= *bp++ << 8;
 
419
 
 
420
              if ((sizeof (shalf) > 2) && (*shalfp & 0x8000))
 
421
                *shalfp |= (~0) << ((sizeof (shalf) - 2) * 8);
 
422
 
 
423
              ++shalfp;
 
424
              npacked += 2;
 
425
            }
 
426
          break;
 
427
 
 
428
        case 'S':
 
429
          shalfp = va_arg (ap, shalf *);
 
430
          for (i = 0; i < nreps; ++i)
 
431
            {
 
432
              *shalfp = *bp++ << 8;
 
433
              *shalfp |= *bp++;
 
434
 
 
435
              if ((sizeof (shalf) > 2) && (*shalfp & 0x8000))
 
436
                *shalfp |= (~0) << ((sizeof (shalf) - 2) * 8);
 
437
 
 
438
              ++shalfp;
 
439
              npacked += 2;
 
440
            }
 
441
          break;
 
442
 
 
443
        case 'l':
 
444
          swordp = va_arg (ap, sword *);
 
445
          for (i = 0; i < nreps; ++i)
 
446
            {
 
447
              *swordp = *bp++;
 
448
              *swordp |= *bp++ << 8;
 
449
              *swordp |= *bp++ << 16;
 
450
              *swordp |= *bp++ << 24;
 
451
 
 
452
              if ((sizeof (swordp) > 4) && (*swordp & 0x80000000))
 
453
                *swordp |= (~0) << ((sizeof (sword) - 4) * 8);
 
454
 
 
455
              ++swordp;
 
456
              npacked += 4;
 
457
            }
 
458
          break;
 
459
 
 
460
        case 'L':
 
461
          swordp = va_arg (ap, sword *);
 
462
          for (i = 0; i < nreps; ++i)
 
463
            {
 
464
              *swordp = *bp++ << 24;
 
465
              *swordp |= *bp++ << 16;
 
466
              *swordp |= *bp++ << 8;
 
467
              *swordp |= *bp++;
 
468
 
 
469
              if ((sizeof (swordp) > 4) && (*swordp & 0x80000000))
 
470
                *swordp |= (~0) << ((sizeof (sword) - 4) * 8);
 
471
 
 
472
              ++swordp;
 
473
              npacked += 4;
 
474
            }
 
475
          break;
 
476
 
 
477
        case 'P':
 
478
          cbvp = va_arg (ap, struct cat_bvec *);
 
479
          for (i = 0; i < nreps; ++i)
 
480
            {
 
481
              len = *bp++ << 24;
 
482
              len |= *bp++ << 16;
 
483
              len |= *bp++ << 8;
 
484
              len |= *bp++;
 
485
 
 
486
              newbuf = (byte *) malloc (len);
 
487
 
 
488
              if (!newbuf)
 
489
                {
 
490
                  int j;
 
491
                  for (j = 0; j < i; j++)
 
492
                    free (cbvp[i].data);
 
493
                  va_end (ap);
 
494
                  return -1;
 
495
                }
 
496
 
 
497
              memmove (newbuf, bp, len);
 
498
              cbvp[i].data = newbuf;
 
499
              cbvp[i].len = len;
 
500
 
 
501
              bp += len;
 
502
              npacked += len;
 
503
            }
 
504
          break;
 
505
 
 
506
        default:
 
507
          va_end (ap);
 
508
          return -1;
 
509
        }
 
510
 
 
511
      ++fmt;
 
512
    }
 
513
 
 
514
  va_end (ap);
 
515
  return 0;
 
516
}