blob: cb1b36ae458f68a7bb37b9681ecba75c65cc05e2 [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()) {
110 if (PyErr_Occurred() == PyExc_TypeError)
111 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 Rossum6c87eca1997-01-03 19:08:16 +0000697 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000698}
699
Guido van Rossum74679b41997-01-02 22:21:36 +0000700static PyObject *
701bu_float(p, f)
702 const char *p;
703 const formatdef *f;
704{
705 return unpack_float(p, 1);
706}
707
708static PyObject *
709bu_double(p, f)
710 const char *p;
711 const formatdef *f;
712{
713 return unpack_double(p, 1);
714}
715
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000716static int
717bp_int(p, v, f)
718 char *p;
719 PyObject *v;
720 const formatdef *f;
721{
722 long x;
723 int i;
724 if (get_long(v, &x) < 0)
725 return -1;
726 i = f->size;
727 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000728 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000729 x >>= 8;
730 } while (i > 0);
731 return 0;
732}
733
Guido van Rossum60c50611996-12-31 16:29:52 +0000734static int
735bp_uint(p, v, f)
736 char *p;
737 PyObject *v;
738 const formatdef *f;
739{
740 unsigned long x;
741 int i;
742 if (get_ulong(v, &x) < 0)
743 return -1;
744 i = f->size;
745 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000746 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000747 x >>= 8;
748 } while (i > 0);
749 return 0;
750}
751
Guido van Rossum74679b41997-01-02 22:21:36 +0000752static int
753bp_float(p, v, f)
754 char *p;
755 PyObject *v;
756 const formatdef *f;
757{
758 double x = PyFloat_AsDouble(v);
759 if (x == -1 && PyErr_Occurred()) {
760 PyErr_SetString(StructError,
761 "required argument is not a float");
762 return -1;
763 }
764 return pack_float(x, p, 1);
765}
766
767static int
768bp_double(p, v, f)
769 char *p;
770 PyObject *v;
771 const formatdef *f;
772{
773 double x = PyFloat_AsDouble(v);
774 if (x == -1 && PyErr_Occurred()) {
775 PyErr_SetString(StructError,
776 "required argument is not a float");
777 return -1;
778 }
779 return pack_double(x, p, 1);
780}
781
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000782static formatdef bigendian_table[] = {
783 {'x', 1, 0, NULL},
784 {'b', 1, 0, bu_int, bp_int},
785 {'B', 1, 0, bu_uint, bp_int},
786 {'c', 1, 0, nu_char, np_char},
787 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000788 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000789 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000790 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000791 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000792 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000793 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000794 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000795 {'f', 4, 0, bu_float, bp_float},
796 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000797 {0}
798};
799
800static PyObject *
801lu_int(p, f)
802 const char *p;
803 const formatdef *f;
804{
805 long x = 0;
806 int i = f->size;
807 do {
808 x = (x<<8) | (p[--i] & 0xFF);
809 } while (i > 0);
810 i = 8*(sizeof(long) - f->size);
811 if (i) {
812 x <<= i;
813 x >>= i;
814 }
815 return PyInt_FromLong(x);
816}
817
818static PyObject *
819lu_uint(p, f)
820 const char *p;
821 const formatdef *f;
822{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000823 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000824 int i = f->size;
825 do {
826 x = (x<<8) | (p[--i] & 0xFF);
827 } while (i > 0);
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000828 return PyLong_FromUnsignedLong(x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000829}
830
Guido van Rossum74679b41997-01-02 22:21:36 +0000831static PyObject *
832lu_float(p, f)
833 const char *p;
834 const formatdef *f;
835{
836 return unpack_float(p+3, -1);
837}
838
839static PyObject *
840lu_double(p, f)
841 const char *p;
842 const formatdef *f;
843{
844 return unpack_double(p+7, -1);
845}
846
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000847static int
848lp_int(p, v, f)
849 char *p;
850 PyObject *v;
851 const formatdef *f;
852{
853 long x;
854 int i;
855 if (get_long(v, &x) < 0)
856 return -1;
857 i = f->size;
858 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000859 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000860 x >>= 8;
861 } while (--i > 0);
862 return 0;
863}
864
Guido van Rossum60c50611996-12-31 16:29:52 +0000865static int
866lp_uint(p, v, f)
867 char *p;
868 PyObject *v;
869 const formatdef *f;
870{
871 unsigned long x;
872 int i;
873 if (get_ulong(v, &x) < 0)
874 return -1;
875 i = f->size;
876 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000877 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000878 x >>= 8;
879 } while (--i > 0);
880 return 0;
881}
882
Guido van Rossum74679b41997-01-02 22:21:36 +0000883static int
884lp_float(p, v, f)
885 char *p;
886 PyObject *v;
887 const formatdef *f;
888{
889 double x = PyFloat_AsDouble(v);
890 if (x == -1 && PyErr_Occurred()) {
891 PyErr_SetString(StructError,
892 "required argument is not a float");
893 return -1;
894 }
895 return pack_float(x, p+3, -1);
896}
897
898static int
899lp_double(p, v, f)
900 char *p;
901 PyObject *v;
902 const formatdef *f;
903{
904 double x = PyFloat_AsDouble(v);
905 if (x == -1 && PyErr_Occurred()) {
906 PyErr_SetString(StructError,
907 "required argument is not a float");
908 return -1;
909 }
910 return pack_double(x, p+7, -1);
911}
912
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000913static formatdef lilendian_table[] = {
914 {'x', 1, 0, NULL},
915 {'b', 1, 0, lu_int, lp_int},
916 {'B', 1, 0, lu_uint, lp_int},
917 {'c', 1, 0, nu_char, np_char},
918 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000919 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000920 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000921 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000922 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000923 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000924 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000925 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000926 {'f', 4, 0, lu_float, lp_float},
927 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000928 {0}
929};
930
931
932static const formatdef *
933whichtable(pfmt)
934 const char **pfmt;
935{
936 const char *fmt = (*pfmt)++; /* May be backed out of later */
937 switch (*fmt) {
938 case '<':
939 return lilendian_table;
940 case '>':
941 case '!': /* Network byte order is big-endian */
942 return bigendian_table;
943 case '=': { /* Host byte order -- different from native in aligment! */
944 int n = 1;
945 char *p = (char *) &n;
946 if (*p == 1)
947 return lilendian_table;
948 else
949 return bigendian_table;
950 }
951 default:
952 --*pfmt; /* Back out of pointer increment */
953 /* Fall through */
954 case '@':
955 return native_table;
956 }
957}
958
959
960/* Get the table entry for a format code */
961
962static const formatdef *
963getentry(c, f)
964 int c;
965 const formatdef *f;
966{
967 for (; f->format != '\0'; f++) {
968 if (f->format == c) {
969 return f;
970 }
971 }
972 PyErr_SetString(StructError, "bad char in struct format");
973 return NULL;
974}
975
976
Guido van Rossum02975121992-08-17 08:55:12 +0000977/* Align a size according to a format code */
978
979static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000980align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +0000981 int size;
982 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000983 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +0000984{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000985 if (e->format == c) {
986 if (e->alignment) {
987 size = ((size + e->alignment - 1)
988 / e->alignment)
989 * e->alignment;
990 }
Guido van Rossum02975121992-08-17 08:55:12 +0000991 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000992 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000993}
994
995
996/* calculate the size of a format string */
997
998static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000999calcsize(fmt, f)
1000 const char *fmt;
1001 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001002{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001003 const formatdef *e;
1004 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001005 char c;
1006 int size, num, itemsize, x;
1007
1008 s = fmt;
1009 size = 0;
1010 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +00001011 if (isspace(c))
1012 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001013 if ('0' <= c && c <= '9') {
1014 num = c - '0';
1015 while ('0' <= (c = *s++) && c <= '9') {
1016 x = num*10 + (c - '0');
1017 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001018 PyErr_SetString(
1019 StructError,
1020 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001021 return -1;
1022 }
1023 num = x;
1024 }
1025 if (c == '\0')
1026 break;
1027 }
1028 else
1029 num = 1;
1030
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001031 e = getentry(c, f);
1032 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001033 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001034 itemsize = e->size;
1035 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001036 x = num * itemsize;
1037 size += x;
1038 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001039 PyErr_SetString(StructError,
1040 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001041 return -1;
1042 }
Guido van Rossum02975121992-08-17 08:55:12 +00001043 }
1044
1045 return size;
1046}
1047
1048
Guido van Rossum414fd481997-12-19 04:24:24 +00001049static char calcsize__doc__[] = "\
1050calcsize(fmt) -> int\n\
1051Return size of C struct described by format string fmt.\n\
1052See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001053
Barry Warsaw30695fa1996-12-12 23:32:31 +00001054static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001055struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001056 PyObject *self; /* Not used */
1057 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001058{
1059 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001060 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001061 int size;
1062
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001063 if (!PyArg_ParseTuple(args, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001064 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001065 f = whichtable(&fmt);
1066 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001067 if (size < 0)
1068 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001069 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001070}
1071
1072
Guido van Rossum414fd481997-12-19 04:24:24 +00001073static char pack__doc__[] = "\
1074pack(fmt, v1, v2, ...) -> string\n\
1075Return string containing values v1, v2, ... packed according to fmt.\n\
1076See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001077
Barry Warsaw30695fa1996-12-12 23:32:31 +00001078static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001079struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001080 PyObject *self; /* Not used */
1081 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001082{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001083 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001084 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001085 char *fmt;
1086 int size, num;
1087 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001088 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001089 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001090
Barry Warsaw30695fa1996-12-12 23:32:31 +00001091 if (args == NULL || !PyTuple_Check(args) ||
1092 (n = PyTuple_Size(args)) < 1)
1093 {
1094 PyErr_BadArgument();
Guido van Rossum02975121992-08-17 08:55:12 +00001095 return NULL;
1096 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001097 format = PyTuple_GetItem(args, 0);
1098 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001099 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001100 f = whichtable(&fmt);
1101 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001102 if (size < 0)
1103 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001104 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001105 if (result == NULL)
1106 return NULL;
1107
1108 s = fmt;
1109 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001110 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001111
1112 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +00001113 if (isspace(c))
1114 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001115 if ('0' <= c && c <= '9') {
1116 num = c - '0';
1117 while ('0' <= (c = *s++) && c <= '9')
1118 num = num*10 + (c - '0');
1119 if (c == '\0')
1120 break;
1121 }
1122 else
1123 num = 1;
1124
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001125 e = getentry(c, f);
1126 if (e == NULL)
1127 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001128 nres = restart + align((int)(res-restart), c, e);
1129 /* Fill padd bytes with zeros */
1130 while (res < nres)
1131 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001132 if (num == 0 && c != 's')
1133 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001134 do {
1135 if (c == 'x') {
1136 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001137 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001138 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001139 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001140 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001141 if (i >= n) {
1142 PyErr_SetString(StructError,
1143 "insufficient arguments to pack");
1144 goto fail;
1145 }
1146 v = PyTuple_GetItem(args, i++);
1147 if (v == NULL)
1148 goto fail;
1149 if (c == 's') {
1150 /* num is string size, not repeat count */
1151 int n;
1152 if (!PyString_Check(v)) {
1153 PyErr_SetString(StructError,
1154 "argument for 's' must be a string");
1155 goto fail;
1156 }
1157 n = PyString_Size(v);
1158 if (n > num)
1159 n = num;
1160 if (n > 0)
1161 memcpy(res, PyString_AsString(v), n);
1162 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001163 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001164 res += num;
1165 break;
1166 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001167 else if (c == 'p') {
1168 /* num is string size + 1,
1169 to fit in the count byte */
1170 int n;
1171 num--; /* now num is max string size */
1172 if (!PyString_Check(v)) {
1173 PyErr_SetString(StructError,
1174 "argument for 'p' must be a string");
1175 goto fail;
1176 }
1177 n = PyString_Size(v);
1178 if (n > num)
1179 n = num;
1180 if (n > 0)
1181 memcpy(res+1, PyString_AsString(v), n);
1182 if (n < num)
1183 /* no real need, just to be nice */
1184 memset(res+1+n, '\0', num-n);
1185 *res++ = n; /* store the length byte */
1186 res += num;
1187 break;
1188 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001189 else {
1190 if (e->pack(res, v, e) < 0)
1191 goto fail;
1192 res += e->size;
1193 }
1194 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001195 }
1196
1197 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001198 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001199 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001200 goto fail;
1201 }
1202
1203 return result;
1204
1205 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001206 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001207 return NULL;
1208}
1209
1210
Guido van Rossum414fd481997-12-19 04:24:24 +00001211static char unpack__doc__[] =
1212"unpack(fmt, string) -> (v1, v2, ...)
1213Unpack the string, containing packed C structure data, according\n"
1214"to fmt. Requires len(string)==calcsize(fmt).\n\
1215See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001216
Barry Warsaw30695fa1996-12-12 23:32:31 +00001217static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001218struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001219 PyObject *self; /* Not used */
1220 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001221{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001222 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001223 char *str, *start, *fmt, *s;
1224 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001225 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001226 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001227
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001228 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001229 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001230 f = whichtable(&fmt);
1231 size = calcsize(fmt, f);
1232 if (size < 0)
1233 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001234 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001235 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001236 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001237 return NULL;
1238 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001239 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001240 if (res == NULL)
1241 return NULL;
1242 str = start;
1243 s = fmt;
1244 while ((c = *s++) != '\0') {
Guido van Rossume20aef51997-08-26 20:39:54 +00001245 if (isspace(c))
1246 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001247 if ('0' <= c && c <= '9') {
1248 num = c - '0';
1249 while ('0' <= (c = *s++) && c <= '9')
1250 num = num*10 + (c - '0');
1251 if (c == '\0')
1252 break;
1253 }
1254 else
1255 num = 1;
1256
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001257 e = getentry(c, f);
1258 if (e == NULL)
1259 goto fail;
1260 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001261 if (num == 0 && c != 's')
1262 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001263
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001264 do {
1265 if (c == 'x') {
1266 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001267 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001268 }
1269 if (c == 's') {
1270 /* num is string size, not repeat count */
1271 v = PyString_FromStringAndSize(str, num);
1272 if (v == NULL)
1273 goto fail;
1274 str += num;
1275 num = 0;
1276 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001277 else if (c == 'p') {
1278 /* num is string buffer size,
1279 not repeat count */
1280 int n = *(unsigned char*)str;
1281 /* first byte (unsigned) is string size */
1282 if (n >= num)
1283 n = num-1;
1284 v = PyString_FromStringAndSize(str+1, n);
1285 if (v == NULL)
1286 goto fail;
1287 str += num;
1288 num = 0;
1289 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001290 else {
1291 v = e->unpack(str, e);
1292 if (v == NULL)
1293 goto fail;
1294 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001295 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001296 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001297 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001298 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001299 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001300 }
1301
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001302 v = PyList_AsTuple(res);
1303 Py_DECREF(res);
1304 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001305
1306 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001307 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001308 return NULL;
1309}
1310
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001311
Guido van Rossum02975121992-08-17 08:55:12 +00001312/* List of functions */
1313
Barry Warsaw30695fa1996-12-12 23:32:31 +00001314static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001315 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1316 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1317 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001318 {NULL, NULL} /* sentinel */
1319};
1320
1321
1322/* Module initialization */
1323
1324void
1325initstruct()
1326{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001327 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001328
1329 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001330 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1331 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001332
1333 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001334 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001335 StructError = PyErr_NewException("struct.error", NULL, NULL);
1336 if (StructError == NULL)
1337 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001338 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001339}