blob: af8f1e53c064ba3b9e718461f98d64450d2e1256 [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
Guido van Rossum414fd481997-12-19 04:24:24 +000037static char struct__doc__[] = "\
38Functions to convert between Python values and C structs.\n\
39Python strings are used to hold the data representing the C struct\n\
40and also as format strings to describe the layout of data in the C struct.\n\
41\n\
42The optional first format char indicates byte ordering and alignment:\n\
43 @: native w/native alignment(default)\n\
44 =: native w/standard alignment\n\
45 <: little-endian, std. alignment\n\
46 >: big-endian, std. alignment\n\
47 !: network, std (same as >)\n\
48\n\
49The remaining chars indicate types of args and must match exactly;\n\
50these can be preceded by a decimal repeat count:\n\
51 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
52 h:short; H:unsigned short; i:int; I:unsigned int;\n\
53 l:long; L:unsigned long; f:float; d:double.\n\
54Special cases (preceding decimal count indicates length):\n\
55 s:string (array of char); p: pascal string (w. count byte).\n\
56Whitespace between formats is ignored.\n\
57\n\
58The variable struct.error is an exception raised on errors.";
59
Barry Warsaw30695fa1996-12-12 23:32:31 +000060#include "Python.h"
Guido van Rossum74679b41997-01-02 22:21:36 +000061#include "mymath.h"
Guido van Rossum02975121992-08-17 08:55:12 +000062
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000063#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000064#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000065
66
67/* Exception */
68
Barry Warsaw30695fa1996-12-12 23:32:31 +000069static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000070
71
72/* Define various structs to figure out the alignments of types */
73
Jack Jansen971e1df1995-02-02 14:29:10 +000074#ifdef __MWERKS__
75/*
76** XXXX We have a problem here. There are no unique alignment rules
77** on the PowerPC mac.
78*/
79#ifdef __powerc
80#pragma options align=mac68k
81#endif
82#endif /* __MWERKS__ */
83
Guido van Rossum02975121992-08-17 08:55:12 +000084typedef struct { char c; short x; } s_short;
85typedef struct { char c; int x; } s_int;
86typedef struct { char c; long x; } s_long;
87typedef struct { char c; float x; } s_float;
88typedef struct { char c; double x; } s_double;
89
90#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
91#define INT_ALIGN (sizeof(s_int) - sizeof(int))
92#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
93#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
94#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
95
Jack Jansen971e1df1995-02-02 14:29:10 +000096#ifdef __powerc
97#pragma options align=reset
98#endif
99
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000100/* Helper routine to get a Python integer and raise the appropriate error
101 if it isn't one */
102
103static int
104get_long(v, p)
105 PyObject *v;
106 long *p;
107{
108 long x = PyInt_AsLong(v);
109 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +0000110 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000111 PyErr_SetString(StructError,
112 "required argument is not an integer");
113 return -1;
114 }
115 *p = x;
116 return 0;
117}
118
119
Guido van Rossum60c50611996-12-31 16:29:52 +0000120/* Same, but handling unsigned long */
121
122static int
123get_ulong(v, p)
124 PyObject *v;
125 unsigned long *p;
126{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000127 if (PyLong_Check(v)) {
128 unsigned long x = PyLong_AsUnsignedLong(v);
129 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000130 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000131 *p = x;
132 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000133 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000134 else {
135 return get_long(v, (long *)p);
136 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000137}
138
139
Guido van Rossum74679b41997-01-02 22:21:36 +0000140/* Floating point helpers */
141
142/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
143 Point Arithmetic). See the following URL:
144 http://www.psc.edu/general/software/packages/ieee/ieee.html */
145
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000146/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000147
148static int
149pack_float(x, p, incr)
150 double x; /* The number to pack */
151 char *p; /* Where to pack the high order byte */
152 int incr; /* 1 for big-endian; -1 for little-endian */
153{
154 int s;
155 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000156 double f;
157 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000158
159 if (x < 0) {
160 s = 1;
161 x = -x;
162 }
163 else
164 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000165
166 f = frexp(x, &e);
167
168 /* Normalize f to be in the range [1.0, 2.0) */
169 if (0.5 <= f && f < 1.0) {
170 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000171 e--;
172 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000173 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000174 e = 0;
175 }
176 else {
177 PyErr_SetString(PyExc_SystemError,
178 "frexp() result out of range");
179 return -1;
180 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000181
182 if (e >= 128) {
183 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000184 PyErr_SetString(PyExc_OverflowError,
185 "float too large to pack with f format");
186 return -1;
187 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000188 else if (e < -126) {
189 /* Gradual underflow */
190 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000191 e = 0;
192 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000193 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000194 e += 127;
195 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000196 }
197
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000198 f *= 8388608.0; /* 2**23 */
199 fbits = (long) floor(f + 0.5); /* Round */
200
Guido van Rossum74679b41997-01-02 22:21:36 +0000201 /* First byte */
202 *p = (s<<7) | (e>>1);
203 p += incr;
204
205 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000206 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000207 p += incr;
208
209 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000210 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000211 p += incr;
212
213 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000214 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000215
216 /* Done */
217 return 0;
218}
219
220static int
221pack_double(x, p, incr)
222 double x; /* The number to pack */
223 char *p; /* Where to pack the high order byte */
224 int incr; /* 1 for big-endian; -1 for little-endian */
225{
226 int s;
227 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000228 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000229 long fhi, flo;
230
231 if (x < 0) {
232 s = 1;
233 x = -x;
234 }
235 else
236 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000237
238 f = frexp(x, &e);
239
240 /* Normalize f to be in the range [1.0, 2.0) */
241 if (0.5 <= f && f < 1.0) {
242 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000243 e--;
244 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000245 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000246 e = 0;
247 }
248 else {
249 PyErr_SetString(PyExc_SystemError,
250 "frexp() result out of range");
251 return -1;
252 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000253
254 if (e >= 1024) {
255 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000256 PyErr_SetString(PyExc_OverflowError,
257 "float too large to pack with d format");
258 return -1;
259 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000260 else if (e < -1022) {
261 /* Gradual underflow */
262 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000263 e = 0;
264 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000265 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000266 e += 1023;
267 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000268 }
269
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000270 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
271 f *= 268435456.0; /* 2**28 */
272 fhi = (long) floor(f); /* Truncate */
273 f -= (double)fhi;
274 f *= 16777216.0; /* 2**24 */
275 flo = (long) floor(f + 0.5); /* Round */
276
Guido van Rossum74679b41997-01-02 22:21:36 +0000277 /* First byte */
278 *p = (s<<7) | (e>>4);
279 p += incr;
280
281 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000282 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000283 p += incr;
284
285 /* Third byte */
286 *p = (fhi>>16) & 0xFF;
287 p += incr;
288
289 /* Fourth byte */
290 *p = (fhi>>8) & 0xFF;
291 p += incr;
292
293 /* Fifth byte */
294 *p = fhi & 0xFF;
295 p += incr;
296
297 /* Sixth byte */
298 *p = (flo>>16) & 0xFF;
299 p += incr;
300
301 /* Seventh byte */
302 *p = (flo>>8) & 0xFF;
303 p += incr;
304
305 /* Eighth byte */
306 *p = flo & 0xFF;
307 p += incr;
308
309 /* Done */
310 return 0;
311}
312
313static PyObject *
314unpack_float(p, incr)
315 char *p; /* Where the high order byte is */
316 int incr; /* 1 for big-endian; -1 for little-endian */
317{
318 int s;
319 int e;
320 long f;
321 double x;
322
323 /* First byte */
324 s = (*p>>7) & 1;
325 e = (*p & 0x7F) << 1;
326 p += incr;
327
328 /* Second byte */
329 e |= (*p>>7) & 1;
330 f = (*p & 0x7F) << 16;
331 p += incr;
332
333 /* Third byte */
334 f |= (*p & 0xFF) << 8;
335 p += incr;
336
337 /* Fourth byte */
338 f |= *p & 0xFF;
339
340 x = (double)f / 8388608.0;
341
342 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000343 if (e == 0)
344 e = -126;
345 else {
346 x += 1.0;
347 e -= 127;
348 }
349 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000350
351 if (s)
352 x = -x;
353
354 return PyFloat_FromDouble(x);
355}
356
357static PyObject *
358unpack_double(p, incr)
359 char *p; /* Where the high order byte is */
360 int incr; /* 1 for big-endian; -1 for little-endian */
361{
362 int s;
363 int e;
364 long fhi, flo;
365 double x;
366
367 /* First byte */
368 s = (*p>>7) & 1;
369 e = (*p & 0x7F) << 4;
370 p += incr;
371
372 /* Second byte */
373 e |= (*p>>4) & 0xF;
374 fhi = (*p & 0xF) << 24;
375 p += incr;
376
377 /* Third byte */
378 fhi |= (*p & 0xFF) << 16;
379 p += incr;
380
381 /* Fourth byte */
382 fhi |= (*p & 0xFF) << 8;
383 p += incr;
384
385 /* Fifth byte */
386 fhi |= *p & 0xFF;
387 p += incr;
388
389 /* Sixth byte */
390 flo = (*p & 0xFF) << 16;
391 p += incr;
392
393 /* Seventh byte */
394 flo |= (*p & 0xFF) << 8;
395 p += incr;
396
397 /* Eighth byte */
398 flo |= *p & 0xFF;
399 p += incr;
400
401 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
402 x /= 268435456.0; /* 2**28 */
403
404 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000405 if (e == 0)
406 e = -1022;
407 else {
408 x += 1.0;
409 e -= 1023;
410 }
411 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000412
413 if (s)
414 x = -x;
415
416 return PyFloat_FromDouble(x);
417}
418
419
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000420/* The translation function for each format character is table driven */
421
422typedef struct _formatdef {
423 char format;
424 int size;
425 int alignment;
426 PyObject* (*unpack) Py_PROTO((const char *,
427 const struct _formatdef *));
428 int (*pack) Py_PROTO((char *,
429 PyObject *,
430 const struct _formatdef *));
431} formatdef;
432
433static PyObject *
434nu_char(p, f)
435 const char *p;
436 const formatdef *f;
437{
438 return PyString_FromStringAndSize(p, 1);
439}
440
441static PyObject *
442nu_byte(p, f)
443 const char *p;
444 const formatdef *f;
445{
446 return PyInt_FromLong((long) *(signed char *)p);
447}
448
449static PyObject *
450nu_ubyte(p, f)
451 const char *p;
452 const formatdef *f;
453{
454 return PyInt_FromLong((long) *(unsigned char *)p);
455}
456
457static PyObject *
458nu_short(p, f)
459 const char *p;
460 const formatdef *f;
461{
462 return PyInt_FromLong((long) *(short *)p);
463}
464
465static PyObject *
466nu_ushort(p, f)
467 const char *p;
468 const formatdef *f;
469{
470 return PyInt_FromLong((long) *(unsigned short *)p);
471}
472
473static PyObject *
474nu_int(p, f)
475 const char *p;
476 const formatdef *f;
477{
478 return PyInt_FromLong((long) *(int *)p);
479}
480
481static PyObject *
482nu_uint(p, f)
483 const char *p;
484 const formatdef *f;
485{
486 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000487 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000488}
489
490static PyObject *
491nu_long(p, f)
492 const char *p;
493 const formatdef *f;
494{
495 return PyInt_FromLong(*(long *)p);
496}
497
498static PyObject *
499nu_ulong(p, f)
500 const char *p;
501 const formatdef *f;
502{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000503 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000504}
505
506static PyObject *
507nu_float(p, f)
508 const char *p;
509 const formatdef *f;
510{
511 float x;
512 memcpy((char *)&x, p, sizeof(float));
513 return PyFloat_FromDouble((double)x);
514}
515
516static PyObject *
517nu_double(p, f)
518 const char *p;
519 const formatdef *f;
520{
521 double x;
522 memcpy((char *)&x, p, sizeof(double));
523 return PyFloat_FromDouble(x);
524}
525
526static int
527np_byte(p, v, f)
528 char *p;
529 PyObject *v;
530 const formatdef *f;
531{
532 long x;
533 if (get_long(v, &x) < 0)
534 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000535 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000536 return 0;
537}
538
539static int
540np_char(p, v, f)
541 char *p;
542 PyObject *v;
543 const formatdef *f;
544{
545 if (!PyString_Check(v) || PyString_Size(v) != 1) {
546 PyErr_SetString(StructError,
547 "char format require string of length 1");
548 return -1;
549 }
550 *p = *PyString_AsString(v);
551 return 0;
552}
553
554static int
555np_short(p, v, f)
556 char *p;
557 PyObject *v;
558 const formatdef *f;
559{
560 long x;
561 if (get_long(v, &x) < 0)
562 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000563 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000564 return 0;
565}
566
567static int
568np_int(p, v, f)
569 char *p;
570 PyObject *v;
571 const formatdef *f;
572{
573 long x;
574 if (get_long(v, &x) < 0)
575 return -1;
576 * (int *)p = x;
577 return 0;
578}
579
580static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000581np_uint(p, v, f)
582 char *p;
583 PyObject *v;
584 const formatdef *f;
585{
586 unsigned long x;
587 if (get_ulong(v, &x) < 0)
588 return -1;
589 * (unsigned int *)p = x;
590 return 0;
591}
592
593static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000594np_long(p, v, f)
595 char *p;
596 PyObject *v;
597 const formatdef *f;
598{
599 long x;
600 if (get_long(v, &x) < 0)
601 return -1;
602 * (long *)p = x;
603 return 0;
604}
605
606static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000607np_ulong(p, v, f)
608 char *p;
609 PyObject *v;
610 const formatdef *f;
611{
612 unsigned long x;
613 if (get_ulong(v, &x) < 0)
614 return -1;
615 * (unsigned long *)p = x;
616 return 0;
617}
618
619static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000620np_float(p, v, f)
621 char *p;
622 PyObject *v;
623 const formatdef *f;
624{
625 float x = (float)PyFloat_AsDouble(v);
626 if (x == -1 && PyErr_Occurred()) {
627 PyErr_SetString(StructError,
628 "required argument is not a float");
629 return -1;
630 }
631 memcpy(p, (char *)&x, sizeof(float));
632 return 0;
633}
634
635static int
636np_double(p, v, f)
637 char *p;
638 PyObject *v;
639 const formatdef *f;
640{
641 double x = PyFloat_AsDouble(v);
642 if (x == -1 && PyErr_Occurred()) {
643 PyErr_SetString(StructError,
644 "required argument is not a float");
645 return -1;
646 }
647 memcpy(p, (char *)&x, sizeof(double));
648 return 0;
649}
650
651static formatdef native_table[] = {
652 {'x', sizeof(char), 0, NULL},
653 {'b', sizeof(char), 0, nu_byte, np_byte},
654 {'B', sizeof(char), 0, nu_ubyte, np_byte},
655 {'c', sizeof(char), 0, nu_char, np_char},
656 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000657 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000658 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
659 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
660 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000661 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000662 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000663 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000664 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
665 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
666 {0}
667};
668
669static PyObject *
670bu_int(p, f)
671 const char *p;
672 const formatdef *f;
673{
674 long x = 0;
675 int i = f->size;
676 do {
677 x = (x<<8) | (*p++ & 0xFF);
678 } while (--i > 0);
679 i = 8*(sizeof(long) - f->size);
680 if (i) {
681 x <<= i;
682 x >>= i;
683 }
684 return PyInt_FromLong(x);
685}
686
687static PyObject *
688bu_uint(p, f)
689 const char *p;
690 const formatdef *f;
691{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000692 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000693 int i = f->size;
694 do {
695 x = (x<<8) | (*p++ & 0xFF);
696 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000697 if (f->size >= 4)
698 return PyLong_FromUnsignedLong(x);
699 else
700 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000701}
702
Guido van Rossum74679b41997-01-02 22:21:36 +0000703static PyObject *
704bu_float(p, f)
705 const char *p;
706 const formatdef *f;
707{
708 return unpack_float(p, 1);
709}
710
711static PyObject *
712bu_double(p, f)
713 const char *p;
714 const formatdef *f;
715{
716 return unpack_double(p, 1);
717}
718
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000719static int
720bp_int(p, v, f)
721 char *p;
722 PyObject *v;
723 const formatdef *f;
724{
725 long x;
726 int i;
727 if (get_long(v, &x) < 0)
728 return -1;
729 i = f->size;
730 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000731 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000732 x >>= 8;
733 } while (i > 0);
734 return 0;
735}
736
Guido van Rossum60c50611996-12-31 16:29:52 +0000737static int
738bp_uint(p, v, f)
739 char *p;
740 PyObject *v;
741 const formatdef *f;
742{
743 unsigned long x;
744 int i;
745 if (get_ulong(v, &x) < 0)
746 return -1;
747 i = f->size;
748 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000749 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000750 x >>= 8;
751 } while (i > 0);
752 return 0;
753}
754
Guido van Rossum74679b41997-01-02 22:21:36 +0000755static int
756bp_float(p, v, f)
757 char *p;
758 PyObject *v;
759 const formatdef *f;
760{
761 double x = PyFloat_AsDouble(v);
762 if (x == -1 && PyErr_Occurred()) {
763 PyErr_SetString(StructError,
764 "required argument is not a float");
765 return -1;
766 }
767 return pack_float(x, p, 1);
768}
769
770static int
771bp_double(p, v, f)
772 char *p;
773 PyObject *v;
774 const formatdef *f;
775{
776 double x = PyFloat_AsDouble(v);
777 if (x == -1 && PyErr_Occurred()) {
778 PyErr_SetString(StructError,
779 "required argument is not a float");
780 return -1;
781 }
782 return pack_double(x, p, 1);
783}
784
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000785static formatdef bigendian_table[] = {
786 {'x', 1, 0, NULL},
787 {'b', 1, 0, bu_int, bp_int},
788 {'B', 1, 0, bu_uint, bp_int},
789 {'c', 1, 0, nu_char, np_char},
790 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000791 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000792 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000793 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000794 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000795 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000796 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000797 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000798 {'f', 4, 0, bu_float, bp_float},
799 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000800 {0}
801};
802
803static PyObject *
804lu_int(p, f)
805 const char *p;
806 const formatdef *f;
807{
808 long x = 0;
809 int i = f->size;
810 do {
811 x = (x<<8) | (p[--i] & 0xFF);
812 } while (i > 0);
813 i = 8*(sizeof(long) - f->size);
814 if (i) {
815 x <<= i;
816 x >>= i;
817 }
818 return PyInt_FromLong(x);
819}
820
821static PyObject *
822lu_uint(p, f)
823 const char *p;
824 const formatdef *f;
825{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000826 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000827 int i = f->size;
828 do {
829 x = (x<<8) | (p[--i] & 0xFF);
830 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000831 if (f->size >= 4)
832 return PyLong_FromUnsignedLong(x);
833 else
834 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000835}
836
Guido van Rossum74679b41997-01-02 22:21:36 +0000837static PyObject *
838lu_float(p, f)
839 const char *p;
840 const formatdef *f;
841{
842 return unpack_float(p+3, -1);
843}
844
845static PyObject *
846lu_double(p, f)
847 const char *p;
848 const formatdef *f;
849{
850 return unpack_double(p+7, -1);
851}
852
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000853static int
854lp_int(p, v, f)
855 char *p;
856 PyObject *v;
857 const formatdef *f;
858{
859 long x;
860 int i;
861 if (get_long(v, &x) < 0)
862 return -1;
863 i = f->size;
864 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000865 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000866 x >>= 8;
867 } while (--i > 0);
868 return 0;
869}
870
Guido van Rossum60c50611996-12-31 16:29:52 +0000871static int
872lp_uint(p, v, f)
873 char *p;
874 PyObject *v;
875 const formatdef *f;
876{
877 unsigned long x;
878 int i;
879 if (get_ulong(v, &x) < 0)
880 return -1;
881 i = f->size;
882 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000883 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000884 x >>= 8;
885 } while (--i > 0);
886 return 0;
887}
888
Guido van Rossum74679b41997-01-02 22:21:36 +0000889static int
890lp_float(p, v, f)
891 char *p;
892 PyObject *v;
893 const formatdef *f;
894{
895 double x = PyFloat_AsDouble(v);
896 if (x == -1 && PyErr_Occurred()) {
897 PyErr_SetString(StructError,
898 "required argument is not a float");
899 return -1;
900 }
901 return pack_float(x, p+3, -1);
902}
903
904static int
905lp_double(p, v, f)
906 char *p;
907 PyObject *v;
908 const formatdef *f;
909{
910 double x = PyFloat_AsDouble(v);
911 if (x == -1 && PyErr_Occurred()) {
912 PyErr_SetString(StructError,
913 "required argument is not a float");
914 return -1;
915 }
916 return pack_double(x, p+7, -1);
917}
918
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000919static formatdef lilendian_table[] = {
920 {'x', 1, 0, NULL},
921 {'b', 1, 0, lu_int, lp_int},
922 {'B', 1, 0, lu_uint, lp_int},
923 {'c', 1, 0, nu_char, np_char},
924 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000925 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000926 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000927 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000928 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000929 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000930 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000931 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000932 {'f', 4, 0, lu_float, lp_float},
933 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000934 {0}
935};
936
937
938static const formatdef *
939whichtable(pfmt)
940 const char **pfmt;
941{
942 const char *fmt = (*pfmt)++; /* May be backed out of later */
943 switch (*fmt) {
944 case '<':
945 return lilendian_table;
946 case '>':
947 case '!': /* Network byte order is big-endian */
948 return bigendian_table;
949 case '=': { /* Host byte order -- different from native in aligment! */
950 int n = 1;
951 char *p = (char *) &n;
952 if (*p == 1)
953 return lilendian_table;
954 else
955 return bigendian_table;
956 }
957 default:
958 --*pfmt; /* Back out of pointer increment */
959 /* Fall through */
960 case '@':
961 return native_table;
962 }
963}
964
965
966/* Get the table entry for a format code */
967
968static const formatdef *
969getentry(c, f)
970 int c;
971 const formatdef *f;
972{
973 for (; f->format != '\0'; f++) {
974 if (f->format == c) {
975 return f;
976 }
977 }
978 PyErr_SetString(StructError, "bad char in struct format");
979 return NULL;
980}
981
982
Guido van Rossum02975121992-08-17 08:55:12 +0000983/* Align a size according to a format code */
984
985static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000986align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +0000987 int size;
988 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000989 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +0000990{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000991 if (e->format == c) {
992 if (e->alignment) {
993 size = ((size + e->alignment - 1)
994 / e->alignment)
995 * e->alignment;
996 }
Guido van Rossum02975121992-08-17 08:55:12 +0000997 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000998 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000999}
1000
1001
1002/* calculate the size of a format string */
1003
1004static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001005calcsize(fmt, f)
1006 const char *fmt;
1007 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001008{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001009 const formatdef *e;
1010 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001011 char c;
1012 int size, num, itemsize, x;
1013
1014 s = fmt;
1015 size = 0;
1016 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001017 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001018 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001019 if ('0' <= c && c <= '9') {
1020 num = c - '0';
1021 while ('0' <= (c = *s++) && c <= '9') {
1022 x = num*10 + (c - '0');
1023 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001024 PyErr_SetString(
1025 StructError,
1026 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001027 return -1;
1028 }
1029 num = x;
1030 }
1031 if (c == '\0')
1032 break;
1033 }
1034 else
1035 num = 1;
1036
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001037 e = getentry(c, f);
1038 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001039 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001040 itemsize = e->size;
1041 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001042 x = num * itemsize;
1043 size += x;
1044 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001045 PyErr_SetString(StructError,
1046 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001047 return -1;
1048 }
Guido van Rossum02975121992-08-17 08:55:12 +00001049 }
1050
1051 return size;
1052}
1053
1054
Guido van Rossum414fd481997-12-19 04:24:24 +00001055static char calcsize__doc__[] = "\
1056calcsize(fmt) -> int\n\
1057Return size of C struct described by format string fmt.\n\
1058See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001059
Barry Warsaw30695fa1996-12-12 23:32:31 +00001060static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001061struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001062 PyObject *self; /* Not used */
1063 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001064{
1065 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001066 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001067 int size;
1068
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001069 if (!PyArg_ParseTuple(args, "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 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001076}
1077
1078
Guido van Rossum414fd481997-12-19 04:24:24 +00001079static char pack__doc__[] = "\
1080pack(fmt, v1, v2, ...) -> string\n\
1081Return string containing values v1, v2, ... packed according to fmt.\n\
1082See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001083
Barry Warsaw30695fa1996-12-12 23:32:31 +00001084static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001085struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001086 PyObject *self; /* Not used */
1087 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001088{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001089 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001090 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001091 char *fmt;
1092 int size, num;
1093 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001094 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001095 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001096
Barry Warsaw30695fa1996-12-12 23:32:31 +00001097 if (args == NULL || !PyTuple_Check(args) ||
1098 (n = PyTuple_Size(args)) < 1)
1099 {
1100 PyErr_BadArgument();
Guido van Rossum02975121992-08-17 08:55:12 +00001101 return NULL;
1102 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001103 format = PyTuple_GetItem(args, 0);
1104 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001105 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001106 f = whichtable(&fmt);
1107 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001108 if (size < 0)
1109 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001110 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001111 if (result == NULL)
1112 return NULL;
1113
1114 s = fmt;
1115 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001116 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001117
1118 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001119 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001120 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001121 if ('0' <= c && c <= '9') {
1122 num = c - '0';
1123 while ('0' <= (c = *s++) && c <= '9')
1124 num = num*10 + (c - '0');
1125 if (c == '\0')
1126 break;
1127 }
1128 else
1129 num = 1;
1130
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001131 e = getentry(c, f);
1132 if (e == NULL)
1133 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001134 nres = restart + align((int)(res-restart), c, e);
1135 /* Fill padd bytes with zeros */
1136 while (res < nres)
1137 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001138 if (num == 0 && c != 's')
1139 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001140 do {
1141 if (c == 'x') {
1142 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001143 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001144 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001145 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001146 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001147 if (i >= n) {
1148 PyErr_SetString(StructError,
1149 "insufficient arguments to pack");
1150 goto fail;
1151 }
1152 v = PyTuple_GetItem(args, i++);
1153 if (v == NULL)
1154 goto fail;
1155 if (c == 's') {
1156 /* num is string size, not repeat count */
1157 int n;
1158 if (!PyString_Check(v)) {
1159 PyErr_SetString(StructError,
1160 "argument for 's' must be a string");
1161 goto fail;
1162 }
1163 n = PyString_Size(v);
1164 if (n > num)
1165 n = num;
1166 if (n > 0)
1167 memcpy(res, PyString_AsString(v), n);
1168 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001169 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001170 res += num;
1171 break;
1172 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001173 else if (c == 'p') {
1174 /* num is string size + 1,
1175 to fit in the count byte */
1176 int n;
1177 num--; /* now num is max string size */
1178 if (!PyString_Check(v)) {
1179 PyErr_SetString(StructError,
1180 "argument for 'p' must be a string");
1181 goto fail;
1182 }
1183 n = PyString_Size(v);
1184 if (n > num)
1185 n = num;
1186 if (n > 0)
1187 memcpy(res+1, PyString_AsString(v), n);
1188 if (n < num)
1189 /* no real need, just to be nice */
1190 memset(res+1+n, '\0', num-n);
1191 *res++ = n; /* store the length byte */
1192 res += num;
1193 break;
1194 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001195 else {
1196 if (e->pack(res, v, e) < 0)
1197 goto fail;
1198 res += e->size;
1199 }
1200 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001201 }
1202
1203 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001204 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001205 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001206 goto fail;
1207 }
1208
1209 return result;
1210
1211 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001212 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001213 return NULL;
1214}
1215
1216
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001217static char unpack__doc__[] = "\
1218unpack(fmt, string) -> (v1, v2, ...)\n\
1219Unpack the string, containing packed C structure data, according\n\
1220to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001221See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001222
Barry Warsaw30695fa1996-12-12 23:32:31 +00001223static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001224struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001225 PyObject *self; /* Not used */
1226 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001227{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001228 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001229 char *str, *start, *fmt, *s;
1230 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001231 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001232 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001233
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001234 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001235 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001236 f = whichtable(&fmt);
1237 size = calcsize(fmt, f);
1238 if (size < 0)
1239 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001240 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001241 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001242 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001243 return NULL;
1244 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001245 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001246 if (res == NULL)
1247 return NULL;
1248 str = start;
1249 s = fmt;
1250 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001251 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001252 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001253 if ('0' <= c && c <= '9') {
1254 num = c - '0';
1255 while ('0' <= (c = *s++) && c <= '9')
1256 num = num*10 + (c - '0');
1257 if (c == '\0')
1258 break;
1259 }
1260 else
1261 num = 1;
1262
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001263 e = getentry(c, f);
1264 if (e == NULL)
1265 goto fail;
1266 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001267 if (num == 0 && c != 's')
1268 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001269
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001270 do {
1271 if (c == 'x') {
1272 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001273 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001274 }
1275 if (c == 's') {
1276 /* num is string size, not repeat count */
1277 v = PyString_FromStringAndSize(str, num);
1278 if (v == NULL)
1279 goto fail;
1280 str += num;
1281 num = 0;
1282 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001283 else if (c == 'p') {
1284 /* num is string buffer size,
1285 not repeat count */
1286 int n = *(unsigned char*)str;
1287 /* first byte (unsigned) is string size */
1288 if (n >= num)
1289 n = num-1;
1290 v = PyString_FromStringAndSize(str+1, n);
1291 if (v == NULL)
1292 goto fail;
1293 str += num;
1294 num = 0;
1295 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001296 else {
1297 v = e->unpack(str, e);
1298 if (v == NULL)
1299 goto fail;
1300 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001301 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001302 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001303 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001304 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001305 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001306 }
1307
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001308 v = PyList_AsTuple(res);
1309 Py_DECREF(res);
1310 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001311
1312 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001313 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001314 return NULL;
1315}
1316
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001317
Guido van Rossum02975121992-08-17 08:55:12 +00001318/* List of functions */
1319
Barry Warsaw30695fa1996-12-12 23:32:31 +00001320static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001321 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1322 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1323 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001324 {NULL, NULL} /* sentinel */
1325};
1326
1327
1328/* Module initialization */
1329
1330void
1331initstruct()
1332{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001333 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001334
1335 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001336 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1337 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001338
1339 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001340 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001341 StructError = PyErr_NewException("struct.error", NULL, NULL);
1342 if (StructError == NULL)
1343 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001344 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001345}