blob: d872e31aa3830e55311585bb72b9224c0869b90f [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\
Guido van Rossum78694d91998-09-18 14:14:13 +000056Special case (only available in native format):\n\
57 P:an integer type that is wide enough to hold a pointer.\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000058Whitespace between formats is ignored.\n\
59\n\
60The variable struct.error is an exception raised on errors.";
61
Barry Warsaw30695fa1996-12-12 23:32:31 +000062#include "Python.h"
Guido van Rossum74679b41997-01-02 22:21:36 +000063#include "mymath.h"
Guido van Rossum02975121992-08-17 08:55:12 +000064
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000065#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000066#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000067
68
69/* Exception */
70
Barry Warsaw30695fa1996-12-12 23:32:31 +000071static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000072
73
74/* Define various structs to figure out the alignments of types */
75
Jack Jansen971e1df1995-02-02 14:29:10 +000076#ifdef __MWERKS__
77/*
78** XXXX We have a problem here. There are no unique alignment rules
79** on the PowerPC mac.
80*/
81#ifdef __powerc
82#pragma options align=mac68k
83#endif
84#endif /* __MWERKS__ */
85
Guido van Rossum02975121992-08-17 08:55:12 +000086typedef struct { char c; short x; } s_short;
87typedef struct { char c; int x; } s_int;
88typedef struct { char c; long x; } s_long;
89typedef struct { char c; float x; } s_float;
90typedef struct { char c; double x; } s_double;
Guido van Rossum78694d91998-09-18 14:14:13 +000091typedef struct { char c; void *x; } s_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000092
93#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
94#define INT_ALIGN (sizeof(s_int) - sizeof(int))
95#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
96#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
97#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
Guido van Rossum78694d91998-09-18 14:14:13 +000098#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
Guido van Rossum02975121992-08-17 08:55:12 +000099
Jack Jansen971e1df1995-02-02 14:29:10 +0000100#ifdef __powerc
101#pragma options align=reset
102#endif
103
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000104/* Helper routine to get a Python integer and raise the appropriate error
105 if it isn't one */
106
107static int
108get_long(v, p)
109 PyObject *v;
110 long *p;
111{
112 long x = PyInt_AsLong(v);
113 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +0000114 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000115 PyErr_SetString(StructError,
116 "required argument is not an integer");
117 return -1;
118 }
119 *p = x;
120 return 0;
121}
122
123
Guido van Rossum60c50611996-12-31 16:29:52 +0000124/* Same, but handling unsigned long */
125
126static int
127get_ulong(v, p)
128 PyObject *v;
129 unsigned long *p;
130{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000131 if (PyLong_Check(v)) {
132 unsigned long x = PyLong_AsUnsignedLong(v);
133 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000134 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000135 *p = x;
136 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000137 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000138 else {
139 return get_long(v, (long *)p);
140 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000141}
142
143
Guido van Rossum74679b41997-01-02 22:21:36 +0000144/* Floating point helpers */
145
146/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
147 Point Arithmetic). See the following URL:
148 http://www.psc.edu/general/software/packages/ieee/ieee.html */
149
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000150/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000151
152static int
153pack_float(x, p, incr)
154 double x; /* The number to pack */
155 char *p; /* Where to pack the high order byte */
156 int incr; /* 1 for big-endian; -1 for little-endian */
157{
158 int s;
159 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000160 double f;
161 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000162
163 if (x < 0) {
164 s = 1;
165 x = -x;
166 }
167 else
168 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000169
170 f = frexp(x, &e);
171
172 /* Normalize f to be in the range [1.0, 2.0) */
173 if (0.5 <= f && f < 1.0) {
174 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000175 e--;
176 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000177 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000178 e = 0;
179 }
180 else {
181 PyErr_SetString(PyExc_SystemError,
182 "frexp() result out of range");
183 return -1;
184 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000185
186 if (e >= 128) {
187 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000188 PyErr_SetString(PyExc_OverflowError,
189 "float too large to pack with f format");
190 return -1;
191 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000192 else if (e < -126) {
193 /* Gradual underflow */
194 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000195 e = 0;
196 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000197 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000198 e += 127;
199 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000200 }
201
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000202 f *= 8388608.0; /* 2**23 */
203 fbits = (long) floor(f + 0.5); /* Round */
204
Guido van Rossum74679b41997-01-02 22:21:36 +0000205 /* First byte */
206 *p = (s<<7) | (e>>1);
207 p += incr;
208
209 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000210 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000211 p += incr;
212
213 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000214 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000215 p += incr;
216
217 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000218 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000219
220 /* Done */
221 return 0;
222}
223
224static int
225pack_double(x, p, incr)
226 double x; /* The number to pack */
227 char *p; /* Where to pack the high order byte */
228 int incr; /* 1 for big-endian; -1 for little-endian */
229{
230 int s;
231 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000232 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000233 long fhi, flo;
234
235 if (x < 0) {
236 s = 1;
237 x = -x;
238 }
239 else
240 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000241
242 f = frexp(x, &e);
243
244 /* Normalize f to be in the range [1.0, 2.0) */
245 if (0.5 <= f && f < 1.0) {
246 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000247 e--;
248 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000249 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000250 e = 0;
251 }
252 else {
253 PyErr_SetString(PyExc_SystemError,
254 "frexp() result out of range");
255 return -1;
256 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000257
258 if (e >= 1024) {
259 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000260 PyErr_SetString(PyExc_OverflowError,
261 "float too large to pack with d format");
262 return -1;
263 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000264 else if (e < -1022) {
265 /* Gradual underflow */
266 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000267 e = 0;
268 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000269 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000270 e += 1023;
271 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000272 }
273
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000274 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
275 f *= 268435456.0; /* 2**28 */
276 fhi = (long) floor(f); /* Truncate */
277 f -= (double)fhi;
278 f *= 16777216.0; /* 2**24 */
279 flo = (long) floor(f + 0.5); /* Round */
280
Guido van Rossum74679b41997-01-02 22:21:36 +0000281 /* First byte */
282 *p = (s<<7) | (e>>4);
283 p += incr;
284
285 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000286 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000287 p += incr;
288
289 /* Third byte */
290 *p = (fhi>>16) & 0xFF;
291 p += incr;
292
293 /* Fourth byte */
294 *p = (fhi>>8) & 0xFF;
295 p += incr;
296
297 /* Fifth byte */
298 *p = fhi & 0xFF;
299 p += incr;
300
301 /* Sixth byte */
302 *p = (flo>>16) & 0xFF;
303 p += incr;
304
305 /* Seventh byte */
306 *p = (flo>>8) & 0xFF;
307 p += incr;
308
309 /* Eighth byte */
310 *p = flo & 0xFF;
311 p += incr;
312
313 /* Done */
314 return 0;
315}
316
317static PyObject *
318unpack_float(p, incr)
319 char *p; /* Where the high order byte is */
320 int incr; /* 1 for big-endian; -1 for little-endian */
321{
322 int s;
323 int e;
324 long f;
325 double x;
326
327 /* First byte */
328 s = (*p>>7) & 1;
329 e = (*p & 0x7F) << 1;
330 p += incr;
331
332 /* Second byte */
333 e |= (*p>>7) & 1;
334 f = (*p & 0x7F) << 16;
335 p += incr;
336
337 /* Third byte */
338 f |= (*p & 0xFF) << 8;
339 p += incr;
340
341 /* Fourth byte */
342 f |= *p & 0xFF;
343
344 x = (double)f / 8388608.0;
345
346 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000347 if (e == 0)
348 e = -126;
349 else {
350 x += 1.0;
351 e -= 127;
352 }
353 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000354
355 if (s)
356 x = -x;
357
358 return PyFloat_FromDouble(x);
359}
360
361static PyObject *
362unpack_double(p, incr)
363 char *p; /* Where the high order byte is */
364 int incr; /* 1 for big-endian; -1 for little-endian */
365{
366 int s;
367 int e;
368 long fhi, flo;
369 double x;
370
371 /* First byte */
372 s = (*p>>7) & 1;
373 e = (*p & 0x7F) << 4;
374 p += incr;
375
376 /* Second byte */
377 e |= (*p>>4) & 0xF;
378 fhi = (*p & 0xF) << 24;
379 p += incr;
380
381 /* Third byte */
382 fhi |= (*p & 0xFF) << 16;
383 p += incr;
384
385 /* Fourth byte */
386 fhi |= (*p & 0xFF) << 8;
387 p += incr;
388
389 /* Fifth byte */
390 fhi |= *p & 0xFF;
391 p += incr;
392
393 /* Sixth byte */
394 flo = (*p & 0xFF) << 16;
395 p += incr;
396
397 /* Seventh byte */
398 flo |= (*p & 0xFF) << 8;
399 p += incr;
400
401 /* Eighth byte */
402 flo |= *p & 0xFF;
403 p += incr;
404
405 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
406 x /= 268435456.0; /* 2**28 */
407
408 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000409 if (e == 0)
410 e = -1022;
411 else {
412 x += 1.0;
413 e -= 1023;
414 }
415 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000416
417 if (s)
418 x = -x;
419
420 return PyFloat_FromDouble(x);
421}
422
423
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000424/* The translation function for each format character is table driven */
425
426typedef struct _formatdef {
427 char format;
428 int size;
429 int alignment;
430 PyObject* (*unpack) Py_PROTO((const char *,
431 const struct _formatdef *));
432 int (*pack) Py_PROTO((char *,
433 PyObject *,
434 const struct _formatdef *));
435} formatdef;
436
437static PyObject *
438nu_char(p, f)
439 const char *p;
440 const formatdef *f;
441{
442 return PyString_FromStringAndSize(p, 1);
443}
444
445static PyObject *
446nu_byte(p, f)
447 const char *p;
448 const formatdef *f;
449{
450 return PyInt_FromLong((long) *(signed char *)p);
451}
452
453static PyObject *
454nu_ubyte(p, f)
455 const char *p;
456 const formatdef *f;
457{
458 return PyInt_FromLong((long) *(unsigned char *)p);
459}
460
461static PyObject *
462nu_short(p, f)
463 const char *p;
464 const formatdef *f;
465{
466 return PyInt_FromLong((long) *(short *)p);
467}
468
469static PyObject *
470nu_ushort(p, f)
471 const char *p;
472 const formatdef *f;
473{
474 return PyInt_FromLong((long) *(unsigned short *)p);
475}
476
477static PyObject *
478nu_int(p, f)
479 const char *p;
480 const formatdef *f;
481{
482 return PyInt_FromLong((long) *(int *)p);
483}
484
485static PyObject *
486nu_uint(p, f)
487 const char *p;
488 const formatdef *f;
489{
490 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000491 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000492}
493
494static PyObject *
495nu_long(p, f)
496 const char *p;
497 const formatdef *f;
498{
499 return PyInt_FromLong(*(long *)p);
500}
501
502static PyObject *
503nu_ulong(p, f)
504 const char *p;
505 const formatdef *f;
506{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000507 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000508}
509
510static PyObject *
511nu_float(p, f)
512 const char *p;
513 const formatdef *f;
514{
515 float x;
516 memcpy((char *)&x, p, sizeof(float));
517 return PyFloat_FromDouble((double)x);
518}
519
520static PyObject *
521nu_double(p, f)
522 const char *p;
523 const formatdef *f;
524{
525 double x;
526 memcpy((char *)&x, p, sizeof(double));
527 return PyFloat_FromDouble(x);
528}
529
Guido van Rossum78694d91998-09-18 14:14:13 +0000530static PyObject *
531nu_void_p(p, f)
532 const char *p;
533 const formatdef *f;
534{
535 return PyLong_FromVoidPtr(*(void **)p);
536}
537
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000538static int
539np_byte(p, v, f)
540 char *p;
541 PyObject *v;
542 const formatdef *f;
543{
544 long x;
545 if (get_long(v, &x) < 0)
546 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000547 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000548 return 0;
549}
550
551static int
552np_char(p, v, f)
553 char *p;
554 PyObject *v;
555 const formatdef *f;
556{
557 if (!PyString_Check(v) || PyString_Size(v) != 1) {
558 PyErr_SetString(StructError,
559 "char format require string of length 1");
560 return -1;
561 }
562 *p = *PyString_AsString(v);
563 return 0;
564}
565
566static int
567np_short(p, v, f)
568 char *p;
569 PyObject *v;
570 const formatdef *f;
571{
572 long x;
573 if (get_long(v, &x) < 0)
574 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000575 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000576 return 0;
577}
578
579static int
580np_int(p, v, f)
581 char *p;
582 PyObject *v;
583 const formatdef *f;
584{
585 long x;
586 if (get_long(v, &x) < 0)
587 return -1;
588 * (int *)p = x;
589 return 0;
590}
591
592static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000593np_uint(p, v, f)
594 char *p;
595 PyObject *v;
596 const formatdef *f;
597{
598 unsigned long x;
599 if (get_ulong(v, &x) < 0)
600 return -1;
601 * (unsigned int *)p = x;
602 return 0;
603}
604
605static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000606np_long(p, v, f)
607 char *p;
608 PyObject *v;
609 const formatdef *f;
610{
611 long x;
612 if (get_long(v, &x) < 0)
613 return -1;
614 * (long *)p = x;
615 return 0;
616}
617
618static int
Guido van Rossum60c50611996-12-31 16:29:52 +0000619np_ulong(p, v, f)
620 char *p;
621 PyObject *v;
622 const formatdef *f;
623{
624 unsigned long x;
625 if (get_ulong(v, &x) < 0)
626 return -1;
627 * (unsigned long *)p = x;
628 return 0;
629}
630
631static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000632np_float(p, v, f)
633 char *p;
634 PyObject *v;
635 const formatdef *f;
636{
637 float x = (float)PyFloat_AsDouble(v);
638 if (x == -1 && PyErr_Occurred()) {
639 PyErr_SetString(StructError,
640 "required argument is not a float");
641 return -1;
642 }
643 memcpy(p, (char *)&x, sizeof(float));
644 return 0;
645}
646
647static int
648np_double(p, v, f)
649 char *p;
650 PyObject *v;
651 const formatdef *f;
652{
653 double x = PyFloat_AsDouble(v);
654 if (x == -1 && PyErr_Occurred()) {
655 PyErr_SetString(StructError,
656 "required argument is not a float");
657 return -1;
658 }
659 memcpy(p, (char *)&x, sizeof(double));
660 return 0;
661}
662
Guido van Rossum78694d91998-09-18 14:14:13 +0000663static int
664np_void_p(p, v, f)
665 char *p;
666 PyObject *v;
667 const formatdef *f;
668{
669 void *x = PyLong_AsVoidPtr(v);
670 if (x == NULL && PyErr_Occurred()) {
671 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
672 if (PyErr_ExceptionMatches(PyExc_TypeError))
673 PyErr_SetString(StructError,
674 "required argument is not an integer");
675 return -1;
676 }
677 *(void **)p = x;
678 return 0;
679}
680
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000681static formatdef native_table[] = {
682 {'x', sizeof(char), 0, NULL},
683 {'b', sizeof(char), 0, nu_byte, np_byte},
684 {'B', sizeof(char), 0, nu_ubyte, np_byte},
685 {'c', sizeof(char), 0, nu_char, np_char},
686 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000687 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000688 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
689 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
690 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000691 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000692 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000693 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000694 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
695 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000696 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000697 {0}
698};
699
700static PyObject *
701bu_int(p, f)
702 const char *p;
703 const formatdef *f;
704{
705 long x = 0;
706 int i = f->size;
707 do {
708 x = (x<<8) | (*p++ & 0xFF);
709 } while (--i > 0);
710 i = 8*(sizeof(long) - f->size);
711 if (i) {
712 x <<= i;
713 x >>= i;
714 }
715 return PyInt_FromLong(x);
716}
717
718static PyObject *
719bu_uint(p, f)
720 const char *p;
721 const formatdef *f;
722{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000723 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000724 int i = f->size;
725 do {
726 x = (x<<8) | (*p++ & 0xFF);
727 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000728 if (f->size >= 4)
729 return PyLong_FromUnsignedLong(x);
730 else
731 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000732}
733
Guido van Rossum74679b41997-01-02 22:21:36 +0000734static PyObject *
735bu_float(p, f)
736 const char *p;
737 const formatdef *f;
738{
739 return unpack_float(p, 1);
740}
741
742static PyObject *
743bu_double(p, f)
744 const char *p;
745 const formatdef *f;
746{
747 return unpack_double(p, 1);
748}
749
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000750static int
751bp_int(p, v, f)
752 char *p;
753 PyObject *v;
754 const formatdef *f;
755{
756 long x;
757 int i;
758 if (get_long(v, &x) < 0)
759 return -1;
760 i = f->size;
761 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000762 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000763 x >>= 8;
764 } while (i > 0);
765 return 0;
766}
767
Guido van Rossum60c50611996-12-31 16:29:52 +0000768static int
769bp_uint(p, v, f)
770 char *p;
771 PyObject *v;
772 const formatdef *f;
773{
774 unsigned long x;
775 int i;
776 if (get_ulong(v, &x) < 0)
777 return -1;
778 i = f->size;
779 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000780 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000781 x >>= 8;
782 } while (i > 0);
783 return 0;
784}
785
Guido van Rossum74679b41997-01-02 22:21:36 +0000786static int
787bp_float(p, v, f)
788 char *p;
789 PyObject *v;
790 const formatdef *f;
791{
792 double x = PyFloat_AsDouble(v);
793 if (x == -1 && PyErr_Occurred()) {
794 PyErr_SetString(StructError,
795 "required argument is not a float");
796 return -1;
797 }
798 return pack_float(x, p, 1);
799}
800
801static int
802bp_double(p, v, f)
803 char *p;
804 PyObject *v;
805 const formatdef *f;
806{
807 double x = PyFloat_AsDouble(v);
808 if (x == -1 && PyErr_Occurred()) {
809 PyErr_SetString(StructError,
810 "required argument is not a float");
811 return -1;
812 }
813 return pack_double(x, p, 1);
814}
815
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000816static formatdef bigendian_table[] = {
817 {'x', 1, 0, NULL},
818 {'b', 1, 0, bu_int, bp_int},
819 {'B', 1, 0, bu_uint, bp_int},
820 {'c', 1, 0, nu_char, np_char},
821 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000822 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000823 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000824 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000825 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000826 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000827 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000828 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000829 {'f', 4, 0, bu_float, bp_float},
830 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000831 {0}
832};
833
834static PyObject *
835lu_int(p, f)
836 const char *p;
837 const formatdef *f;
838{
839 long x = 0;
840 int i = f->size;
841 do {
842 x = (x<<8) | (p[--i] & 0xFF);
843 } while (i > 0);
844 i = 8*(sizeof(long) - f->size);
845 if (i) {
846 x <<= i;
847 x >>= i;
848 }
849 return PyInt_FromLong(x);
850}
851
852static PyObject *
853lu_uint(p, f)
854 const char *p;
855 const formatdef *f;
856{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000857 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000858 int i = f->size;
859 do {
860 x = (x<<8) | (p[--i] & 0xFF);
861 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000862 if (f->size >= 4)
863 return PyLong_FromUnsignedLong(x);
864 else
865 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000866}
867
Guido van Rossum74679b41997-01-02 22:21:36 +0000868static PyObject *
869lu_float(p, f)
870 const char *p;
871 const formatdef *f;
872{
873 return unpack_float(p+3, -1);
874}
875
876static PyObject *
877lu_double(p, f)
878 const char *p;
879 const formatdef *f;
880{
881 return unpack_double(p+7, -1);
882}
883
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000884static int
885lp_int(p, v, f)
886 char *p;
887 PyObject *v;
888 const formatdef *f;
889{
890 long x;
891 int i;
892 if (get_long(v, &x) < 0)
893 return -1;
894 i = f->size;
895 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000896 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000897 x >>= 8;
898 } while (--i > 0);
899 return 0;
900}
901
Guido van Rossum60c50611996-12-31 16:29:52 +0000902static int
903lp_uint(p, v, f)
904 char *p;
905 PyObject *v;
906 const formatdef *f;
907{
908 unsigned long x;
909 int i;
910 if (get_ulong(v, &x) < 0)
911 return -1;
912 i = f->size;
913 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000914 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000915 x >>= 8;
916 } while (--i > 0);
917 return 0;
918}
919
Guido van Rossum74679b41997-01-02 22:21:36 +0000920static int
921lp_float(p, v, f)
922 char *p;
923 PyObject *v;
924 const formatdef *f;
925{
926 double x = PyFloat_AsDouble(v);
927 if (x == -1 && PyErr_Occurred()) {
928 PyErr_SetString(StructError,
929 "required argument is not a float");
930 return -1;
931 }
932 return pack_float(x, p+3, -1);
933}
934
935static int
936lp_double(p, v, f)
937 char *p;
938 PyObject *v;
939 const formatdef *f;
940{
941 double x = PyFloat_AsDouble(v);
942 if (x == -1 && PyErr_Occurred()) {
943 PyErr_SetString(StructError,
944 "required argument is not a float");
945 return -1;
946 }
947 return pack_double(x, p+7, -1);
948}
949
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000950static formatdef lilendian_table[] = {
951 {'x', 1, 0, NULL},
952 {'b', 1, 0, lu_int, lp_int},
953 {'B', 1, 0, lu_uint, lp_int},
954 {'c', 1, 0, nu_char, np_char},
955 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000956 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000957 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000958 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000959 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000960 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000961 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000962 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000963 {'f', 4, 0, lu_float, lp_float},
964 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000965 {0}
966};
967
968
969static const formatdef *
970whichtable(pfmt)
971 const char **pfmt;
972{
973 const char *fmt = (*pfmt)++; /* May be backed out of later */
974 switch (*fmt) {
975 case '<':
976 return lilendian_table;
977 case '>':
978 case '!': /* Network byte order is big-endian */
979 return bigendian_table;
980 case '=': { /* Host byte order -- different from native in aligment! */
981 int n = 1;
982 char *p = (char *) &n;
983 if (*p == 1)
984 return lilendian_table;
985 else
986 return bigendian_table;
987 }
988 default:
989 --*pfmt; /* Back out of pointer increment */
990 /* Fall through */
991 case '@':
992 return native_table;
993 }
994}
995
996
997/* Get the table entry for a format code */
998
999static const formatdef *
1000getentry(c, f)
1001 int c;
1002 const formatdef *f;
1003{
1004 for (; f->format != '\0'; f++) {
1005 if (f->format == c) {
1006 return f;
1007 }
1008 }
1009 PyErr_SetString(StructError, "bad char in struct format");
1010 return NULL;
1011}
1012
1013
Guido van Rossum02975121992-08-17 08:55:12 +00001014/* Align a size according to a format code */
1015
1016static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001017align(size, c, e)
Guido van Rossum02975121992-08-17 08:55:12 +00001018 int size;
1019 int c;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001020 const formatdef *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001021{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001022 if (e->format == c) {
1023 if (e->alignment) {
1024 size = ((size + e->alignment - 1)
1025 / e->alignment)
1026 * e->alignment;
1027 }
Guido van Rossum02975121992-08-17 08:55:12 +00001028 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001029 return size;
Guido van Rossum02975121992-08-17 08:55:12 +00001030}
1031
1032
1033/* calculate the size of a format string */
1034
1035static int
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001036calcsize(fmt, f)
1037 const char *fmt;
1038 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001039{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001040 const formatdef *e;
1041 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +00001042 char c;
1043 int size, num, itemsize, x;
1044
1045 s = fmt;
1046 size = 0;
1047 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001048 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001049 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001050 if ('0' <= c && c <= '9') {
1051 num = c - '0';
1052 while ('0' <= (c = *s++) && c <= '9') {
1053 x = num*10 + (c - '0');
1054 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001055 PyErr_SetString(
1056 StructError,
1057 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +00001058 return -1;
1059 }
1060 num = x;
1061 }
1062 if (c == '\0')
1063 break;
1064 }
1065 else
1066 num = 1;
1067
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001068 e = getentry(c, f);
1069 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +00001070 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001071 itemsize = e->size;
1072 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +00001073 x = num * itemsize;
1074 size += x;
1075 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001076 PyErr_SetString(StructError,
1077 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +00001078 return -1;
1079 }
Guido van Rossum02975121992-08-17 08:55:12 +00001080 }
1081
1082 return size;
1083}
1084
1085
Guido van Rossum414fd481997-12-19 04:24:24 +00001086static char calcsize__doc__[] = "\
1087calcsize(fmt) -> int\n\
1088Return size of C struct described by format string fmt.\n\
1089See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001090
Barry Warsaw30695fa1996-12-12 23:32:31 +00001091static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001092struct_calcsize(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001093 PyObject *self; /* Not used */
1094 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001095{
1096 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001097 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +00001098 int size;
1099
Guido van Rossum43713e52000-02-29 13:59:29 +00001100 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001101 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001102 f = whichtable(&fmt);
1103 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001104 if (size < 0)
1105 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001106 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001107}
1108
1109
Guido van Rossum414fd481997-12-19 04:24:24 +00001110static char pack__doc__[] = "\
1111pack(fmt, v1, v2, ...) -> string\n\
1112Return string containing values v1, v2, ... packed according to fmt.\n\
1113See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001114
Barry Warsaw30695fa1996-12-12 23:32:31 +00001115static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001116struct_pack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001117 PyObject *self; /* Not used */
1118 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001119{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001120 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001121 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001122 char *fmt;
1123 int size, num;
1124 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001125 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001126 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001127
Barry Warsaw30695fa1996-12-12 23:32:31 +00001128 if (args == NULL || !PyTuple_Check(args) ||
1129 (n = PyTuple_Size(args)) < 1)
1130 {
Fred Drake137507e2000-06-01 02:02:46 +00001131 PyErr_SetString(PyExc_TypeError,
1132 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001133 return NULL;
1134 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001135 format = PyTuple_GetItem(args, 0);
1136 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001137 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001138 f = whichtable(&fmt);
1139 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001140 if (size < 0)
1141 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001142 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001143 if (result == NULL)
1144 return NULL;
1145
1146 s = fmt;
1147 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001148 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001149
1150 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001151 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001152 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001153 if ('0' <= c && c <= '9') {
1154 num = c - '0';
1155 while ('0' <= (c = *s++) && c <= '9')
1156 num = num*10 + (c - '0');
1157 if (c == '\0')
1158 break;
1159 }
1160 else
1161 num = 1;
1162
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001163 e = getentry(c, f);
1164 if (e == NULL)
1165 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001166 nres = restart + align((int)(res-restart), c, e);
1167 /* Fill padd bytes with zeros */
1168 while (res < nres)
1169 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001170 if (num == 0 && c != 's')
1171 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001172 do {
1173 if (c == 'x') {
1174 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001175 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001176 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001177 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001178 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001179 if (i >= n) {
1180 PyErr_SetString(StructError,
1181 "insufficient arguments to pack");
1182 goto fail;
1183 }
1184 v = PyTuple_GetItem(args, i++);
1185 if (v == NULL)
1186 goto fail;
1187 if (c == 's') {
1188 /* num is string size, not repeat count */
1189 int n;
1190 if (!PyString_Check(v)) {
1191 PyErr_SetString(StructError,
1192 "argument for 's' must be a string");
1193 goto fail;
1194 }
1195 n = PyString_Size(v);
1196 if (n > num)
1197 n = num;
1198 if (n > 0)
1199 memcpy(res, PyString_AsString(v), n);
1200 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001201 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001202 res += num;
1203 break;
1204 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001205 else if (c == 'p') {
1206 /* num is string size + 1,
1207 to fit in the count byte */
1208 int n;
1209 num--; /* now num is max string size */
1210 if (!PyString_Check(v)) {
1211 PyErr_SetString(StructError,
1212 "argument for 'p' must be a string");
1213 goto fail;
1214 }
1215 n = PyString_Size(v);
1216 if (n > num)
1217 n = num;
1218 if (n > 0)
1219 memcpy(res+1, PyString_AsString(v), n);
1220 if (n < num)
1221 /* no real need, just to be nice */
1222 memset(res+1+n, '\0', num-n);
1223 *res++ = n; /* store the length byte */
1224 res += num;
1225 break;
1226 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001227 else {
1228 if (e->pack(res, v, e) < 0)
1229 goto fail;
1230 res += e->size;
1231 }
1232 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001233 }
1234
1235 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001236 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001237 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001238 goto fail;
1239 }
1240
1241 return result;
1242
1243 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001244 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001245 return NULL;
1246}
1247
1248
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001249static char unpack__doc__[] = "\
1250unpack(fmt, string) -> (v1, v2, ...)\n\
1251Unpack the string, containing packed C structure data, according\n\
1252to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001253See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001254
Barry Warsaw30695fa1996-12-12 23:32:31 +00001255static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001256struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001257 PyObject *self; /* Not used */
1258 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001259{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001260 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001261 char *str, *start, *fmt, *s;
1262 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001263 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001264 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001265
Guido van Rossum43713e52000-02-29 13:59:29 +00001266 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001267 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001268 f = whichtable(&fmt);
1269 size = calcsize(fmt, f);
1270 if (size < 0)
1271 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001272 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001273 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001274 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001275 return NULL;
1276 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001277 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001278 if (res == NULL)
1279 return NULL;
1280 str = start;
1281 s = fmt;
1282 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001283 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001284 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001285 if ('0' <= c && c <= '9') {
1286 num = c - '0';
1287 while ('0' <= (c = *s++) && c <= '9')
1288 num = num*10 + (c - '0');
1289 if (c == '\0')
1290 break;
1291 }
1292 else
1293 num = 1;
1294
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001295 e = getentry(c, f);
1296 if (e == NULL)
1297 goto fail;
1298 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001299 if (num == 0 && c != 's')
1300 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001301
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001302 do {
1303 if (c == 'x') {
1304 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001305 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001306 }
1307 if (c == 's') {
1308 /* num is string size, not repeat count */
1309 v = PyString_FromStringAndSize(str, num);
1310 if (v == NULL)
1311 goto fail;
1312 str += num;
1313 num = 0;
1314 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001315 else if (c == 'p') {
1316 /* num is string buffer size,
1317 not repeat count */
1318 int n = *(unsigned char*)str;
1319 /* first byte (unsigned) is string size */
1320 if (n >= num)
1321 n = num-1;
1322 v = PyString_FromStringAndSize(str+1, n);
1323 if (v == NULL)
1324 goto fail;
1325 str += num;
1326 num = 0;
1327 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001328 else {
1329 v = e->unpack(str, e);
1330 if (v == NULL)
1331 goto fail;
1332 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001333 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001334 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001335 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001336 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001337 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001338 }
1339
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001340 v = PyList_AsTuple(res);
1341 Py_DECREF(res);
1342 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001343
1344 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001345 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001346 return NULL;
1347}
1348
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001349
Guido van Rossum02975121992-08-17 08:55:12 +00001350/* List of functions */
1351
Barry Warsaw30695fa1996-12-12 23:32:31 +00001352static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001353 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1354 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1355 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001356 {NULL, NULL} /* sentinel */
1357};
1358
1359
1360/* Module initialization */
1361
Guido van Rossum3886bb61998-12-04 18:50:17 +00001362DL_EXPORT(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001363initstruct()
1364{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001365 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001366
1367 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001368 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1369 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001370
1371 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001372 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001373 StructError = PyErr_NewException("struct.error", NULL, NULL);
1374 if (StructError == NULL)
1375 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001376 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001377}