blob: 9994d20313605a2e6dd59d0fcfbb16338ad002e6 [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 Rossumf7e6b4b1996-12-31 01:41:25 +00001100 if (!PyArg_ParseTuple(args, "s", &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 {
1131 PyErr_BadArgument();
Guido van Rossum02975121992-08-17 08:55:12 +00001132 return NULL;
1133 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001134 format = PyTuple_GetItem(args, 0);
1135 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001136 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001137 f = whichtable(&fmt);
1138 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001139 if (size < 0)
1140 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001141 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001142 if (result == NULL)
1143 return NULL;
1144
1145 s = fmt;
1146 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001147 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001148
1149 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001150 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001151 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001152 if ('0' <= c && c <= '9') {
1153 num = c - '0';
1154 while ('0' <= (c = *s++) && c <= '9')
1155 num = num*10 + (c - '0');
1156 if (c == '\0')
1157 break;
1158 }
1159 else
1160 num = 1;
1161
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001162 e = getentry(c, f);
1163 if (e == NULL)
1164 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001165 nres = restart + align((int)(res-restart), c, e);
1166 /* Fill padd bytes with zeros */
1167 while (res < nres)
1168 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001169 if (num == 0 && c != 's')
1170 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001171 do {
1172 if (c == 'x') {
1173 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001174 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001175 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001176 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001177 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001178 if (i >= n) {
1179 PyErr_SetString(StructError,
1180 "insufficient arguments to pack");
1181 goto fail;
1182 }
1183 v = PyTuple_GetItem(args, i++);
1184 if (v == NULL)
1185 goto fail;
1186 if (c == 's') {
1187 /* num is string size, not repeat count */
1188 int n;
1189 if (!PyString_Check(v)) {
1190 PyErr_SetString(StructError,
1191 "argument for 's' must be a string");
1192 goto fail;
1193 }
1194 n = PyString_Size(v);
1195 if (n > num)
1196 n = num;
1197 if (n > 0)
1198 memcpy(res, PyString_AsString(v), n);
1199 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001200 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001201 res += num;
1202 break;
1203 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001204 else if (c == 'p') {
1205 /* num is string size + 1,
1206 to fit in the count byte */
1207 int n;
1208 num--; /* now num is max string size */
1209 if (!PyString_Check(v)) {
1210 PyErr_SetString(StructError,
1211 "argument for 'p' must be a string");
1212 goto fail;
1213 }
1214 n = PyString_Size(v);
1215 if (n > num)
1216 n = num;
1217 if (n > 0)
1218 memcpy(res+1, PyString_AsString(v), n);
1219 if (n < num)
1220 /* no real need, just to be nice */
1221 memset(res+1+n, '\0', num-n);
1222 *res++ = n; /* store the length byte */
1223 res += num;
1224 break;
1225 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001226 else {
1227 if (e->pack(res, v, e) < 0)
1228 goto fail;
1229 res += e->size;
1230 }
1231 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001232 }
1233
1234 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001235 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001236 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001237 goto fail;
1238 }
1239
1240 return result;
1241
1242 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001243 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001244 return NULL;
1245}
1246
1247
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001248static char unpack__doc__[] = "\
1249unpack(fmt, string) -> (v1, v2, ...)\n\
1250Unpack the string, containing packed C structure data, according\n\
1251to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001252See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001253
Barry Warsaw30695fa1996-12-12 23:32:31 +00001254static PyObject *
Guido van Rossum02975121992-08-17 08:55:12 +00001255struct_unpack(self, args)
Barry Warsaw30695fa1996-12-12 23:32:31 +00001256 PyObject *self; /* Not used */
1257 PyObject *args;
Guido van Rossum02975121992-08-17 08:55:12 +00001258{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001259 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001260 char *str, *start, *fmt, *s;
1261 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001262 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001263 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001264
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001265 if (!PyArg_ParseTuple(args, "ss#", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001266 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001267 f = whichtable(&fmt);
1268 size = calcsize(fmt, f);
1269 if (size < 0)
1270 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001271 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001272 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001273 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001274 return NULL;
1275 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001276 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001277 if (res == NULL)
1278 return NULL;
1279 str = start;
1280 s = fmt;
1281 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001282 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001283 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001284 if ('0' <= c && c <= '9') {
1285 num = c - '0';
1286 while ('0' <= (c = *s++) && c <= '9')
1287 num = num*10 + (c - '0');
1288 if (c == '\0')
1289 break;
1290 }
1291 else
1292 num = 1;
1293
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001294 e = getentry(c, f);
1295 if (e == NULL)
1296 goto fail;
1297 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001298 if (num == 0 && c != 's')
1299 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001300
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001301 do {
1302 if (c == 'x') {
1303 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001304 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001305 }
1306 if (c == 's') {
1307 /* num is string size, not repeat count */
1308 v = PyString_FromStringAndSize(str, num);
1309 if (v == NULL)
1310 goto fail;
1311 str += num;
1312 num = 0;
1313 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001314 else if (c == 'p') {
1315 /* num is string buffer size,
1316 not repeat count */
1317 int n = *(unsigned char*)str;
1318 /* first byte (unsigned) is string size */
1319 if (n >= num)
1320 n = num-1;
1321 v = PyString_FromStringAndSize(str+1, n);
1322 if (v == NULL)
1323 goto fail;
1324 str += num;
1325 num = 0;
1326 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001327 else {
1328 v = e->unpack(str, e);
1329 if (v == NULL)
1330 goto fail;
1331 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001332 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001333 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001334 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001335 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001336 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001337 }
1338
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001339 v = PyList_AsTuple(res);
1340 Py_DECREF(res);
1341 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001342
1343 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001344 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001345 return NULL;
1346}
1347
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001348
Guido van Rossum02975121992-08-17 08:55:12 +00001349/* List of functions */
1350
Barry Warsaw30695fa1996-12-12 23:32:31 +00001351static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001352 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1353 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1354 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001355 {NULL, NULL} /* sentinel */
1356};
1357
1358
1359/* Module initialization */
1360
Guido van Rossum3886bb61998-12-04 18:50:17 +00001361DL_EXPORT(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001362initstruct()
1363{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001364 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001365
1366 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001367 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1368 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001369
1370 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001371 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001372 StructError = PyErr_NewException("struct.error", NULL, NULL);
1373 if (StructError == NULL)
1374 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001375 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001376}