blob: ef35bd707fb00c887125d71601252bc029cd4a84 [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 Rossum74679b41997-01-02 22:21:36 +000038#include "mymath.h"
Guido van Rossum02975121992-08-17 08:55:12 +000039
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000040#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000041#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000042
43
44/* Exception */
45
Barry Warsaw30695fa1996-12-12 23:32:31 +000046static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000047
48
49/* Define various structs to figure out the alignments of types */
50
Jack Jansen971e1df1995-02-02 14:29:10 +000051#ifdef __MWERKS__
52/*
53** XXXX We have a problem here. There are no unique alignment rules
54** on the PowerPC mac.
55*/
56#ifdef __powerc
57#pragma options align=mac68k
58#endif
59#endif /* __MWERKS__ */
60
Guido van Rossum02975121992-08-17 08:55:12 +000061typedef struct { char c; short x; } s_short;
62typedef struct { char c; int x; } s_int;
63typedef struct { char c; long x; } s_long;
64typedef struct { char c; float x; } s_float;
65typedef struct { char c; double x; } s_double;
66
67#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
68#define INT_ALIGN (sizeof(s_int) - sizeof(int))
69#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
70#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
71#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
72
Jack Jansen971e1df1995-02-02 14:29:10 +000073#ifdef __powerc
74#pragma options align=reset
75#endif
76
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000077/* Helper routine to get a Python integer and raise the appropriate error
78 if it isn't one */
79
80static int
81get_long(v, p)
82 PyObject *v;
83 long *p;
84{
85 long x = PyInt_AsLong(v);
86 if (x == -1 && PyErr_Occurred()) {
87 if (PyErr_Occurred() == PyExc_TypeError)
88 PyErr_SetString(StructError,
89 "required argument is not an integer");
90 return -1;
91 }
92 *p = x;
93 return 0;
94}
95
96
Guido van Rossum60c50611996-12-31 16:29:52 +000097/* Same, but handling unsigned long */
98
99static int
100get_ulong(v, p)
101 PyObject *v;
102 unsigned long *p;
103{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000104 if (PyLong_Check(v)) {
105 unsigned long x = PyLong_AsUnsignedLong(v);
106 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000107 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000108 *p = x;
109 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000110 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000111 else {
112 return get_long(v, (long *)p);
113 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000114}
115
116
Guido van Rossum74679b41997-01-02 22:21:36 +0000117/* Floating point helpers */
118
119/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
120 Point Arithmetic). See the following URL:
121 http://www.psc.edu/general/software/packages/ieee/ieee.html */
122
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000123/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000124
125static int
126pack_float(x, p, incr)
127 double x; /* The number to pack */
128 char *p; /* Where to pack the high order byte */
129 int incr; /* 1 for big-endian; -1 for little-endian */
130{
131 int s;
132 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000133 double f;
134 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000135
136 if (x < 0) {
137 s = 1;
138 x = -x;
139 }
140 else
141 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000142
143 f = frexp(x, &e);
144
145 /* Normalize f to be in the range [1.0, 2.0) */
146 if (0.5 <= f && f < 1.0) {
147 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000148 e--;
149 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000150 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000151 e = 0;
152 }
153 else {
154 PyErr_SetString(PyExc_SystemError,
155 "frexp() result out of range");
156 return -1;
157 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000158
159 if (e >= 128) {
160 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000161 PyErr_SetString(PyExc_OverflowError,
162 "float too large to pack with f format");
163 return -1;
164 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000165 else if (e < -126) {
166 /* Gradual underflow */
167 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000168 e = 0;
169 }
Guido van Rossum74679b41997-01-02 22:21:36 +0000170 else {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000171 e += 127;
172 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000173 }
174
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000175 f *= 8388608.0; /* 2**23 */
176 fbits = (long) floor(f + 0.5); /* Round */
177
Guido van Rossum74679b41997-01-02 22:21:36 +0000178 /* First byte */
179 *p = (s<<7) | (e>>1);
180 p += incr;
181
182 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000183 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000184 p += incr;
185
186 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000187 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000188 p += incr;
189
190 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000191 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000192
193 /* Done */
194 return 0;
195}
196
197static int
198pack_double(x, p, incr)
199 double x; /* The number to pack */
200 char *p; /* Where to pack the high order byte */
201 int incr; /* 1 for big-endian; -1 for little-endian */
202{
203 int s;
204 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000205 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000206 long fhi, flo;
207
208 if (x < 0) {
209 s = 1;
210 x = -x;
211 }
212 else
213 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000214
215 f = frexp(x, &e);
216
217 /* Normalize f to be in the range [1.0, 2.0) */
218 if (0.5 <= f && f < 1.0) {
219 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000220 e--;
221 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000222 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000223 e = 0;
224 }
225 else {
226 PyErr_SetString(PyExc_SystemError,
227 "frexp() result out of range");
228 return -1;
229 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000230
231 if (e >= 1024) {
232 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000233 PyErr_SetString(PyExc_OverflowError,
234 "float too large to pack with d format");
235 return -1;
236 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000237 else if (e < -1022) {
238 /* Gradual underflow */
239 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000240 e = 0;
241 }
Guido van Rossum74679b41997-01-02 22:21:36 +0000242 else {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000243 e += 1023;
244 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000245 }
246
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000247 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
248 f *= 268435456.0; /* 2**28 */
249 fhi = (long) floor(f); /* Truncate */
250 f -= (double)fhi;
251 f *= 16777216.0; /* 2**24 */
252 flo = (long) floor(f + 0.5); /* Round */
253
Guido van Rossum74679b41997-01-02 22:21:36 +0000254 /* First byte */
255 *p = (s<<7) | (e>>4);
256 p += incr;
257
258 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000259 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000260 p += incr;
261
262 /* Third byte */
263 *p = (fhi>>16) & 0xFF;
264 p += incr;
265
266 /* Fourth byte */
267 *p = (fhi>>8) & 0xFF;
268 p += incr;
269
270 /* Fifth byte */
271 *p = fhi & 0xFF;
272 p += incr;
273
274 /* Sixth byte */
275 *p = (flo>>16) & 0xFF;
276 p += incr;
277
278 /* Seventh byte */
279 *p = (flo>>8) & 0xFF;
280 p += incr;
281
282 /* Eighth byte */
283 *p = flo & 0xFF;
284 p += incr;
285
286 /* Done */
287 return 0;
288}
289
290static PyObject *
291unpack_float(p, incr)
292 char *p; /* Where the high order byte is */
293 int incr; /* 1 for big-endian; -1 for little-endian */
294{
295 int s;
296 int e;
297 long f;
298 double x;
299
300 /* First byte */
301 s = (*p>>7) & 1;
302 e = (*p & 0x7F) << 1;
303 p += incr;
304
305 /* Second byte */
306 e |= (*p>>7) & 1;
307 f = (*p & 0x7F) << 16;
308 p += incr;
309
310 /* Third byte */
311 f |= (*p & 0xFF) << 8;
312 p += incr;
313
314 /* Fourth byte */
315 f |= *p & 0xFF;
316
317 x = (double)f / 8388608.0;
318
319 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000320 if (e == 0)
321 e = -126;
322 else {
323 x += 1.0;
324 e -= 127;
325 }
326 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000327
328 if (s)
329 x = -x;
330
331 return PyFloat_FromDouble(x);
332}
333
334static PyObject *
335unpack_double(p, incr)
336 char *p; /* Where the high order byte is */
337 int incr; /* 1 for big-endian; -1 for little-endian */
338{
339 int s;
340 int e;
341 long fhi, flo;
342 double x;
343
344 /* First byte */
345 s = (*p>>7) & 1;
346 e = (*p & 0x7F) << 4;
347 p += incr;
348
349 /* Second byte */
350 e |= (*p>>4) & 0xF;
351 fhi = (*p & 0xF) << 24;
352 p += incr;
353
354 /* Third byte */
355 fhi |= (*p & 0xFF) << 16;
356 p += incr;
357
358 /* Fourth byte */
359 fhi |= (*p & 0xFF) << 8;
360 p += incr;
361
362 /* Fifth byte */
363 fhi |= *p & 0xFF;
364 p += incr;
365
366 /* Sixth byte */
367 flo = (*p & 0xFF) << 16;
368 p += incr;
369
370 /* Seventh byte */
371 flo |= (*p & 0xFF) << 8;
372 p += incr;
373
374 /* Eighth byte */
375 flo |= *p & 0xFF;
376 p += incr;
377
378 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
379 x /= 268435456.0; /* 2**28 */
380
381 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000382 if (e == 0)
383 e = -1022;
384 else {
385 x += 1.0;
386 e -= 1023;
387 }
388 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000389
390 if (s)
391 x = -x;
392
393 return PyFloat_FromDouble(x);
394}
395
396
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000397/* The translation function for each format character is table driven */
398
399typedef struct _formatdef {
400 char format;
401 int size;
402 int alignment;
403 PyObject* (*unpack) Py_PROTO((const char *,
404 const struct _formatdef *));
405 int (*pack) Py_PROTO((char *,
406 PyObject *,
407 const struct _formatdef *));
408} formatdef;
409
410static PyObject *
411nu_char(p, f)
412 const char *p;
413 const formatdef *f;
414{
415 return PyString_FromStringAndSize(p, 1);
416}
417
418static PyObject *
419nu_byte(p, f)
420 const char *p;
421 const formatdef *f;
422{
423 return PyInt_FromLong((long) *(signed char *)p);
424}
425
426static PyObject *
427nu_ubyte(p, f)
428 const char *p;
429 const formatdef *f;
430{
431 return PyInt_FromLong((long) *(unsigned char *)p);
432}
433
434static PyObject *
435nu_short(p, f)
436 const char *p;
437 const formatdef *f;
438{
439 return PyInt_FromLong((long) *(short *)p);
440}
441
442static PyObject *
443nu_ushort(p, f)
444 const char *p;
445 const formatdef *f;
446{
447 return PyInt_FromLong((long) *(unsigned short *)p);
448}
449
450static PyObject *
451nu_int(p, f)
452 const char *p;
453 const formatdef *f;
454{
455 return PyInt_FromLong((long) *(int *)p);
456}
457
458static PyObject *
459nu_uint(p, f)
460 const char *p;
461 const formatdef *f;
462{
463 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000464 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000465}
466
467static PyObject *
468nu_long(p, f)
469 const char *p;
470 const formatdef *f;
471{
472 return PyInt_FromLong(*(long *)p);
473}
474
475static PyObject *
476nu_ulong(p, f)
477 const char *p;
478 const formatdef *f;
479{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000480 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000481}
482
483static PyObject *
484nu_float(p, f)
485 const char *p;
486 const formatdef *f;
487{
488 float x;
489 memcpy((char *)&x, p, sizeof(float));
490 return PyFloat_FromDouble((double)x);
491}
492
493static PyObject *
494nu_double(p, f)
495 const char *p;
496 const formatdef *f;
497{
498 double x;
499 memcpy((char *)&x, p, sizeof(double));
500 return PyFloat_FromDouble(x);
501}
502
503static int
504np_byte(p, v, f)
505 char *p;
506 PyObject *v;
507 const formatdef *f;
508{
509 long x;
510 if (get_long(v, &x) < 0)
511 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000512 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000513 return 0;
514}
515
516static int
517np_char(p, v, f)
518 char *p;
519 PyObject *v;
520 const formatdef *f;
521{
522 if (!PyString_Check(v) || PyString_Size(v) != 1) {
523 PyErr_SetString(StructError,
524 "char format require string of length 1");
525 return -1;
526 }
527 *p = *PyString_AsString(v);
528 return 0;
529}
530
531static int
532np_short(p, v, f)
533 char *p;
534 PyObject *v;
535 const formatdef *f;
536{
537 long x;
538 if (get_long(v, &x) < 0)
539 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000540 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000541 return 0;
542}
543
544static int
545np_int(p, v, f)
546 char *p;
547 PyObject *v;
548 const formatdef *f;
549{
550 long x;
551 if (get_long(v, &x) < 0)
552 return -1;
553 * (int *)p = x;
554 return 0;
555}
556
557static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000558np_uint(p, v, f)
559 char *p;
560 PyObject *v;
561 const formatdef *f;
562{
563 unsigned long x;
564 if (get_ulong(v, &x) < 0)
565 return -1;
566 * (unsigned int *)p = x;
567 return 0;
568}
569
570static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000571np_long(p, v, f)
572 char *p;
573 PyObject *v;
574 const formatdef *f;
575{
576 long x;
577 if (get_long(v, &x) < 0)
578 return -1;
579 * (long *)p = x;
580 return 0;
581}
582
583static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000584np_ulong(p, v, f)
585 char *p;
586 PyObject *v;
587 const formatdef *f;
588{
589 unsigned long x;
590 if (get_ulong(v, &x) < 0)
591 return -1;
592 * (unsigned long *)p = x;
593 return 0;
594}
595
596static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000597np_float(p, v, f)
598 char *p;
599 PyObject *v;
600 const formatdef *f;
601{
602 float x = (float)PyFloat_AsDouble(v);
603 if (x == -1 && PyErr_Occurred()) {
604 PyErr_SetString(StructError,
605 "required argument is not a float");
606 return -1;
607 }
608 memcpy(p, (char *)&x, sizeof(float));
609 return 0;
610}
611
612static int
613np_double(p, v, f)
614 char *p;
615 PyObject *v;
616 const formatdef *f;
617{
618 double x = PyFloat_AsDouble(v);
619 if (x == -1 && PyErr_Occurred()) {
620 PyErr_SetString(StructError,
621 "required argument is not a float");
622 return -1;
623 }
624 memcpy(p, (char *)&x, sizeof(double));
625 return 0;
626}
627
628static formatdef native_table[] = {
629 {'x', sizeof(char), 0, NULL},
630 {'b', sizeof(char), 0, nu_byte, np_byte},
631 {'B', sizeof(char), 0, nu_ubyte, np_byte},
632 {'c', sizeof(char), 0, nu_char, np_char},
633 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000634 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000635 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
636 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
637 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000638 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000639 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000640 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000641 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
642 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
643 {0}
644};
645
646static PyObject *
647bu_int(p, f)
648 const char *p;
649 const formatdef *f;
650{
651 long x = 0;
652 int i = f->size;
653 do {
654 x = (x<<8) | (*p++ & 0xFF);
655 } while (--i > 0);
656 i = 8*(sizeof(long) - f->size);
657 if (i) {
658 x <<= i;
659 x >>= i;
660 }
661 return PyInt_FromLong(x);
662}
663
664static PyObject *
665bu_uint(p, f)
666 const char *p;
667 const formatdef *f;
668{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000669 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000670 int i = f->size;
671 do {
672 x = (x<<8) | (*p++ & 0xFF);
673 } while (--i > 0);
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000674 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000675}
676
Guido van Rossum74679b41997-01-02 22:21:36 +0000677static PyObject *
678bu_float(p, f)
679 const char *p;
680 const formatdef *f;
681{
682 return unpack_float(p, 1);
683}
684
685static PyObject *
686bu_double(p, f)
687 const char *p;
688 const formatdef *f;
689{
690 return unpack_double(p, 1);
691}
692
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000693static int
694bp_int(p, v, f)
695 char *p;
696 PyObject *v;
697 const formatdef *f;
698{
699 long x;
700 int i;
701 if (get_long(v, &x) < 0)
702 return -1;
703 i = f->size;
704 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000705 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000706 x >>= 8;
707 } while (i > 0);
708 return 0;
709}
710
Guido van Rossum60c50611996-12-31 16:29:52 +0000711static int
712bp_uint(p, v, f)
713 char *p;
714 PyObject *v;
715 const formatdef *f;
716{
717 unsigned long x;
718 int i;
719 if (get_ulong(v, &x) < 0)
720 return -1;
721 i = f->size;
722 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000723 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000724 x >>= 8;
725 } while (i > 0);
726 return 0;
727}
728
Guido van Rossum74679b41997-01-02 22:21:36 +0000729static int
730bp_float(p, v, f)
731 char *p;
732 PyObject *v;
733 const formatdef *f;
734{
735 double x = PyFloat_AsDouble(v);
736 if (x == -1 && PyErr_Occurred()) {
737 PyErr_SetString(StructError,
738 "required argument is not a float");
739 return -1;
740 }
741 return pack_float(x, p, 1);
742}
743
744static int
745bp_double(p, v, f)
746 char *p;
747 PyObject *v;
748 const formatdef *f;
749{
750 double x = PyFloat_AsDouble(v);
751 if (x == -1 && PyErr_Occurred()) {
752 PyErr_SetString(StructError,
753 "required argument is not a float");
754 return -1;
755 }
756 return pack_double(x, p, 1);
757}
758
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000759static formatdef bigendian_table[] = {
760 {'x', 1, 0, NULL},
761 {'b', 1, 0, bu_int, bp_int},
762 {'B', 1, 0, bu_uint, bp_int},
763 {'c', 1, 0, nu_char, np_char},
764 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000765 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000766 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000767 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000768 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000769 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000770 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000771 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000772 {'f', 4, 0, bu_float, bp_float},
773 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000774 {0}
775};
776
777static PyObject *
778lu_int(p, f)
779 const char *p;
780 const formatdef *f;
781{
782 long x = 0;
783 int i = f->size;
784 do {
785 x = (x<<8) | (p[--i] & 0xFF);
786 } while (i > 0);
787 i = 8*(sizeof(long) - f->size);
788 if (i) {
789 x <<= i;
790 x >>= i;
791 }
792 return PyInt_FromLong(x);
793}
794
795static PyObject *
796lu_uint(p, f)
797 const char *p;
798 const formatdef *f;
799{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000800 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000801 int i = f->size;
802 do {
803 x = (x<<8) | (p[--i] & 0xFF);
804 } while (i > 0);
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000805 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000806}
807
Guido van Rossum74679b41997-01-02 22:21:36 +0000808static PyObject *
809lu_float(p, f)
810 const char *p;
811 const formatdef *f;
812{
813 return unpack_float(p+3, -1);
814}
815
816static PyObject *
817lu_double(p, f)
818 const char *p;
819 const formatdef *f;
820{
821 return unpack_double(p+7, -1);
822}
823
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000824static int
825lp_int(p, v, f)
826 char *p;
827 PyObject *v;
828 const formatdef *f;
829{
830 long x;
831 int i;
832 if (get_long(v, &x) < 0)
833 return -1;
834 i = f->size;
835 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000836 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000837 x >>= 8;
838 } while (--i > 0);
839 return 0;
840}
841
Guido van Rossum60c50611996-12-31 16:29:52 +0000842static int
843lp_uint(p, v, f)
844 char *p;
845 PyObject *v;
846 const formatdef *f;
847{
848 unsigned long x;
849 int i;
850 if (get_ulong(v, &x) < 0)
851 return -1;
852 i = f->size;
853 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000854 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000855 x >>= 8;
856 } while (--i > 0);
857 return 0;
858}
859
Guido van Rossum74679b41997-01-02 22:21:36 +0000860static int
861lp_float(p, v, f)
862 char *p;
863 PyObject *v;
864 const formatdef *f;
865{
866 double x = PyFloat_AsDouble(v);
867 if (x == -1 && PyErr_Occurred()) {
868 PyErr_SetString(StructError,
869 "required argument is not a float");
870 return -1;
871 }
872 return pack_float(x, p+3, -1);
873}
874
875static int
876lp_double(p, v, f)
877 char *p;
878 PyObject *v;
879 const formatdef *f;
880{
881 double x = PyFloat_AsDouble(v);
882 if (x == -1 && PyErr_Occurred()) {
883 PyErr_SetString(StructError,
884 "required argument is not a float");
885 return -1;
886 }
887 return pack_double(x, p+7, -1);
888}
889
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000890static formatdef lilendian_table[] = {
891 {'x', 1, 0, NULL},
892 {'b', 1, 0, lu_int, lp_int},
893 {'B', 1, 0, lu_uint, lp_int},
894 {'c', 1, 0, nu_char, np_char},
895 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000896 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000897 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000898 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000899 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000900 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000901 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000902 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000903 {'f', 4, 0, lu_float, lp_float},
904 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000905 {0}
906};
907
908
909static const formatdef *
910whichtable(pfmt)
911 const char **pfmt;
912{
913 const char *fmt = (*pfmt)++; /* May be backed out of later */
914 switch (*fmt) {
915 case '<':
916 return lilendian_table;
917 case '>':
918 case '!': /* Network byte order is big-endian */
919 return bigendian_table;
920 case '=': { /* Host byte order -- different from native in aligment! */
921 int n = 1;
922 char *p = (char *) &n;
923 if (*p == 1)
924 return lilendian_table;
925 else
926 return bigendian_table;
927 }
928 default:
929 --*pfmt; /* Back out of pointer increment */
930 /* Fall through */
931 case '@':
932 return native_table;
933 }
934}
935
936
937/* Get the table entry for a format code */
938
939static const formatdef *
940getentry(c, f)
941 int c;
942 const formatdef *f;
943{
944 for (; f->format != '\0'; f++) {
945 if (f->format == c) {
946 return f;
947 }
948 }
949 PyErr_SetString(StructError, "bad char in struct format");
950 return NULL;
951}
952
953
Guido van Rossum02975121992-08-17 08:55:12 +0000954/* Align a size according to a format code */
955
956static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000957align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +0000958 int size;
959 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000960 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +0000961{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000962 if (e->format == c) {
963 if (e->alignment) {
964 size = ((size + e->alignment - 1)
965 / e->alignment)
966 * e->alignment;
967 }
Guido van Rossum02975121992-08-17 08:55:12 +0000968 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000969 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000970}
971
972
973/* calculate the size of a format string */
974
975static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000976calcsize(fmt, f)
977 const char *fmt;
978 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000979{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000980 const formatdef *e;
981 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000982 char c;
983 int size, num, itemsize, x;
984
985 s = fmt;
986 size = 0;
987 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +0000988 if (isspace(c))
989 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000990 if ('0' <= c && c <= '9') {
991 num = c - '0';
992 while ('0' <= (c = *s++) && c <= '9') {
993 x = num*10 + (c - '0');
994 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000995 PyErr_SetString(
996 StructError,
997 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000998 return -1;
999 }
1000 num = x;
1001 }
1002 if (c == '\0')
1003 break;
1004 }
1005 else
1006 num = 1;
1007
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001008 e = getentry(c, f);
1009 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001010 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001011 itemsize = e->size;
1012 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001013 x = num * itemsize;
1014 size += x;
1015 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001016 PyErr_SetString(StructError,
1017 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001018 return -1;
1019 }
Guido van Rossum02975121992-08-17 08:55:12 +00001020 }
1021
1022 return size;
1023}
1024
1025
1026/* pack(fmt, v1, v2, ...) --> string */
1027
Barry Warsaw30695fa1996-12-12 23:32:31 +00001028static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001029struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001030 PyObject *self; /* Not used */
1031 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001032{
1033 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001034 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001035 int size;
1036
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001037 if (!PyArg_ParseTuple(args, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001038 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001039 f = whichtable(&fmt);
1040 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001041 if (size < 0)
1042 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001043 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001044}
1045
1046
1047/* pack(fmt, v1, v2, ...) --> string */
1048
Barry Warsaw30695fa1996-12-12 23:32:31 +00001049static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001050struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001051 PyObject *self; /* Not used */
1052 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001053{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001054 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001055 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001056 char *fmt;
1057 int size, num;
1058 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001059 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001060 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001061
Barry Warsaw30695fa1996-12-12 23:32:31 +00001062 if (args == NULL || !PyTuple_Check(args) ||
1063 (n = PyTuple_Size(args)) < 1)
1064 {
1065 PyErr_BadArgument();
Guido van Rossum02975121992-08-17 08:55:12 +00001066 return NULL;
1067 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001068 format = PyTuple_GetItem(args, 0);
1069 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001070 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001071 f = whichtable(&fmt);
1072 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001073 if (size < 0)
1074 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001075 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001076 if (result == NULL)
1077 return NULL;
1078
1079 s = fmt;
1080 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001081 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001082
1083 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +00001084 if (isspace(c))
1085 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001086 if ('0' <= c && c <= '9') {
1087 num = c - '0';
1088 while ('0' <= (c = *s++) && c <= '9')
1089 num = num*10 + (c - '0');
1090 if (c == '\0')
1091 break;
1092 }
1093 else
1094 num = 1;
1095
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001096 e = getentry(c, f);
1097 if (e == NULL)
1098 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001099 nres = restart + align((int)(res-restart), c, e);
1100 /* Fill padd bytes with zeros */
1101 while (res < nres)
1102 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001103 if (num == 0 && c != 's')
1104 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001105 do {
1106 if (c == 'x') {
1107 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001108 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001109 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001110 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001111 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001112 if (i >= n) {
1113 PyErr_SetString(StructError,
1114 "insufficient arguments to pack");
1115 goto fail;
1116 }
1117 v = PyTuple_GetItem(args, i++);
1118 if (v == NULL)
1119 goto fail;
1120 if (c == 's') {
1121 /* num is string size, not repeat count */
1122 int n;
1123 if (!PyString_Check(v)) {
1124 PyErr_SetString(StructError,
1125 "argument for 's' must be a string");
1126 goto fail;
1127 }
1128 n = PyString_Size(v);
1129 if (n > num)
1130 n = num;
1131 if (n > 0)
1132 memcpy(res, PyString_AsString(v), n);
1133 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001134 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001135 res += num;
1136 break;
1137 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001138 else if (c == 'p') {
1139 /* num is string size + 1,
1140 to fit in the count byte */
1141 int n;
1142 num--; /* now num is max string size */
1143 if (!PyString_Check(v)) {
1144 PyErr_SetString(StructError,
1145 "argument for 'p' must be a string");
1146 goto fail;
1147 }
1148 n = PyString_Size(v);
1149 if (n > num)
1150 n = num;
1151 if (n > 0)
1152 memcpy(res+1, PyString_AsString(v), n);
1153 if (n < num)
1154 /* no real need, just to be nice */
1155 memset(res+1+n, '\0', num-n);
1156 *res++ = n; /* store the length byte */
1157 res += num;
1158 break;
1159 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001160 else {
1161 if (e->pack(res, v, e) < 0)
1162 goto fail;
1163 res += e->size;
1164 }
1165 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001166 }
1167
1168 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001169 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001170 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001171 goto fail;
1172 }
1173
1174 return result;
1175
1176 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001177 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001178 return NULL;
1179}
1180
1181
1182/* unpack(fmt, string) --> (v1, v2, ...) */
1183
Barry Warsaw30695fa1996-12-12 23:32:31 +00001184static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001185struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001186 PyObject *self; /* Not used */
1187 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001188{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001189 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001190 char *str, *start, *fmt, *s;
1191 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001192 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001193 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001194
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001195 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001196 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001197 f = whichtable(&fmt);
1198 size = calcsize(fmt, f);
1199 if (size < 0)
1200 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001201 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001202 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001203 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001204 return NULL;
1205 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001206 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001207 if (res == NULL)
1208 return NULL;
1209 str = start;
1210 s = fmt;
1211 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +00001212 if (isspace(c))
1213 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001214 if ('0' <= c && c <= '9') {
1215 num = c - '0';
1216 while ('0' <= (c = *s++) && c <= '9')
1217 num = num*10 + (c - '0');
1218 if (c == '\0')
1219 break;
1220 }
1221 else
1222 num = 1;
1223
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001224 e = getentry(c, f);
1225 if (e == NULL)
1226 goto fail;
1227 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001228 if (num == 0 && c != 's')
1229 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001230
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001231 do {
1232 if (c == 'x') {
1233 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001234 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001235 }
1236 if (c == 's') {
1237 /* num is string size, not repeat count */
1238 v = PyString_FromStringAndSize(str, num);
1239 if (v == NULL)
1240 goto fail;
1241 str += num;
1242 num = 0;
1243 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001244 else if (c == 'p') {
1245 /* num is string buffer size,
1246 not repeat count */
1247 int n = *(unsigned char*)str;
1248 /* first byte (unsigned) is string size */
1249 if (n >= num)
1250 n = num-1;
1251 v = PyString_FromStringAndSize(str+1, n);
1252 if (v == NULL)
1253 goto fail;
1254 str += num;
1255 num = 0;
1256 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001257 else {
1258 v = e->unpack(str, e);
1259 if (v == NULL)
1260 goto fail;
1261 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001262 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001263 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001264 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001265 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001266 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001267 }
1268
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001269 v = PyList_AsTuple(res);
1270 Py_DECREF(res);
1271 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001272
1273 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001274 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001275 return NULL;
1276}
1277
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001278
Guido van Rossum02975121992-08-17 08:55:12 +00001279/* List of functions */
1280
Barry Warsaw30695fa1996-12-12 23:32:31 +00001281static PyMethodDef struct_methods[] = {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001282 {"calcsize", struct_calcsize, METH_VARARGS},
1283 {"pack", struct_pack, METH_VARARGS},
1284 {"unpack", struct_unpack, METH_VARARGS},
Guido van Rossum02975121992-08-17 08:55:12 +00001285 {NULL, NULL} /* sentinel */
1286};
1287
1288
1289/* Module initialization */
1290
1291void
1292initstruct()
1293{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001294 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001295
1296 /* Create the module and add the functions */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001297 m = Py_InitModule("struct", struct_methods);
Guido van Rossum02975121992-08-17 08:55:12 +00001298
1299 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001300 d = PyModule_GetDict(m);
1301 StructError = PyString_FromString("struct.error");
1302 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001303
1304 /* Check for errors */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001305 if (PyErr_Occurred())
1306 Py_FatalError("can't initialize module struct");
Guido van Rossum02975121992-08-17 08:55:12 +00001307}