blob: ff10b18ae909a0a8e950ec1fbeb214f2fcd9fae4 [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 Rossum02975121992-08-17 08:55:12 +000042
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000043#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000044#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000045
46
47/* Exception */
48
Barry Warsaw30695fa1996-12-12 23:32:31 +000049static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000050
51
52/* Define various structs to figure out the alignments of types */
53
Jack Jansen971e1df1995-02-02 14:29:10 +000054#ifdef __MWERKS__
55/*
56** XXXX We have a problem here. There are no unique alignment rules
57** on the PowerPC mac.
58*/
59#ifdef __powerc
60#pragma options align=mac68k
61#endif
62#endif /* __MWERKS__ */
63
Guido van Rossum02975121992-08-17 08:55:12 +000064typedef struct { char c; short x; } s_short;
65typedef struct { char c; int x; } s_int;
66typedef struct { char c; long x; } s_long;
67typedef struct { char c; float x; } s_float;
68typedef struct { char c; double x; } s_double;
Guido van Rossum78694d91998-09-18 14:14:13 +000069typedef struct { char c; void *x; } s_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000070
71#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
72#define INT_ALIGN (sizeof(s_int) - sizeof(int))
73#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
74#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
75#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
Guido van Rossum78694d91998-09-18 14:14:13 +000076#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
Guido van Rossum02975121992-08-17 08:55:12 +000077
Jack Jansen971e1df1995-02-02 14:29:10 +000078#ifdef __powerc
79#pragma options align=reset
80#endif
81
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000082/* Helper routine to get a Python integer and raise the appropriate error
83 if it isn't one */
84
85static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000086get_long(PyObject *v, long *p)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000087{
88 long x = PyInt_AsLong(v);
89 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +000090 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000091 PyErr_SetString(StructError,
92 "required argument is not an integer");
93 return -1;
94 }
95 *p = x;
96 return 0;
97}
98
99
Guido van Rossum60c50611996-12-31 16:29:52 +0000100/* Same, but handling unsigned long */
101
102static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000103get_ulong(PyObject *v, unsigned long *p)
Guido van Rossum60c50611996-12-31 16:29:52 +0000104{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000105 if (PyLong_Check(v)) {
106 unsigned long x = PyLong_AsUnsignedLong(v);
107 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000108 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000109 *p = x;
110 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000111 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000112 else {
113 return get_long(v, (long *)p);
114 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000115}
116
117
Guido van Rossum74679b41997-01-02 22:21:36 +0000118/* Floating point helpers */
119
120/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
121 Point Arithmetic). See the following URL:
122 http://www.psc.edu/general/software/packages/ieee/ieee.html */
123
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000124/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000125
126static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000127pack_float(double x, /* The number to pack */
128 char *p, /* Where to pack the high order byte */
129 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000130{
131 int s;
132 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000133 double f;
134 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000135
136 if (x < 0) {
137 s = 1;
138 x = -x;
139 }
140 else
141 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000142
143 f = frexp(x, &e);
144
145 /* Normalize f to be in the range [1.0, 2.0) */
146 if (0.5 <= f && f < 1.0) {
147 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000148 e--;
149 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000150 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000151 e = 0;
152 }
153 else {
154 PyErr_SetString(PyExc_SystemError,
155 "frexp() result out of range");
156 return -1;
157 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000158
159 if (e >= 128) {
160 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000161 PyErr_SetString(PyExc_OverflowError,
162 "float too large to pack with f format");
163 return -1;
164 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000165 else if (e < -126) {
166 /* Gradual underflow */
167 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000168 e = 0;
169 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000170 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000171 e += 127;
172 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000173 }
174
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000175 f *= 8388608.0; /* 2**23 */
176 fbits = (long) floor(f + 0.5); /* Round */
177
Guido van Rossum74679b41997-01-02 22:21:36 +0000178 /* First byte */
179 *p = (s<<7) | (e>>1);
180 p += incr;
181
182 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000183 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000184 p += incr;
185
186 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000187 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000188 p += incr;
189
190 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000191 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000192
193 /* Done */
194 return 0;
195}
196
197static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000198pack_double(double x, /* The number to pack */
199 char *p, /* Where to pack the high order byte */
200 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000201{
202 int s;
203 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000204 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000205 long fhi, flo;
206
207 if (x < 0) {
208 s = 1;
209 x = -x;
210 }
211 else
212 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000213
214 f = frexp(x, &e);
215
216 /* Normalize f to be in the range [1.0, 2.0) */
217 if (0.5 <= f && f < 1.0) {
218 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000219 e--;
220 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000221 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000222 e = 0;
223 }
224 else {
225 PyErr_SetString(PyExc_SystemError,
226 "frexp() result out of range");
227 return -1;
228 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000229
230 if (e >= 1024) {
231 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000232 PyErr_SetString(PyExc_OverflowError,
233 "float too large to pack with d format");
234 return -1;
235 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000236 else if (e < -1022) {
237 /* Gradual underflow */
238 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000239 e = 0;
240 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000241 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000242 e += 1023;
243 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000244 }
245
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000246 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
247 f *= 268435456.0; /* 2**28 */
248 fhi = (long) floor(f); /* Truncate */
249 f -= (double)fhi;
250 f *= 16777216.0; /* 2**24 */
251 flo = (long) floor(f + 0.5); /* Round */
252
Guido van Rossum74679b41997-01-02 22:21:36 +0000253 /* First byte */
254 *p = (s<<7) | (e>>4);
255 p += incr;
256
257 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000258 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000259 p += incr;
260
261 /* Third byte */
262 *p = (fhi>>16) & 0xFF;
263 p += incr;
264
265 /* Fourth byte */
266 *p = (fhi>>8) & 0xFF;
267 p += incr;
268
269 /* Fifth byte */
270 *p = fhi & 0xFF;
271 p += incr;
272
273 /* Sixth byte */
274 *p = (flo>>16) & 0xFF;
275 p += incr;
276
277 /* Seventh byte */
278 *p = (flo>>8) & 0xFF;
279 p += incr;
280
281 /* Eighth byte */
282 *p = flo & 0xFF;
283 p += incr;
284
285 /* Done */
286 return 0;
287}
288
289static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000290unpack_float(const char *p, /* Where the high order byte is */
291 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000292{
293 int s;
294 int e;
295 long f;
296 double x;
297
298 /* First byte */
299 s = (*p>>7) & 1;
300 e = (*p & 0x7F) << 1;
301 p += incr;
302
303 /* Second byte */
304 e |= (*p>>7) & 1;
305 f = (*p & 0x7F) << 16;
306 p += incr;
307
308 /* Third byte */
309 f |= (*p & 0xFF) << 8;
310 p += incr;
311
312 /* Fourth byte */
313 f |= *p & 0xFF;
314
315 x = (double)f / 8388608.0;
316
317 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000318 if (e == 0)
319 e = -126;
320 else {
321 x += 1.0;
322 e -= 127;
323 }
324 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000325
326 if (s)
327 x = -x;
328
329 return PyFloat_FromDouble(x);
330}
331
332static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000333unpack_double(const char *p, /* Where the high order byte is */
334 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000335{
336 int s;
337 int e;
338 long fhi, flo;
339 double x;
340
341 /* First byte */
342 s = (*p>>7) & 1;
343 e = (*p & 0x7F) << 4;
344 p += incr;
345
346 /* Second byte */
347 e |= (*p>>4) & 0xF;
348 fhi = (*p & 0xF) << 24;
349 p += incr;
350
351 /* Third byte */
352 fhi |= (*p & 0xFF) << 16;
353 p += incr;
354
355 /* Fourth byte */
356 fhi |= (*p & 0xFF) << 8;
357 p += incr;
358
359 /* Fifth byte */
360 fhi |= *p & 0xFF;
361 p += incr;
362
363 /* Sixth byte */
364 flo = (*p & 0xFF) << 16;
365 p += incr;
366
367 /* Seventh byte */
368 flo |= (*p & 0xFF) << 8;
369 p += incr;
370
371 /* Eighth byte */
372 flo |= *p & 0xFF;
373 p += incr;
374
375 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
376 x /= 268435456.0; /* 2**28 */
377
378 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000379 if (e == 0)
380 e = -1022;
381 else {
382 x += 1.0;
383 e -= 1023;
384 }
385 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000386
387 if (s)
388 x = -x;
389
390 return PyFloat_FromDouble(x);
391}
392
393
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000394/* The translation function for each format character is table driven */
395
396typedef struct _formatdef {
397 char format;
398 int size;
399 int alignment;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000400 PyObject* (*unpack)(const char *,
401 const struct _formatdef *);
402 int (*pack)(char *, PyObject *,
403 const struct _formatdef *);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000404} formatdef;
405
406static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000407nu_char(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000408{
409 return PyString_FromStringAndSize(p, 1);
410}
411
412static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000413nu_byte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000414{
415 return PyInt_FromLong((long) *(signed char *)p);
416}
417
418static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000419nu_ubyte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000420{
421 return PyInt_FromLong((long) *(unsigned char *)p);
422}
423
424static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000425nu_short(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000426{
427 return PyInt_FromLong((long) *(short *)p);
428}
429
430static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000431nu_ushort(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000432{
433 return PyInt_FromLong((long) *(unsigned short *)p);
434}
435
436static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000437nu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000438{
439 return PyInt_FromLong((long) *(int *)p);
440}
441
442static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000443nu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000444{
445 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000446 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000447}
448
449static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000450nu_long(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000451{
452 return PyInt_FromLong(*(long *)p);
453}
454
455static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000456nu_ulong(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000457{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000458 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000459}
460
461static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000462nu_float(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000463{
464 float x;
465 memcpy((char *)&x, p, sizeof(float));
466 return PyFloat_FromDouble((double)x);
467}
468
469static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000470nu_double(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000471{
472 double x;
473 memcpy((char *)&x, p, sizeof(double));
474 return PyFloat_FromDouble(x);
475}
476
Guido van Rossum78694d91998-09-18 14:14:13 +0000477static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000478nu_void_p(const char *p, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000479{
480 return PyLong_FromVoidPtr(*(void **)p);
481}
482
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000483static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000484np_byte(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000485{
486 long x;
487 if (get_long(v, &x) < 0)
488 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000489 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000490 return 0;
491}
492
493static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000494np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000495{
496 if (!PyString_Check(v) || PyString_Size(v) != 1) {
497 PyErr_SetString(StructError,
498 "char format require string of length 1");
499 return -1;
500 }
501 *p = *PyString_AsString(v);
502 return 0;
503}
504
505static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000506np_short(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000507{
508 long x;
509 if (get_long(v, &x) < 0)
510 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000511 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000512 return 0;
513}
514
515static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000516np_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000517{
518 long x;
519 if (get_long(v, &x) < 0)
520 return -1;
521 * (int *)p = x;
522 return 0;
523}
524
525static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000526np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000527{
528 unsigned long x;
529 if (get_ulong(v, &x) < 0)
530 return -1;
531 * (unsigned int *)p = x;
532 return 0;
533}
534
535static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000536np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000537{
538 long x;
539 if (get_long(v, &x) < 0)
540 return -1;
541 * (long *)p = x;
542 return 0;
543}
544
545static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000546np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000547{
548 unsigned long x;
549 if (get_ulong(v, &x) < 0)
550 return -1;
551 * (unsigned long *)p = x;
552 return 0;
553}
554
555static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000556np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000557{
558 float x = (float)PyFloat_AsDouble(v);
559 if (x == -1 && PyErr_Occurred()) {
560 PyErr_SetString(StructError,
561 "required argument is not a float");
562 return -1;
563 }
564 memcpy(p, (char *)&x, sizeof(float));
565 return 0;
566}
567
568static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000569np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000570{
571 double x = PyFloat_AsDouble(v);
572 if (x == -1 && PyErr_Occurred()) {
573 PyErr_SetString(StructError,
574 "required argument is not a float");
575 return -1;
576 }
577 memcpy(p, (char *)&x, sizeof(double));
578 return 0;
579}
580
Guido van Rossum78694d91998-09-18 14:14:13 +0000581static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000582np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000583{
584 void *x = PyLong_AsVoidPtr(v);
585 if (x == NULL && PyErr_Occurred()) {
586 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
587 if (PyErr_ExceptionMatches(PyExc_TypeError))
588 PyErr_SetString(StructError,
589 "required argument is not an integer");
590 return -1;
591 }
592 *(void **)p = x;
593 return 0;
594}
595
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000596static formatdef native_table[] = {
597 {'x', sizeof(char), 0, NULL},
598 {'b', sizeof(char), 0, nu_byte, np_byte},
599 {'B', sizeof(char), 0, nu_ubyte, np_byte},
600 {'c', sizeof(char), 0, nu_char, np_char},
601 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000602 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000603 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
604 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
605 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000606 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000607 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000608 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000609 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
610 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000611 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000612 {0}
613};
614
615static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000616bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000617{
618 long x = 0;
619 int i = f->size;
620 do {
621 x = (x<<8) | (*p++ & 0xFF);
622 } while (--i > 0);
623 i = 8*(sizeof(long) - f->size);
624 if (i) {
625 x <<= i;
626 x >>= i;
627 }
628 return PyInt_FromLong(x);
629}
630
631static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000632bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000633{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000634 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000635 int i = f->size;
636 do {
637 x = (x<<8) | (*p++ & 0xFF);
638 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000639 if (f->size >= 4)
640 return PyLong_FromUnsignedLong(x);
641 else
642 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000643}
644
Guido van Rossum74679b41997-01-02 22:21:36 +0000645static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000646bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000647{
648 return unpack_float(p, 1);
649}
650
651static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000652bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000653{
654 return unpack_double(p, 1);
655}
656
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000657static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000658bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000659{
660 long x;
661 int i;
662 if (get_long(v, &x) < 0)
663 return -1;
664 i = f->size;
665 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000666 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000667 x >>= 8;
668 } while (i > 0);
669 return 0;
670}
671
Guido van Rossum60c50611996-12-31 16:29:52 +0000672static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000673bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000674{
675 unsigned long x;
676 int i;
677 if (get_ulong(v, &x) < 0)
678 return -1;
679 i = f->size;
680 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000681 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000682 x >>= 8;
683 } while (i > 0);
684 return 0;
685}
686
Guido van Rossum74679b41997-01-02 22:21:36 +0000687static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000688bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000689{
690 double x = PyFloat_AsDouble(v);
691 if (x == -1 && PyErr_Occurred()) {
692 PyErr_SetString(StructError,
693 "required argument is not a float");
694 return -1;
695 }
696 return pack_float(x, p, 1);
697}
698
699static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000700bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000701{
702 double x = PyFloat_AsDouble(v);
703 if (x == -1 && PyErr_Occurred()) {
704 PyErr_SetString(StructError,
705 "required argument is not a float");
706 return -1;
707 }
708 return pack_double(x, p, 1);
709}
710
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000711static formatdef bigendian_table[] = {
712 {'x', 1, 0, NULL},
713 {'b', 1, 0, bu_int, bp_int},
714 {'B', 1, 0, bu_uint, bp_int},
715 {'c', 1, 0, nu_char, np_char},
716 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000717 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000718 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000719 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000720 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000721 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000722 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000723 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000724 {'f', 4, 0, bu_float, bp_float},
725 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000726 {0}
727};
728
729static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000730lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000731{
732 long x = 0;
733 int i = f->size;
734 do {
735 x = (x<<8) | (p[--i] & 0xFF);
736 } while (i > 0);
737 i = 8*(sizeof(long) - f->size);
738 if (i) {
739 x <<= i;
740 x >>= i;
741 }
742 return PyInt_FromLong(x);
743}
744
745static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000746lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000747{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000748 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000749 int i = f->size;
750 do {
751 x = (x<<8) | (p[--i] & 0xFF);
752 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000753 if (f->size >= 4)
754 return PyLong_FromUnsignedLong(x);
755 else
756 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000757}
758
Guido van Rossum74679b41997-01-02 22:21:36 +0000759static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000760lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000761{
762 return unpack_float(p+3, -1);
763}
764
765static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000766lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000767{
768 return unpack_double(p+7, -1);
769}
770
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000771static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000772lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000773{
774 long x;
775 int i;
776 if (get_long(v, &x) < 0)
777 return -1;
778 i = f->size;
779 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000780 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000781 x >>= 8;
782 } while (--i > 0);
783 return 0;
784}
785
Guido van Rossum60c50611996-12-31 16:29:52 +0000786static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000787lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000788{
789 unsigned long x;
790 int i;
791 if (get_ulong(v, &x) < 0)
792 return -1;
793 i = f->size;
794 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000795 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000796 x >>= 8;
797 } while (--i > 0);
798 return 0;
799}
800
Guido van Rossum74679b41997-01-02 22:21:36 +0000801static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000802lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000803{
804 double x = PyFloat_AsDouble(v);
805 if (x == -1 && PyErr_Occurred()) {
806 PyErr_SetString(StructError,
807 "required argument is not a float");
808 return -1;
809 }
810 return pack_float(x, p+3, -1);
811}
812
813static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000814lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000815{
816 double x = PyFloat_AsDouble(v);
817 if (x == -1 && PyErr_Occurred()) {
818 PyErr_SetString(StructError,
819 "required argument is not a float");
820 return -1;
821 }
822 return pack_double(x, p+7, -1);
823}
824
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000825static formatdef lilendian_table[] = {
826 {'x', 1, 0, NULL},
827 {'b', 1, 0, lu_int, lp_int},
828 {'B', 1, 0, lu_uint, lp_int},
829 {'c', 1, 0, nu_char, np_char},
830 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000831 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000832 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000833 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000834 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000835 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000836 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000837 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000838 {'f', 4, 0, lu_float, lp_float},
839 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000840 {0}
841};
842
843
844static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000845whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000846{
847 const char *fmt = (*pfmt)++; /* May be backed out of later */
848 switch (*fmt) {
849 case '<':
850 return lilendian_table;
851 case '>':
852 case '!': /* Network byte order is big-endian */
853 return bigendian_table;
854 case '=': { /* Host byte order -- different from native in aligment! */
855 int n = 1;
856 char *p = (char *) &n;
857 if (*p == 1)
858 return lilendian_table;
859 else
860 return bigendian_table;
861 }
862 default:
863 --*pfmt; /* Back out of pointer increment */
864 /* Fall through */
865 case '@':
866 return native_table;
867 }
868}
869
870
871/* Get the table entry for a format code */
872
873static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000874getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000875{
876 for (; f->format != '\0'; f++) {
877 if (f->format == c) {
878 return f;
879 }
880 }
881 PyErr_SetString(StructError, "bad char in struct format");
882 return NULL;
883}
884
885
Guido van Rossum02975121992-08-17 08:55:12 +0000886/* Align a size according to a format code */
887
888static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000889align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +0000890{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000891 if (e->format == c) {
892 if (e->alignment) {
893 size = ((size + e->alignment - 1)
894 / e->alignment)
895 * e->alignment;
896 }
Guido van Rossum02975121992-08-17 08:55:12 +0000897 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000898 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000899}
900
901
902/* calculate the size of a format string */
903
904static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000905calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +0000906{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000907 const formatdef *e;
908 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000909 char c;
910 int size, num, itemsize, x;
911
912 s = fmt;
913 size = 0;
914 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +0000915 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +0000916 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000917 if ('0' <= c && c <= '9') {
918 num = c - '0';
919 while ('0' <= (c = *s++) && c <= '9') {
920 x = num*10 + (c - '0');
921 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000922 PyErr_SetString(
923 StructError,
924 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000925 return -1;
926 }
927 num = x;
928 }
929 if (c == '\0')
930 break;
931 }
932 else
933 num = 1;
934
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000935 e = getentry(c, f);
936 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000937 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000938 itemsize = e->size;
939 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000940 x = num * itemsize;
941 size += x;
942 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000943 PyErr_SetString(StructError,
944 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000945 return -1;
946 }
Guido van Rossum02975121992-08-17 08:55:12 +0000947 }
948
949 return size;
950}
951
952
Guido van Rossum414fd481997-12-19 04:24:24 +0000953static char calcsize__doc__[] = "\
954calcsize(fmt) -> int\n\
955Return size of C struct described by format string fmt.\n\
956See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +0000957
Barry Warsaw30695fa1996-12-12 23:32:31 +0000958static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000959struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +0000960{
961 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000962 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000963 int size;
964
Guido van Rossum43713e52000-02-29 13:59:29 +0000965 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +0000966 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000967 f = whichtable(&fmt);
968 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +0000969 if (size < 0)
970 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000971 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +0000972}
973
974
Guido van Rossum414fd481997-12-19 04:24:24 +0000975static char pack__doc__[] = "\
976pack(fmt, v1, v2, ...) -> string\n\
977Return string containing values v1, v2, ... packed according to fmt.\n\
978See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +0000979
Barry Warsaw30695fa1996-12-12 23:32:31 +0000980static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000981struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +0000982{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000983 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000984 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +0000985 char *fmt;
986 int size, num;
987 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +0000988 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +0000989 char c;
Guido van Rossum02975121992-08-17 08:55:12 +0000990
Barry Warsaw30695fa1996-12-12 23:32:31 +0000991 if (args == NULL || !PyTuple_Check(args) ||
992 (n = PyTuple_Size(args)) < 1)
993 {
Fred Drake137507e2000-06-01 02:02:46 +0000994 PyErr_SetString(PyExc_TypeError,
995 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +0000996 return NULL;
997 }
Barry Warsaw30695fa1996-12-12 23:32:31 +0000998 format = PyTuple_GetItem(args, 0);
999 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001000 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001001 f = whichtable(&fmt);
1002 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001003 if (size < 0)
1004 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001005 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001006 if (result == NULL)
1007 return NULL;
1008
1009 s = fmt;
1010 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001011 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001012
1013 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001014 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001015 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001016 if ('0' <= c && c <= '9') {
1017 num = c - '0';
1018 while ('0' <= (c = *s++) && c <= '9')
1019 num = num*10 + (c - '0');
1020 if (c == '\0')
1021 break;
1022 }
1023 else
1024 num = 1;
1025
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001026 e = getentry(c, f);
1027 if (e == NULL)
1028 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001029 nres = restart + align((int)(res-restart), c, e);
1030 /* Fill padd bytes with zeros */
1031 while (res < nres)
1032 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001033 if (num == 0 && c != 's')
1034 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001035 do {
1036 if (c == 'x') {
1037 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001038 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001039 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001040 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001041 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001042 if (i >= n) {
1043 PyErr_SetString(StructError,
1044 "insufficient arguments to pack");
1045 goto fail;
1046 }
1047 v = PyTuple_GetItem(args, i++);
1048 if (v == NULL)
1049 goto fail;
1050 if (c == 's') {
1051 /* num is string size, not repeat count */
1052 int n;
1053 if (!PyString_Check(v)) {
1054 PyErr_SetString(StructError,
1055 "argument for 's' must be a string");
1056 goto fail;
1057 }
1058 n = PyString_Size(v);
1059 if (n > num)
1060 n = num;
1061 if (n > 0)
1062 memcpy(res, PyString_AsString(v), n);
1063 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001064 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001065 res += num;
1066 break;
1067 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001068 else if (c == 'p') {
1069 /* num is string size + 1,
1070 to fit in the count byte */
1071 int n;
1072 num--; /* now num is max string size */
1073 if (!PyString_Check(v)) {
1074 PyErr_SetString(StructError,
1075 "argument for 'p' must be a string");
1076 goto fail;
1077 }
1078 n = PyString_Size(v);
1079 if (n > num)
1080 n = num;
1081 if (n > 0)
1082 memcpy(res+1, PyString_AsString(v), n);
1083 if (n < num)
1084 /* no real need, just to be nice */
1085 memset(res+1+n, '\0', num-n);
1086 *res++ = n; /* store the length byte */
1087 res += num;
1088 break;
1089 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001090 else {
1091 if (e->pack(res, v, e) < 0)
1092 goto fail;
1093 res += e->size;
1094 }
1095 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001096 }
1097
1098 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001099 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001100 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001101 goto fail;
1102 }
1103
1104 return result;
1105
1106 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001107 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001108 return NULL;
1109}
1110
1111
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001112static char unpack__doc__[] = "\
1113unpack(fmt, string) -> (v1, v2, ...)\n\
1114Unpack the string, containing packed C structure data, according\n\
1115to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001116See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001117
Barry Warsaw30695fa1996-12-12 23:32:31 +00001118static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001119struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001120{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001121 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001122 char *str, *start, *fmt, *s;
1123 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001124 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001125 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001126
Guido van Rossum43713e52000-02-29 13:59:29 +00001127 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001128 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001129 f = whichtable(&fmt);
1130 size = calcsize(fmt, f);
1131 if (size < 0)
1132 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001133 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001134 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001135 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001136 return NULL;
1137 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001138 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001139 if (res == NULL)
1140 return NULL;
1141 str = start;
1142 s = fmt;
1143 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001144 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001145 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001146 if ('0' <= c && c <= '9') {
1147 num = c - '0';
1148 while ('0' <= (c = *s++) && c <= '9')
1149 num = num*10 + (c - '0');
1150 if (c == '\0')
1151 break;
1152 }
1153 else
1154 num = 1;
1155
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001156 e = getentry(c, f);
1157 if (e == NULL)
1158 goto fail;
1159 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001160 if (num == 0 && c != 's')
1161 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001162
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001163 do {
1164 if (c == 'x') {
1165 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001166 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001167 }
1168 if (c == 's') {
1169 /* num is string size, not repeat count */
1170 v = PyString_FromStringAndSize(str, num);
1171 if (v == NULL)
1172 goto fail;
1173 str += num;
1174 num = 0;
1175 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001176 else if (c == 'p') {
1177 /* num is string buffer size,
1178 not repeat count */
1179 int n = *(unsigned char*)str;
1180 /* first byte (unsigned) is string size */
1181 if (n >= num)
1182 n = num-1;
1183 v = PyString_FromStringAndSize(str+1, n);
1184 if (v == NULL)
1185 goto fail;
1186 str += num;
1187 num = 0;
1188 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001189 else {
1190 v = e->unpack(str, e);
1191 if (v == NULL)
1192 goto fail;
1193 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001194 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001195 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001196 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001197 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001198 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001199 }
1200
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001201 v = PyList_AsTuple(res);
1202 Py_DECREF(res);
1203 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001204
1205 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001206 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001207 return NULL;
1208}
1209
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001210
Guido van Rossum02975121992-08-17 08:55:12 +00001211/* List of functions */
1212
Barry Warsaw30695fa1996-12-12 23:32:31 +00001213static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001214 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1215 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1216 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001217 {NULL, NULL} /* sentinel */
1218};
1219
1220
1221/* Module initialization */
1222
Guido van Rossum3886bb61998-12-04 18:50:17 +00001223DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001224initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001225{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001226 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001227
1228 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001229 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1230 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001231
1232 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001233 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001234 StructError = PyErr_NewException("struct.error", NULL, NULL);
1235 if (StructError == NULL)
1236 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001237 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001238}