blob: fac442f53f600c0209c8b37e6af8e4b84480365e [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum02975121992-08-17 08:55:12 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum02975121992-08-17 08:55:12 +00009******************************************************************/
10
11/* struct module -- pack values into and (out of) strings */
12
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000013/* New version supporting byte order, alignment and size options,
14 character strings, and unsigned numbers */
15
Guido van Rossum414fd481997-12-19 04:24:24 +000016static char struct__doc__[] = "\
17Functions to convert between Python values and C structs.\n\
18Python strings are used to hold the data representing the C struct\n\
19and also as format strings to describe the layout of data in the C struct.\n\
20\n\
21The optional first format char indicates byte ordering and alignment:\n\
22 @: native w/native alignment(default)\n\
23 =: native w/standard alignment\n\
24 <: little-endian, std. alignment\n\
25 >: big-endian, std. alignment\n\
26 !: network, std (same as >)\n\
27\n\
28The remaining chars indicate types of args and must match exactly;\n\
29these can be preceded by a decimal repeat count:\n\
30 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
31 h:short; H:unsigned short; i:int; I:unsigned int;\n\
32 l:long; L:unsigned long; f:float; d:double.\n\
33Special cases (preceding decimal count indicates length):\n\
34 s:string (array of char); p: pascal string (w. count byte).\n\
Guido van Rossum78694d91998-09-18 14:14:13 +000035Special case (only available in native format):\n\
36 P:an integer type that is wide enough to hold a pointer.\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000037Whitespace between formats is ignored.\n\
38\n\
39The variable struct.error is an exception raised on errors.";
40
Barry Warsaw30695fa1996-12-12 23:32:31 +000041#include "Python.h"
Guido van Rossum74679b41997-01-02 22:21:36 +000042#include "mymath.h"
Guido van Rossum02975121992-08-17 08:55:12 +000043
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000044#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000045#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000046
47
48/* Exception */
49
Barry Warsaw30695fa1996-12-12 23:32:31 +000050static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000051
52
53/* Define various structs to figure out the alignments of types */
54
Jack Jansen971e1df1995-02-02 14:29:10 +000055#ifdef __MWERKS__
56/*
57** XXXX We have a problem here. There are no unique alignment rules
58** on the PowerPC mac.
59*/
60#ifdef __powerc
61#pragma options align=mac68k
62#endif
63#endif /* __MWERKS__ */
64
Guido van Rossum02975121992-08-17 08:55:12 +000065typedef struct { char c; short x; } s_short;
66typedef struct { char c; int x; } s_int;
67typedef struct { char c; long x; } s_long;
68typedef struct { char c; float x; } s_float;
69typedef struct { char c; double x; } s_double;
Guido van Rossum78694d91998-09-18 14:14:13 +000070typedef struct { char c; void *x; } s_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000071
72#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
73#define INT_ALIGN (sizeof(s_int) - sizeof(int))
74#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
75#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
76#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
Guido van Rossum78694d91998-09-18 14:14:13 +000077#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
Guido van Rossum02975121992-08-17 08:55:12 +000078
Jack Jansen971e1df1995-02-02 14:29:10 +000079#ifdef __powerc
80#pragma options align=reset
81#endif
82
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000083/* Helper routine to get a Python integer and raise the appropriate error
84 if it isn't one */
85
86static int
87get_long(v, p)
88 PyObject *v;
89 long *p;
90{
91 long x = PyInt_AsLong(v);
92 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +000093 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000094 PyErr_SetString(StructError,
95 "required argument is not an integer");
96 return -1;
97 }
98 *p = x;
99 return 0;
100}
101
102
Guido van Rossum60c50611996-12-31 16:29:52 +0000103/* Same, but handling unsigned long */
104
105static int
106get_ulong(v, p)
107 PyObject *v;
108 unsigned long *p;
109{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000110 if (PyLong_Check(v)) {
111 unsigned long x = PyLong_AsUnsignedLong(v);
112 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000113 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000114 *p = x;
115 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000116 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000117 else {
118 return get_long(v, (long *)p);
119 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000120}
121
122
Guido van Rossum74679b41997-01-02 22:21:36 +0000123/* Floating point helpers */
124
125/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
126 Point Arithmetic). See the following URL:
127 http://www.psc.edu/general/software/packages/ieee/ieee.html */
128
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000129/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000130
131static int
132pack_float(x, p, incr)
133 double x; /* The number to pack */
134 char *p; /* Where to pack the high order byte */
135 int incr; /* 1 for big-endian; -1 for little-endian */
136{
137 int s;
138 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000139 double f;
140 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000141
142 if (x < 0) {
143 s = 1;
144 x = -x;
145 }
146 else
147 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000148
149 f = frexp(x, &e);
150
151 /* Normalize f to be in the range [1.0, 2.0) */
152 if (0.5 <= f && f < 1.0) {
153 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000154 e--;
155 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000156 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000157 e = 0;
158 }
159 else {
160 PyErr_SetString(PyExc_SystemError,
161 "frexp() result out of range");
162 return -1;
163 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000164
165 if (e >= 128) {
166 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000167 PyErr_SetString(PyExc_OverflowError,
168 "float too large to pack with f format");
169 return -1;
170 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000171 else if (e < -126) {
172 /* Gradual underflow */
173 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000174 e = 0;
175 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000176 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000177 e += 127;
178 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000179 }
180
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000181 f *= 8388608.0; /* 2**23 */
182 fbits = (long) floor(f + 0.5); /* Round */
183
Guido van Rossum74679b41997-01-02 22:21:36 +0000184 /* First byte */
185 *p = (s<<7) | (e>>1);
186 p += incr;
187
188 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000189 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000190 p += incr;
191
192 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000193 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000194 p += incr;
195
196 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000197 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000198
199 /* Done */
200 return 0;
201}
202
203static int
204pack_double(x, p, incr)
205 double x; /* The number to pack */
206 char *p; /* Where to pack the high order byte */
207 int incr; /* 1 for big-endian; -1 for little-endian */
208{
209 int s;
210 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000211 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000212 long fhi, flo;
213
214 if (x < 0) {
215 s = 1;
216 x = -x;
217 }
218 else
219 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000220
221 f = frexp(x, &e);
222
223 /* Normalize f to be in the range [1.0, 2.0) */
224 if (0.5 <= f && f < 1.0) {
225 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000226 e--;
227 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000228 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000229 e = 0;
230 }
231 else {
232 PyErr_SetString(PyExc_SystemError,
233 "frexp() result out of range");
234 return -1;
235 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000236
237 if (e >= 1024) {
238 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000239 PyErr_SetString(PyExc_OverflowError,
240 "float too large to pack with d format");
241 return -1;
242 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000243 else if (e < -1022) {
244 /* Gradual underflow */
245 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000246 e = 0;
247 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000248 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000249 e += 1023;
250 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000251 }
252
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000253 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
254 f *= 268435456.0; /* 2**28 */
255 fhi = (long) floor(f); /* Truncate */
256 f -= (double)fhi;
257 f *= 16777216.0; /* 2**24 */
258 flo = (long) floor(f + 0.5); /* Round */
259
Guido van Rossum74679b41997-01-02 22:21:36 +0000260 /* First byte */
261 *p = (s<<7) | (e>>4);
262 p += incr;
263
264 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000265 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000266 p += incr;
267
268 /* Third byte */
269 *p = (fhi>>16) & 0xFF;
270 p += incr;
271
272 /* Fourth byte */
273 *p = (fhi>>8) & 0xFF;
274 p += incr;
275
276 /* Fifth byte */
277 *p = fhi & 0xFF;
278 p += incr;
279
280 /* Sixth byte */
281 *p = (flo>>16) & 0xFF;
282 p += incr;
283
284 /* Seventh byte */
285 *p = (flo>>8) & 0xFF;
286 p += incr;
287
288 /* Eighth byte */
289 *p = flo & 0xFF;
290 p += incr;
291
292 /* Done */
293 return 0;
294}
295
296static PyObject *
297unpack_float(p, incr)
298 char *p; /* Where the high order byte is */
299 int incr; /* 1 for big-endian; -1 for little-endian */
300{
301 int s;
302 int e;
303 long f;
304 double x;
305
306 /* First byte */
307 s = (*p>>7) & 1;
308 e = (*p & 0x7F) << 1;
309 p += incr;
310
311 /* Second byte */
312 e |= (*p>>7) & 1;
313 f = (*p & 0x7F) << 16;
314 p += incr;
315
316 /* Third byte */
317 f |= (*p & 0xFF) << 8;
318 p += incr;
319
320 /* Fourth byte */
321 f |= *p & 0xFF;
322
323 x = (double)f / 8388608.0;
324
325 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000326 if (e == 0)
327 e = -126;
328 else {
329 x += 1.0;
330 e -= 127;
331 }
332 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000333
334 if (s)
335 x = -x;
336
337 return PyFloat_FromDouble(x);
338}
339
340static PyObject *
341unpack_double(p, incr)
342 char *p; /* Where the high order byte is */
343 int incr; /* 1 for big-endian; -1 for little-endian */
344{
345 int s;
346 int e;
347 long fhi, flo;
348 double x;
349
350 /* First byte */
351 s = (*p>>7) & 1;
352 e = (*p & 0x7F) << 4;
353 p += incr;
354
355 /* Second byte */
356 e |= (*p>>4) & 0xF;
357 fhi = (*p & 0xF) << 24;
358 p += incr;
359
360 /* Third byte */
361 fhi |= (*p & 0xFF) << 16;
362 p += incr;
363
364 /* Fourth byte */
365 fhi |= (*p & 0xFF) << 8;
366 p += incr;
367
368 /* Fifth byte */
369 fhi |= *p & 0xFF;
370 p += incr;
371
372 /* Sixth byte */
373 flo = (*p & 0xFF) << 16;
374 p += incr;
375
376 /* Seventh byte */
377 flo |= (*p & 0xFF) << 8;
378 p += incr;
379
380 /* Eighth byte */
381 flo |= *p & 0xFF;
382 p += incr;
383
384 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
385 x /= 268435456.0; /* 2**28 */
386
387 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000388 if (e == 0)
389 e = -1022;
390 else {
391 x += 1.0;
392 e -= 1023;
393 }
394 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000395
396 if (s)
397 x = -x;
398
399 return PyFloat_FromDouble(x);
400}
401
402
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000403/* The translation function for each format character is table driven */
404
405typedef struct _formatdef {
406 char format;
407 int size;
408 int alignment;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000409 PyObject* (*unpack)(const char *,
410 const struct _formatdef *);
411 int (*pack)(char *, PyObject *,
412 const struct _formatdef *);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000413} formatdef;
414
415static PyObject *
416nu_char(p, f)
417 const char *p;
418 const formatdef *f;
419{
420 return PyString_FromStringAndSize(p, 1);
421}
422
423static PyObject *
424nu_byte(p, f)
425 const char *p;
426 const formatdef *f;
427{
428 return PyInt_FromLong((long) *(signed char *)p);
429}
430
431static PyObject *
432nu_ubyte(p, f)
433 const char *p;
434 const formatdef *f;
435{
436 return PyInt_FromLong((long) *(unsigned char *)p);
437}
438
439static PyObject *
440nu_short(p, f)
441 const char *p;
442 const formatdef *f;
443{
444 return PyInt_FromLong((long) *(short *)p);
445}
446
447static PyObject *
448nu_ushort(p, f)
449 const char *p;
450 const formatdef *f;
451{
452 return PyInt_FromLong((long) *(unsigned short *)p);
453}
454
455static PyObject *
456nu_int(p, f)
457 const char *p;
458 const formatdef *f;
459{
460 return PyInt_FromLong((long) *(int *)p);
461}
462
463static PyObject *
464nu_uint(p, f)
465 const char *p;
466 const formatdef *f;
467{
468 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000469 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000470}
471
472static PyObject *
473nu_long(p, f)
474 const char *p;
475 const formatdef *f;
476{
477 return PyInt_FromLong(*(long *)p);
478}
479
480static PyObject *
481nu_ulong(p, f)
482 const char *p;
483 const formatdef *f;
484{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000485 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000486}
487
488static PyObject *
489nu_float(p, f)
490 const char *p;
491 const formatdef *f;
492{
493 float x;
494 memcpy((char *)&x, p, sizeof(float));
495 return PyFloat_FromDouble((double)x);
496}
497
498static PyObject *
499nu_double(p, f)
500 const char *p;
501 const formatdef *f;
502{
503 double x;
504 memcpy((char *)&x, p, sizeof(double));
505 return PyFloat_FromDouble(x);
506}
507
Guido van Rossum78694d91998-09-18 14:14:13 +0000508static PyObject *
509nu_void_p(p, f)
510 const char *p;
511 const formatdef *f;
512{
513 return PyLong_FromVoidPtr(*(void **)p);
514}
515
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000516static int
517np_byte(p, v, f)
518 char *p;
519 PyObject *v;
520 const formatdef *f;
521{
522 long x;
523 if (get_long(v, &x) < 0)
524 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000525 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000526 return 0;
527}
528
529static int
530np_char(p, v, f)
531 char *p;
532 PyObject *v;
533 const formatdef *f;
534{
535 if (!PyString_Check(v) || PyString_Size(v) != 1) {
536 PyErr_SetString(StructError,
537 "char format require string of length 1");
538 return -1;
539 }
540 *p = *PyString_AsString(v);
541 return 0;
542}
543
544static int
545np_short(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;
Guido van Rossum7844e381997-04-11 20:44:04 +0000553 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000554 return 0;
555}
556
557static int
558np_int(p, v, f)
559 char *p;
560 PyObject *v;
561 const formatdef *f;
562{
563 long x;
564 if (get_long(v, &x) < 0)
565 return -1;
566 * (int *)p = x;
567 return 0;
568}
569
570static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000571np_uint(p, v, f)
572 char *p;
573 PyObject *v;
574 const formatdef *f;
575{
576 unsigned long x;
577 if (get_ulong(v, &x) < 0)
578 return -1;
579 * (unsigned int *)p = x;
580 return 0;
581}
582
583static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000584np_long(p, v, f)
585 char *p;
586 PyObject *v;
587 const formatdef *f;
588{
589 long x;
590 if (get_long(v, &x) < 0)
591 return -1;
592 * (long *)p = x;
593 return 0;
594}
595
596static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000597np_ulong(p, v, f)
598 char *p;
599 PyObject *v;
600 const formatdef *f;
601{
602 unsigned long x;
603 if (get_ulong(v, &x) < 0)
604 return -1;
605 * (unsigned long *)p = x;
606 return 0;
607}
608
609static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000610np_float(p, v, f)
611 char *p;
612 PyObject *v;
613 const formatdef *f;
614{
615 float x = (float)PyFloat_AsDouble(v);
616 if (x == -1 && PyErr_Occurred()) {
617 PyErr_SetString(StructError,
618 "required argument is not a float");
619 return -1;
620 }
621 memcpy(p, (char *)&x, sizeof(float));
622 return 0;
623}
624
625static int
626np_double(p, v, f)
627 char *p;
628 PyObject *v;
629 const formatdef *f;
630{
631 double x = PyFloat_AsDouble(v);
632 if (x == -1 && PyErr_Occurred()) {
633 PyErr_SetString(StructError,
634 "required argument is not a float");
635 return -1;
636 }
637 memcpy(p, (char *)&x, sizeof(double));
638 return 0;
639}
640
Guido van Rossum78694d91998-09-18 14:14:13 +0000641static int
642np_void_p(p, v, f)
643 char *p;
644 PyObject *v;
645 const formatdef *f;
646{
647 void *x = PyLong_AsVoidPtr(v);
648 if (x == NULL && PyErr_Occurred()) {
649 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
650 if (PyErr_ExceptionMatches(PyExc_TypeError))
651 PyErr_SetString(StructError,
652 "required argument is not an integer");
653 return -1;
654 }
655 *(void **)p = x;
656 return 0;
657}
658
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000659static formatdef native_table[] = {
660 {'x', sizeof(char), 0, NULL},
661 {'b', sizeof(char), 0, nu_byte, np_byte},
662 {'B', sizeof(char), 0, nu_ubyte, np_byte},
663 {'c', sizeof(char), 0, nu_char, np_char},
664 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000665 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000666 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
667 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
668 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000669 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000670 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000671 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000672 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
673 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000674 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000675 {0}
676};
677
678static PyObject *
679bu_int(p, f)
680 const char *p;
681 const formatdef *f;
682{
683 long x = 0;
684 int i = f->size;
685 do {
686 x = (x<<8) | (*p++ & 0xFF);
687 } while (--i > 0);
688 i = 8*(sizeof(long) - f->size);
689 if (i) {
690 x <<= i;
691 x >>= i;
692 }
693 return PyInt_FromLong(x);
694}
695
696static PyObject *
697bu_uint(p, f)
698 const char *p;
699 const formatdef *f;
700{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000701 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000702 int i = f->size;
703 do {
704 x = (x<<8) | (*p++ & 0xFF);
705 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000706 if (f->size >= 4)
707 return PyLong_FromUnsignedLong(x);
708 else
709 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000710}
711
Guido van Rossum74679b41997-01-02 22:21:36 +0000712static PyObject *
713bu_float(p, f)
714 const char *p;
715 const formatdef *f;
716{
717 return unpack_float(p, 1);
718}
719
720static PyObject *
721bu_double(p, f)
722 const char *p;
723 const formatdef *f;
724{
725 return unpack_double(p, 1);
726}
727
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000728static int
729bp_int(p, v, f)
730 char *p;
731 PyObject *v;
732 const formatdef *f;
733{
734 long x;
735 int i;
736 if (get_long(v, &x) < 0)
737 return -1;
738 i = f->size;
739 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000740 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000741 x >>= 8;
742 } while (i > 0);
743 return 0;
744}
745
Guido van Rossum60c50611996-12-31 16:29:52 +0000746static int
747bp_uint(p, v, f)
748 char *p;
749 PyObject *v;
750 const formatdef *f;
751{
752 unsigned long x;
753 int i;
754 if (get_ulong(v, &x) < 0)
755 return -1;
756 i = f->size;
757 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000758 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000759 x >>= 8;
760 } while (i > 0);
761 return 0;
762}
763
Guido van Rossum74679b41997-01-02 22:21:36 +0000764static int
765bp_float(p, v, f)
766 char *p;
767 PyObject *v;
768 const formatdef *f;
769{
770 double x = PyFloat_AsDouble(v);
771 if (x == -1 && PyErr_Occurred()) {
772 PyErr_SetString(StructError,
773 "required argument is not a float");
774 return -1;
775 }
776 return pack_float(x, p, 1);
777}
778
779static int
780bp_double(p, v, f)
781 char *p;
782 PyObject *v;
783 const formatdef *f;
784{
785 double x = PyFloat_AsDouble(v);
786 if (x == -1 && PyErr_Occurred()) {
787 PyErr_SetString(StructError,
788 "required argument is not a float");
789 return -1;
790 }
791 return pack_double(x, p, 1);
792}
793
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000794static formatdef bigendian_table[] = {
795 {'x', 1, 0, NULL},
796 {'b', 1, 0, bu_int, bp_int},
797 {'B', 1, 0, bu_uint, bp_int},
798 {'c', 1, 0, nu_char, np_char},
799 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000800 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000801 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000802 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000803 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000804 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000805 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000806 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000807 {'f', 4, 0, bu_float, bp_float},
808 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000809 {0}
810};
811
812static PyObject *
813lu_int(p, f)
814 const char *p;
815 const formatdef *f;
816{
817 long x = 0;
818 int i = f->size;
819 do {
820 x = (x<<8) | (p[--i] & 0xFF);
821 } while (i > 0);
822 i = 8*(sizeof(long) - f->size);
823 if (i) {
824 x <<= i;
825 x >>= i;
826 }
827 return PyInt_FromLong(x);
828}
829
830static PyObject *
831lu_uint(p, f)
832 const char *p;
833 const formatdef *f;
834{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000835 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000836 int i = f->size;
837 do {
838 x = (x<<8) | (p[--i] & 0xFF);
839 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000840 if (f->size >= 4)
841 return PyLong_FromUnsignedLong(x);
842 else
843 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000844}
845
Guido van Rossum74679b41997-01-02 22:21:36 +0000846static PyObject *
847lu_float(p, f)
848 const char *p;
849 const formatdef *f;
850{
851 return unpack_float(p+3, -1);
852}
853
854static PyObject *
855lu_double(p, f)
856 const char *p;
857 const formatdef *f;
858{
859 return unpack_double(p+7, -1);
860}
861
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000862static int
863lp_int(p, v, f)
864 char *p;
865 PyObject *v;
866 const formatdef *f;
867{
868 long x;
869 int i;
870 if (get_long(v, &x) < 0)
871 return -1;
872 i = f->size;
873 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000874 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000875 x >>= 8;
876 } while (--i > 0);
877 return 0;
878}
879
Guido van Rossum60c50611996-12-31 16:29:52 +0000880static int
881lp_uint(p, v, f)
882 char *p;
883 PyObject *v;
884 const formatdef *f;
885{
886 unsigned long x;
887 int i;
888 if (get_ulong(v, &x) < 0)
889 return -1;
890 i = f->size;
891 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000892 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000893 x >>= 8;
894 } while (--i > 0);
895 return 0;
896}
897
Guido van Rossum74679b41997-01-02 22:21:36 +0000898static int
899lp_float(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_float(x, p+3, -1);
911}
912
913static int
914lp_double(p, v, f)
915 char *p;
916 PyObject *v;
917 const formatdef *f;
918{
919 double x = PyFloat_AsDouble(v);
920 if (x == -1 && PyErr_Occurred()) {
921 PyErr_SetString(StructError,
922 "required argument is not a float");
923 return -1;
924 }
925 return pack_double(x, p+7, -1);
926}
927
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000928static formatdef lilendian_table[] = {
929 {'x', 1, 0, NULL},
930 {'b', 1, 0, lu_int, lp_int},
931 {'B', 1, 0, lu_uint, lp_int},
932 {'c', 1, 0, nu_char, np_char},
933 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000934 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000935 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000936 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000937 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000938 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000939 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000940 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000941 {'f', 4, 0, lu_float, lp_float},
942 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000943 {0}
944};
945
946
947static const formatdef *
948whichtable(pfmt)
949 const char **pfmt;
950{
951 const char *fmt = (*pfmt)++; /* May be backed out of later */
952 switch (*fmt) {
953 case '<':
954 return lilendian_table;
955 case '>':
956 case '!': /* Network byte order is big-endian */
957 return bigendian_table;
958 case '=': { /* Host byte order -- different from native in aligment! */
959 int n = 1;
960 char *p = (char *) &n;
961 if (*p == 1)
962 return lilendian_table;
963 else
964 return bigendian_table;
965 }
966 default:
967 --*pfmt; /* Back out of pointer increment */
968 /* Fall through */
969 case '@':
970 return native_table;
971 }
972}
973
974
975/* Get the table entry for a format code */
976
977static const formatdef *
978getentry(c, f)
979 int c;
980 const formatdef *f;
981{
982 for (; f->format != '\0'; f++) {
983 if (f->format == c) {
984 return f;
985 }
986 }
987 PyErr_SetString(StructError, "bad char in struct format");
988 return NULL;
989}
990
991
Guido van Rossum02975121992-08-17 08:55:12 +0000992/* Align a size according to a format code */
993
994static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000995align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +0000996 int size;
997 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000998 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +0000999{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001000 if (e->format == c) {
1001 if (e->alignment) {
1002 size = ((size + e->alignment - 1)
1003 / e->alignment)
1004 * e->alignment;
1005 }
Guido van Rossum02975121992-08-17 08:55:12 +00001006 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001007 return size;
Guido van Rossum02975121992-08-17 08:55:12 +00001008}
1009
1010
1011/* calculate the size of a format string */
1012
1013static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001014calcsize(fmt, f)
1015 const char *fmt;
1016 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001017{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001018 const formatdef *e;
1019 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001020 char c;
1021 int size, num, itemsize, x;
1022
1023 s = fmt;
1024 size = 0;
1025 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001026 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001027 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001028 if ('0' <= c && c <= '9') {
1029 num = c - '0';
1030 while ('0' <= (c = *s++) && c <= '9') {
1031 x = num*10 + (c - '0');
1032 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001033 PyErr_SetString(
1034 StructError,
1035 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001036 return -1;
1037 }
1038 num = x;
1039 }
1040 if (c == '\0')
1041 break;
1042 }
1043 else
1044 num = 1;
1045
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001046 e = getentry(c, f);
1047 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001048 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001049 itemsize = e->size;
1050 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001051 x = num * itemsize;
1052 size += x;
1053 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001054 PyErr_SetString(StructError,
1055 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001056 return -1;
1057 }
Guido van Rossum02975121992-08-17 08:55:12 +00001058 }
1059
1060 return size;
1061}
1062
1063
Guido van Rossum414fd481997-12-19 04:24:24 +00001064static char calcsize__doc__[] = "\
1065calcsize(fmt) -> int\n\
1066Return size of C struct described by format string fmt.\n\
1067See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001068
Barry Warsaw30695fa1996-12-12 23:32:31 +00001069static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001070struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001071 PyObject *self; /* Not used */
1072 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001073{
1074 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001075 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001076 int size;
1077
Guido van Rossum43713e52000-02-29 13:59:29 +00001078 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001079 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001080 f = whichtable(&fmt);
1081 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001082 if (size < 0)
1083 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001084 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001085}
1086
1087
Guido van Rossum414fd481997-12-19 04:24:24 +00001088static char pack__doc__[] = "\
1089pack(fmt, v1, v2, ...) -> string\n\
1090Return string containing values v1, v2, ... packed according to fmt.\n\
1091See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001092
Barry Warsaw30695fa1996-12-12 23:32:31 +00001093static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001094struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001095 PyObject *self; /* Not used */
1096 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001097{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001098 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001099 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001100 char *fmt;
1101 int size, num;
1102 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001103 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001104 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001105
Barry Warsaw30695fa1996-12-12 23:32:31 +00001106 if (args == NULL || !PyTuple_Check(args) ||
1107 (n = PyTuple_Size(args)) < 1)
1108 {
Fred Drake137507e2000-06-01 02:02:46 +00001109 PyErr_SetString(PyExc_TypeError,
1110 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001111 return NULL;
1112 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001113 format = PyTuple_GetItem(args, 0);
1114 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001115 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001116 f = whichtable(&fmt);
1117 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001118 if (size < 0)
1119 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001120 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001121 if (result == NULL)
1122 return NULL;
1123
1124 s = fmt;
1125 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001126 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001127
1128 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001129 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001130 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001131 if ('0' <= c && c <= '9') {
1132 num = c - '0';
1133 while ('0' <= (c = *s++) && c <= '9')
1134 num = num*10 + (c - '0');
1135 if (c == '\0')
1136 break;
1137 }
1138 else
1139 num = 1;
1140
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001141 e = getentry(c, f);
1142 if (e == NULL)
1143 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001144 nres = restart + align((int)(res-restart), c, e);
1145 /* Fill padd bytes with zeros */
1146 while (res < nres)
1147 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001148 if (num == 0 && c != 's')
1149 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001150 do {
1151 if (c == 'x') {
1152 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001153 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001154 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001155 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001156 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001157 if (i >= n) {
1158 PyErr_SetString(StructError,
1159 "insufficient arguments to pack");
1160 goto fail;
1161 }
1162 v = PyTuple_GetItem(args, i++);
1163 if (v == NULL)
1164 goto fail;
1165 if (c == 's') {
1166 /* num is string size, not repeat count */
1167 int n;
1168 if (!PyString_Check(v)) {
1169 PyErr_SetString(StructError,
1170 "argument for 's' must be a string");
1171 goto fail;
1172 }
1173 n = PyString_Size(v);
1174 if (n > num)
1175 n = num;
1176 if (n > 0)
1177 memcpy(res, PyString_AsString(v), n);
1178 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001179 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001180 res += num;
1181 break;
1182 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001183 else if (c == 'p') {
1184 /* num is string size + 1,
1185 to fit in the count byte */
1186 int n;
1187 num--; /* now num is max string size */
1188 if (!PyString_Check(v)) {
1189 PyErr_SetString(StructError,
1190 "argument for 'p' must be a string");
1191 goto fail;
1192 }
1193 n = PyString_Size(v);
1194 if (n > num)
1195 n = num;
1196 if (n > 0)
1197 memcpy(res+1, PyString_AsString(v), n);
1198 if (n < num)
1199 /* no real need, just to be nice */
1200 memset(res+1+n, '\0', num-n);
1201 *res++ = n; /* store the length byte */
1202 res += num;
1203 break;
1204 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001205 else {
1206 if (e->pack(res, v, e) < 0)
1207 goto fail;
1208 res += e->size;
1209 }
1210 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001211 }
1212
1213 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001214 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001215 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001216 goto fail;
1217 }
1218
1219 return result;
1220
1221 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001222 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001223 return NULL;
1224}
1225
1226
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001227static char unpack__doc__[] = "\
1228unpack(fmt, string) -> (v1, v2, ...)\n\
1229Unpack the string, containing packed C structure data, according\n\
1230to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001231See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001232
Barry Warsaw30695fa1996-12-12 23:32:31 +00001233static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001234struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001235 PyObject *self; /* Not used */
1236 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001237{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001238 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001239 char *str, *start, *fmt, *s;
1240 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001241 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001242 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001243
Guido van Rossum43713e52000-02-29 13:59:29 +00001244 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001245 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001246 f = whichtable(&fmt);
1247 size = calcsize(fmt, f);
1248 if (size < 0)
1249 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001250 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001251 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001252 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001253 return NULL;
1254 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001255 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001256 if (res == NULL)
1257 return NULL;
1258 str = start;
1259 s = fmt;
1260 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001261 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001262 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001263 if ('0' <= c && c <= '9') {
1264 num = c - '0';
1265 while ('0' <= (c = *s++) && c <= '9')
1266 num = num*10 + (c - '0');
1267 if (c == '\0')
1268 break;
1269 }
1270 else
1271 num = 1;
1272
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001273 e = getentry(c, f);
1274 if (e == NULL)
1275 goto fail;
1276 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001277 if (num == 0 && c != 's')
1278 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001279
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001280 do {
1281 if (c == 'x') {
1282 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001283 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001284 }
1285 if (c == 's') {
1286 /* num is string size, not repeat count */
1287 v = PyString_FromStringAndSize(str, num);
1288 if (v == NULL)
1289 goto fail;
1290 str += num;
1291 num = 0;
1292 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001293 else if (c == 'p') {
1294 /* num is string buffer size,
1295 not repeat count */
1296 int n = *(unsigned char*)str;
1297 /* first byte (unsigned) is string size */
1298 if (n >= num)
1299 n = num-1;
1300 v = PyString_FromStringAndSize(str+1, n);
1301 if (v == NULL)
1302 goto fail;
1303 str += num;
1304 num = 0;
1305 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001306 else {
1307 v = e->unpack(str, e);
1308 if (v == NULL)
1309 goto fail;
1310 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001311 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001312 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001313 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001314 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001315 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001316 }
1317
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001318 v = PyList_AsTuple(res);
1319 Py_DECREF(res);
1320 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001321
1322 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001323 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001324 return NULL;
1325}
1326
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001327
Guido van Rossum02975121992-08-17 08:55:12 +00001328/* List of functions */
1329
Barry Warsaw30695fa1996-12-12 23:32:31 +00001330static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001331 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1332 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1333 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001334 {NULL, NULL} /* sentinel */
1335};
1336
1337
1338/* Module initialization */
1339
Guido van Rossum3886bb61998-12-04 18:50:17 +00001340DL_EXPORT(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001341initstruct()
1342{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001343 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001344
1345 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001346 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1347 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001348
1349 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001350 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001351 StructError = PyErr_NewException("struct.error", NULL, NULL);
1352 if (StructError == NULL)
1353 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001354 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001355}