blob: a96606b3b3ef0348d8265569abb6ee10e370d3c4 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossum02975121992-08-17 08:55:12 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossum02975121992-08-17 08:55:12 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossum02975121992-08-17 08:55:12 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossum02975121992-08-17 08:55:12 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossum02975121992-08-17 08:55:12 +000029
30******************************************************************/
31
32/* struct module -- pack values into and (out of) strings */
33
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000034/* New version supporting byte order, alignment and size options,
35 character strings, and unsigned numbers */
36
Barry Warsaw30695fa1996-12-12 23:32:31 +000037#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +000038
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000039#include <limits.h>
40
41
42/* Exception */
43
Barry Warsaw30695fa1996-12-12 23:32:31 +000044static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000045
46
47/* Define various structs to figure out the alignments of types */
48
Jack Jansen971e1df1995-02-02 14:29:10 +000049#ifdef __MWERKS__
50/*
51** XXXX We have a problem here. There are no unique alignment rules
52** on the PowerPC mac.
53*/
54#ifdef __powerc
55#pragma options align=mac68k
56#endif
57#endif /* __MWERKS__ */
58
Guido van Rossum02975121992-08-17 08:55:12 +000059typedef struct { char c; short x; } s_short;
60typedef struct { char c; int x; } s_int;
61typedef struct { char c; long x; } s_long;
62typedef struct { char c; float x; } s_float;
63typedef struct { char c; double x; } s_double;
64
65#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
66#define INT_ALIGN (sizeof(s_int) - sizeof(int))
67#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
68#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
69#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
70
Jack Jansen971e1df1995-02-02 14:29:10 +000071#ifdef __powerc
72#pragma options align=reset
73#endif
74
Guido van Rossum02975121992-08-17 08:55:12 +000075
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000076/* Helper routine to turn a (signed) long into an unsigned long */
77/* XXX This assumes 2's complement arithmetic */
78
79static PyObject *
80make_ulong(x)
81 long x;
82{
83 PyObject *v = PyLong_FromLong(x);
84 if (x < 0 && v != NULL) {
85 static PyObject *offset = NULL;
86 PyObject *result = NULL;
87 if (offset == NULL) {
88 PyObject *one = PyLong_FromLong(1L);
89 PyObject *shiftcount =
90 PyLong_FromLong(8 * sizeof(long));
91 if (one == NULL || shiftcount == NULL)
92 goto bad;
93 offset = PyNumber_Lshift(one, shiftcount);
94 bad:
95 Py_XDECREF(one);
96 Py_XDECREF(shiftcount);
97 if (offset == NULL)
98 goto finally;
99 }
100 result = PyNumber_Add(v, offset);
101 finally:
102 Py_DECREF(v);
103 return result;
104 }
105 else
106 return v;
107}
108
109/* Helper routine to get a Python integer and raise the appropriate error
110 if it isn't one */
111
112static int
113get_long(v, p)
114 PyObject *v;
115 long *p;
116{
117 long x = PyInt_AsLong(v);
118 if (x == -1 && PyErr_Occurred()) {
119 if (PyErr_Occurred() == PyExc_TypeError)
120 PyErr_SetString(StructError,
121 "required argument is not an integer");
122 return -1;
123 }
124 *p = x;
125 return 0;
126}
127
128
129/* The translation function for each format character is table driven */
130
131typedef struct _formatdef {
132 char format;
133 int size;
134 int alignment;
135 PyObject* (*unpack) Py_PROTO((const char *,
136 const struct _formatdef *));
137 int (*pack) Py_PROTO((char *,
138 PyObject *,
139 const struct _formatdef *));
140} formatdef;
141
142static PyObject *
143nu_char(p, f)
144 const char *p;
145 const formatdef *f;
146{
147 return PyString_FromStringAndSize(p, 1);
148}
149
150static PyObject *
151nu_byte(p, f)
152 const char *p;
153 const formatdef *f;
154{
155 return PyInt_FromLong((long) *(signed char *)p);
156}
157
158static PyObject *
159nu_ubyte(p, f)
160 const char *p;
161 const formatdef *f;
162{
163 return PyInt_FromLong((long) *(unsigned char *)p);
164}
165
166static PyObject *
167nu_short(p, f)
168 const char *p;
169 const formatdef *f;
170{
171 return PyInt_FromLong((long) *(short *)p);
172}
173
174static PyObject *
175nu_ushort(p, f)
176 const char *p;
177 const formatdef *f;
178{
179 return PyInt_FromLong((long) *(unsigned short *)p);
180}
181
182static PyObject *
183nu_int(p, f)
184 const char *p;
185 const formatdef *f;
186{
187 return PyInt_FromLong((long) *(int *)p);
188}
189
190static PyObject *
191nu_uint(p, f)
192 const char *p;
193 const formatdef *f;
194{
195 unsigned int x = *(unsigned int *)p;
196#if INT_MAX == LONG_MAX
197 return make_ulong((long)x);
198#else
199 return PyInt_FromLong((long)x);
200#endif
201}
202
203static PyObject *
204nu_long(p, f)
205 const char *p;
206 const formatdef *f;
207{
208 return PyInt_FromLong(*(long *)p);
209}
210
211static PyObject *
212nu_ulong(p, f)
213 const char *p;
214 const formatdef *f;
215{
216 return make_ulong(*(long *)p);
217}
218
219static PyObject *
220nu_float(p, f)
221 const char *p;
222 const formatdef *f;
223{
224 float x;
225 memcpy((char *)&x, p, sizeof(float));
226 return PyFloat_FromDouble((double)x);
227}
228
229static PyObject *
230nu_double(p, f)
231 const char *p;
232 const formatdef *f;
233{
234 double x;
235 memcpy((char *)&x, p, sizeof(double));
236 return PyFloat_FromDouble(x);
237}
238
239static int
240np_byte(p, v, f)
241 char *p;
242 PyObject *v;
243 const formatdef *f;
244{
245 long x;
246 if (get_long(v, &x) < 0)
247 return -1;
248 *p = x;
249 return 0;
250}
251
252static int
253np_char(p, v, f)
254 char *p;
255 PyObject *v;
256 const formatdef *f;
257{
258 if (!PyString_Check(v) || PyString_Size(v) != 1) {
259 PyErr_SetString(StructError,
260 "char format require string of length 1");
261 return -1;
262 }
263 *p = *PyString_AsString(v);
264 return 0;
265}
266
267static int
268np_short(p, v, f)
269 char *p;
270 PyObject *v;
271 const formatdef *f;
272{
273 long x;
274 if (get_long(v, &x) < 0)
275 return -1;
276 * (short *)p = x;
277 return 0;
278}
279
280static int
281np_int(p, v, f)
282 char *p;
283 PyObject *v;
284 const formatdef *f;
285{
286 long x;
287 if (get_long(v, &x) < 0)
288 return -1;
289 * (int *)p = x;
290 return 0;
291}
292
293static int
294np_long(p, v, f)
295 char *p;
296 PyObject *v;
297 const formatdef *f;
298{
299 long x;
300 if (get_long(v, &x) < 0)
301 return -1;
302 * (long *)p = x;
303 return 0;
304}
305
306static int
307np_float(p, v, f)
308 char *p;
309 PyObject *v;
310 const formatdef *f;
311{
312 float x = (float)PyFloat_AsDouble(v);
313 if (x == -1 && PyErr_Occurred()) {
314 PyErr_SetString(StructError,
315 "required argument is not a float");
316 return -1;
317 }
318 memcpy(p, (char *)&x, sizeof(float));
319 return 0;
320}
321
322static int
323np_double(p, v, f)
324 char *p;
325 PyObject *v;
326 const formatdef *f;
327{
328 double x = PyFloat_AsDouble(v);
329 if (x == -1 && PyErr_Occurred()) {
330 PyErr_SetString(StructError,
331 "required argument is not a float");
332 return -1;
333 }
334 memcpy(p, (char *)&x, sizeof(double));
335 return 0;
336}
337
338static formatdef native_table[] = {
339 {'x', sizeof(char), 0, NULL},
340 {'b', sizeof(char), 0, nu_byte, np_byte},
341 {'B', sizeof(char), 0, nu_ubyte, np_byte},
342 {'c', sizeof(char), 0, nu_char, np_char},
343 {'s', sizeof(char), 0, NULL},
344 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
345 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
346 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
347 {'I', sizeof(int), INT_ALIGN, nu_uint, np_int},
348 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
349 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_long},
350 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
351 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
352 {0}
353};
354
355static PyObject *
356bu_int(p, f)
357 const char *p;
358 const formatdef *f;
359{
360 long x = 0;
361 int i = f->size;
362 do {
363 x = (x<<8) | (*p++ & 0xFF);
364 } while (--i > 0);
365 i = 8*(sizeof(long) - f->size);
366 if (i) {
367 x <<= i;
368 x >>= i;
369 }
370 return PyInt_FromLong(x);
371}
372
373static PyObject *
374bu_uint(p, f)
375 const char *p;
376 const formatdef *f;
377{
378 long x = 0;
379 int i = f->size;
380 do {
381 x = (x<<8) | (*p++ & 0xFF);
382 } while (--i > 0);
383 if (f->size == sizeof(long))
384 return make_ulong(x);
385 else
386 return PyLong_FromLong(x);
387}
388
389static int
390bp_int(p, v, f)
391 char *p;
392 PyObject *v;
393 const formatdef *f;
394{
395 long x;
396 int i;
397 if (get_long(v, &x) < 0)
398 return -1;
399 i = f->size;
400 do {
401 p[--i] = x;
402 x >>= 8;
403 } while (i > 0);
404 return 0;
405}
406
407static formatdef bigendian_table[] = {
408 {'x', 1, 0, NULL},
409 {'b', 1, 0, bu_int, bp_int},
410 {'B', 1, 0, bu_uint, bp_int},
411 {'c', 1, 0, nu_char, np_char},
412 {'s', 1, 0, NULL},
413 {'h', 2, 0, bu_int, bp_int},
414 {'H', 2, 0, bu_uint, bp_int},
415 {'i', 4, 0, bu_int, bp_int},
416 {'I', 4, 0, bu_uint, bp_int},
417 {'l', 4, 0, bu_int, bp_int},
418 {'L', 4, 0, bu_uint, bp_int},
419 /* No float and double! */
420 {0}
421};
422
423static PyObject *
424lu_int(p, f)
425 const char *p;
426 const formatdef *f;
427{
428 long x = 0;
429 int i = f->size;
430 do {
431 x = (x<<8) | (p[--i] & 0xFF);
432 } while (i > 0);
433 i = 8*(sizeof(long) - f->size);
434 if (i) {
435 x <<= i;
436 x >>= i;
437 }
438 return PyInt_FromLong(x);
439}
440
441static PyObject *
442lu_uint(p, f)
443 const char *p;
444 const formatdef *f;
445{
446 long x = 0;
447 int i = f->size;
448 do {
449 x = (x<<8) | (p[--i] & 0xFF);
450 } while (i > 0);
451 if (f->size == sizeof(long))
452 return make_ulong(x);
453 else
454 return PyLong_FromLong(x);
455}
456
457static int
458lp_int(p, v, f)
459 char *p;
460 PyObject *v;
461 const formatdef *f;
462{
463 long x;
464 int i;
465 if (get_long(v, &x) < 0)
466 return -1;
467 i = f->size;
468 do {
469 *p++ = x;
470 x >>= 8;
471 } while (--i > 0);
472 return 0;
473}
474
475static formatdef lilendian_table[] = {
476 {'x', 1, 0, NULL},
477 {'b', 1, 0, lu_int, lp_int},
478 {'B', 1, 0, lu_uint, lp_int},
479 {'c', 1, 0, nu_char, np_char},
480 {'s', 1, 0, NULL},
481 {'h', 2, 0, lu_int, lp_int},
482 {'H', 2, 0, lu_uint, lp_int},
483 {'i', 4, 0, lu_int, lp_int},
484 {'I', 4, 0, lu_uint, lp_int},
485 {'l', 4, 0, lu_int, lp_int},
486 {'L', 4, 0, lu_uint, lp_int},
487 /* No float and double! */
488 {0}
489};
490
491
492static const formatdef *
493whichtable(pfmt)
494 const char **pfmt;
495{
496 const char *fmt = (*pfmt)++; /* May be backed out of later */
497 switch (*fmt) {
498 case '<':
499 return lilendian_table;
500 case '>':
501 case '!': /* Network byte order is big-endian */
502 return bigendian_table;
503 case '=': { /* Host byte order -- different from native in aligment! */
504 int n = 1;
505 char *p = (char *) &n;
506 if (*p == 1)
507 return lilendian_table;
508 else
509 return bigendian_table;
510 }
511 default:
512 --*pfmt; /* Back out of pointer increment */
513 /* Fall through */
514 case '@':
515 return native_table;
516 }
517}
518
519
520/* Get the table entry for a format code */
521
522static const formatdef *
523getentry(c, f)
524 int c;
525 const formatdef *f;
526{
527 for (; f->format != '\0'; f++) {
528 if (f->format == c) {
529 return f;
530 }
531 }
532 PyErr_SetString(StructError, "bad char in struct format");
533 return NULL;
534}
535
536
Guido van Rossum02975121992-08-17 08:55:12 +0000537/* Align a size according to a format code */
538
539static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000540align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +0000541 int size;
542 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000543 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +0000544{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000545 if (e->format == c) {
546 if (e->alignment) {
547 size = ((size + e->alignment - 1)
548 / e->alignment)
549 * e->alignment;
550 }
Guido van Rossum02975121992-08-17 08:55:12 +0000551 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000552 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000553}
554
555
556/* calculate the size of a format string */
557
558static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000559calcsize(fmt, f)
560 const char *fmt;
561 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000562{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000563 const formatdef *e;
564 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000565 char c;
566 int size, num, itemsize, x;
567
568 s = fmt;
569 size = 0;
570 while ((c = *s++) != '\0') {
571 if ('0' <= c && c <= '9') {
572 num = c - '0';
573 while ('0' <= (c = *s++) && c <= '9') {
574 x = num*10 + (c - '0');
575 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000576 PyErr_SetString(
577 StructError,
578 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000579 return -1;
580 }
581 num = x;
582 }
583 if (c == '\0')
584 break;
585 }
586 else
587 num = 1;
588
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000589 e = getentry(c, f);
590 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000591 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000592 itemsize = e->size;
593 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000594 x = num * itemsize;
595 size += x;
596 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000597 PyErr_SetString(StructError,
598 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000599 return -1;
600 }
Guido van Rossum02975121992-08-17 08:55:12 +0000601 }
602
603 return size;
604}
605
606
607/* pack(fmt, v1, v2, ...) --> string */
608
Barry Warsaw30695fa1996-12-12 23:32:31 +0000609static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +0000610struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +0000611 PyObject *self; /* Not used */
612 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +0000613{
614 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000615 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000616 int size;
617
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000618 if (!PyArg_ParseTuple(args, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +0000619 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000620 f = whichtable(&fmt);
621 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +0000622 if (size < 0)
623 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000624 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +0000625}
626
627
628/* pack(fmt, v1, v2, ...) --> string */
629
Barry Warsaw30695fa1996-12-12 23:32:31 +0000630static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +0000631struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +0000632 PyObject *self; /* Not used */
633 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +0000634{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000635 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000636 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +0000637 char *fmt;
638 int size, num;
639 int i, n;
640 char *s, *res, *restart;
641 char c;
Guido van Rossum02975121992-08-17 08:55:12 +0000642
Barry Warsaw30695fa1996-12-12 23:32:31 +0000643 if (args == NULL || !PyTuple_Check(args) ||
644 (n = PyTuple_Size(args)) < 1)
645 {
646 PyErr_BadArgument();
Guido van Rossum02975121992-08-17 08:55:12 +0000647 return NULL;
648 }
Barry Warsaw30695fa1996-12-12 23:32:31 +0000649 format = PyTuple_GetItem(args, 0);
650 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +0000651 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000652 f = whichtable(&fmt);
653 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +0000654 if (size < 0)
655 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000656 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +0000657 if (result == NULL)
658 return NULL;
659
660 s = fmt;
661 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000662 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +0000663
664 while ((c = *s++) != '\0') {
665 if ('0' <= c && c <= '9') {
666 num = c - '0';
667 while ('0' <= (c = *s++) && c <= '9')
668 num = num*10 + (c - '0');
669 if (c == '\0')
670 break;
671 }
672 else
673 num = 1;
674
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000675 e = getentry(c, f);
676 if (e == NULL)
677 goto fail;
678 res = restart + align((int)(res-restart), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +0000679 if (num == 0 && c != 's')
680 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000681 do {
682 if (c == 'x') {
683 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +0000684 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000685 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +0000686 break;
Guido van Rossum02975121992-08-17 08:55:12 +0000687 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000688 if (i >= n) {
689 PyErr_SetString(StructError,
690 "insufficient arguments to pack");
691 goto fail;
692 }
693 v = PyTuple_GetItem(args, i++);
694 if (v == NULL)
695 goto fail;
696 if (c == 's') {
697 /* num is string size, not repeat count */
698 int n;
699 if (!PyString_Check(v)) {
700 PyErr_SetString(StructError,
701 "argument for 's' must be a string");
702 goto fail;
703 }
704 n = PyString_Size(v);
705 if (n > num)
706 n = num;
707 if (n > 0)
708 memcpy(res, PyString_AsString(v), n);
709 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +0000710 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000711 res += num;
712 break;
713 }
714 else {
715 if (e->pack(res, v, e) < 0)
716 goto fail;
717 res += e->size;
718 }
719 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +0000720 }
721
722 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000723 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000724 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +0000725 goto fail;
726 }
727
728 return result;
729
730 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +0000731 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +0000732 return NULL;
733}
734
735
736/* unpack(fmt, string) --> (v1, v2, ...) */
737
Barry Warsaw30695fa1996-12-12 23:32:31 +0000738static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +0000739struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +0000740 PyObject *self; /* Not used */
741 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +0000742{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000743 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +0000744 char *str, *start, *fmt, *s;
745 char c;
746 int len, size, num, x;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000747 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +0000748
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000749 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +0000750 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000751 f = whichtable(&fmt);
752 size = calcsize(fmt, f);
753 if (size < 0)
754 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +0000755 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000756 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000757 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +0000758 return NULL;
759 }
Barry Warsaw30695fa1996-12-12 23:32:31 +0000760 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +0000761 if (res == NULL)
762 return NULL;
763 str = start;
764 s = fmt;
765 while ((c = *s++) != '\0') {
766 if ('0' <= c && c <= '9') {
767 num = c - '0';
768 while ('0' <= (c = *s++) && c <= '9')
769 num = num*10 + (c - '0');
770 if (c == '\0')
771 break;
772 }
773 else
774 num = 1;
775
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000776 e = getentry(c, f);
777 if (e == NULL)
778 goto fail;
779 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +0000780 if (num == 0 && c != 's')
781 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000782
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000783 do {
784 if (c == 'x') {
785 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +0000786 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000787 }
788 if (c == 's') {
789 /* num is string size, not repeat count */
790 v = PyString_FromStringAndSize(str, num);
791 if (v == NULL)
792 goto fail;
793 str += num;
794 num = 0;
795 }
796 else {
797 v = e->unpack(str, e);
798 if (v == NULL)
799 goto fail;
800 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +0000801 }
Barry Warsaw30695fa1996-12-12 23:32:31 +0000802 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +0000803 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000804 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000805 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +0000806 }
807
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000808 v = PyList_AsTuple(res);
809 Py_DECREF(res);
810 return v;
Guido van Rossum02975121992-08-17 08:55:12 +0000811
812 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +0000813 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +0000814 return NULL;
815}
816
Guido van Rossum90ddb7b1992-08-19 16:44:15 +0000817
Guido van Rossum02975121992-08-17 08:55:12 +0000818/* List of functions */
819
Barry Warsaw30695fa1996-12-12 23:32:31 +0000820static PyMethodDef struct_methods[] = {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000821 {"calcsize", struct_calcsize, METH_VARARGS},
822 {"pack", struct_pack, METH_VARARGS},
823 {"unpack", struct_unpack, METH_VARARGS},
Guido van Rossum02975121992-08-17 08:55:12 +0000824 {NULL, NULL} /* sentinel */
825};
826
827
828/* Module initialization */
829
830void
831initstruct()
832{
Barry Warsaw30695fa1996-12-12 23:32:31 +0000833 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +0000834
835 /* Create the module and add the functions */
Barry Warsaw30695fa1996-12-12 23:32:31 +0000836 m = Py_InitModule("struct", struct_methods);
Guido van Rossum02975121992-08-17 08:55:12 +0000837
838 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +0000839 d = PyModule_GetDict(m);
840 StructError = PyString_FromString("struct.error");
841 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +0000842
843 /* Check for errors */
Barry Warsaw30695fa1996-12-12 23:32:31 +0000844 if (PyErr_Occurred())
845 Py_FatalError("can't initialize module struct");
Guido van Rossum02975121992-08-17 08:55:12 +0000846}