blob: 12759553c33af194322b9de0f6e36f10c80628be [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossum02975121992-08-17 08:55:12 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossum02975121992-08-17 08:55:12 +00009******************************************************************/
10
11/* struct module -- pack values into and (out of) strings */
12
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000013/* New version supporting byte order, alignment and size options,
14 character strings, and unsigned numbers */
15
Guido van Rossum414fd481997-12-19 04:24:24 +000016static char struct__doc__[] = "\
17Functions to convert between Python values and C structs.\n\
18Python strings are used to hold the data representing the C struct\n\
19and also as format strings to describe the layout of data in the C struct.\n\
20\n\
21The optional first format char indicates byte ordering and alignment:\n\
22 @: native w/native alignment(default)\n\
23 =: native w/standard alignment\n\
24 <: little-endian, std. alignment\n\
25 >: big-endian, std. alignment\n\
26 !: network, std (same as >)\n\
27\n\
28The remaining chars indicate types of args and must match exactly;\n\
29these can be preceded by a decimal repeat count:\n\
30 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
31 h:short; H:unsigned short; i:int; I:unsigned int;\n\
32 l:long; L:unsigned long; f:float; d:double.\n\
33Special cases (preceding decimal count indicates length):\n\
34 s:string (array of char); p: pascal string (w. count byte).\n\
Guido van Rossum78694d91998-09-18 14:14:13 +000035Special case (only available in native format):\n\
36 P:an integer type that is wide enough to hold a pointer.\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000037Whitespace between formats is ignored.\n\
38\n\
39The variable struct.error is an exception raised on errors.";
40
Barry Warsaw30695fa1996-12-12 23:32:31 +000041#include "Python.h"
Guido van Rossum74679b41997-01-02 22:21:36 +000042#include "mymath.h"
Guido van Rossum02975121992-08-17 08:55:12 +000043
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000044#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000045#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000046
47
48/* Exception */
49
Barry Warsaw30695fa1996-12-12 23:32:31 +000050static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000051
52
53/* Define various structs to figure out the alignments of types */
54
Jack Jansen971e1df1995-02-02 14:29:10 +000055#ifdef __MWERKS__
56/*
57** XXXX We have a problem here. There are no unique alignment rules
58** on the PowerPC mac.
59*/
60#ifdef __powerc
61#pragma options align=mac68k
62#endif
63#endif /* __MWERKS__ */
64
Guido van Rossum02975121992-08-17 08:55:12 +000065typedef struct { char c; short x; } s_short;
66typedef struct { char c; int x; } s_int;
67typedef struct { char c; long x; } s_long;
68typedef struct { char c; float x; } s_float;
69typedef struct { char c; double x; } s_double;
Guido van Rossum78694d91998-09-18 14:14:13 +000070typedef struct { char c; void *x; } s_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000071
72#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
73#define INT_ALIGN (sizeof(s_int) - sizeof(int))
74#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
75#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
76#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
Guido van Rossum78694d91998-09-18 14:14:13 +000077#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
Guido van Rossum02975121992-08-17 08:55:12 +000078
Jack Jansen971e1df1995-02-02 14:29:10 +000079#ifdef __powerc
80#pragma options align=reset
81#endif
82
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000083/* Helper routine to get a Python integer and raise the appropriate error
84 if it isn't one */
85
86static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000087get_long(PyObject *v, long *p)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000088{
89 long x = PyInt_AsLong(v);
90 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +000091 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000092 PyErr_SetString(StructError,
93 "required argument is not an integer");
94 return -1;
95 }
96 *p = x;
97 return 0;
98}
99
100
Guido van Rossum60c50611996-12-31 16:29:52 +0000101/* Same, but handling unsigned long */
102
103static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000104get_ulong(PyObject *v, unsigned long *p)
Guido van Rossum60c50611996-12-31 16:29:52 +0000105{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000106 if (PyLong_Check(v)) {
107 unsigned long x = PyLong_AsUnsignedLong(v);
108 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +0000109 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000110 *p = x;
111 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000112 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000113 else {
114 return get_long(v, (long *)p);
115 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000116}
117
118
Guido van Rossum74679b41997-01-02 22:21:36 +0000119/* Floating point helpers */
120
121/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
122 Point Arithmetic). See the following URL:
123 http://www.psc.edu/general/software/packages/ieee/ieee.html */
124
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000125/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000126
127static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000128pack_float(double x, /* The number to pack */
129 char *p, /* Where to pack the high order byte */
130 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000131{
132 int s;
133 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000134 double f;
135 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000136
137 if (x < 0) {
138 s = 1;
139 x = -x;
140 }
141 else
142 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000143
144 f = frexp(x, &e);
145
146 /* Normalize f to be in the range [1.0, 2.0) */
147 if (0.5 <= f && f < 1.0) {
148 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000149 e--;
150 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000151 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000152 e = 0;
153 }
154 else {
155 PyErr_SetString(PyExc_SystemError,
156 "frexp() result out of range");
157 return -1;
158 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000159
160 if (e >= 128) {
161 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000162 PyErr_SetString(PyExc_OverflowError,
163 "float too large to pack with f format");
164 return -1;
165 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000166 else if (e < -126) {
167 /* Gradual underflow */
168 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000169 e = 0;
170 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000171 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000172 e += 127;
173 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000174 }
175
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000176 f *= 8388608.0; /* 2**23 */
177 fbits = (long) floor(f + 0.5); /* Round */
178
Guido van Rossum74679b41997-01-02 22:21:36 +0000179 /* First byte */
180 *p = (s<<7) | (e>>1);
181 p += incr;
182
183 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000184 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000185 p += incr;
186
187 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000188 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000189 p += incr;
190
191 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000192 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000193
194 /* Done */
195 return 0;
196}
197
198static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000199pack_double(double x, /* The number to pack */
200 char *p, /* Where to pack the high order byte */
201 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000202{
203 int s;
204 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000205 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000206 long fhi, flo;
207
208 if (x < 0) {
209 s = 1;
210 x = -x;
211 }
212 else
213 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000214
215 f = frexp(x, &e);
216
217 /* Normalize f to be in the range [1.0, 2.0) */
218 if (0.5 <= f && f < 1.0) {
219 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000220 e--;
221 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000222 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000223 e = 0;
224 }
225 else {
226 PyErr_SetString(PyExc_SystemError,
227 "frexp() result out of range");
228 return -1;
229 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000230
231 if (e >= 1024) {
232 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000233 PyErr_SetString(PyExc_OverflowError,
234 "float too large to pack with d format");
235 return -1;
236 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000237 else if (e < -1022) {
238 /* Gradual underflow */
239 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000240 e = 0;
241 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000242 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000243 e += 1023;
244 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000245 }
246
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000247 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
248 f *= 268435456.0; /* 2**28 */
249 fhi = (long) floor(f); /* Truncate */
250 f -= (double)fhi;
251 f *= 16777216.0; /* 2**24 */
252 flo = (long) floor(f + 0.5); /* Round */
253
Guido van Rossum74679b41997-01-02 22:21:36 +0000254 /* First byte */
255 *p = (s<<7) | (e>>4);
256 p += incr;
257
258 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000259 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000260 p += incr;
261
262 /* Third byte */
263 *p = (fhi>>16) & 0xFF;
264 p += incr;
265
266 /* Fourth byte */
267 *p = (fhi>>8) & 0xFF;
268 p += incr;
269
270 /* Fifth byte */
271 *p = fhi & 0xFF;
272 p += incr;
273
274 /* Sixth byte */
275 *p = (flo>>16) & 0xFF;
276 p += incr;
277
278 /* Seventh byte */
279 *p = (flo>>8) & 0xFF;
280 p += incr;
281
282 /* Eighth byte */
283 *p = flo & 0xFF;
284 p += incr;
285
286 /* Done */
287 return 0;
288}
289
290static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000291unpack_float(const char *p, /* Where the high order byte is */
292 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000293{
294 int s;
295 int e;
296 long f;
297 double x;
298
299 /* First byte */
300 s = (*p>>7) & 1;
301 e = (*p & 0x7F) << 1;
302 p += incr;
303
304 /* Second byte */
305 e |= (*p>>7) & 1;
306 f = (*p & 0x7F) << 16;
307 p += incr;
308
309 /* Third byte */
310 f |= (*p & 0xFF) << 8;
311 p += incr;
312
313 /* Fourth byte */
314 f |= *p & 0xFF;
315
316 x = (double)f / 8388608.0;
317
318 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000319 if (e == 0)
320 e = -126;
321 else {
322 x += 1.0;
323 e -= 127;
324 }
325 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000326
327 if (s)
328 x = -x;
329
330 return PyFloat_FromDouble(x);
331}
332
333static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000334unpack_double(const char *p, /* Where the high order byte is */
335 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000336{
337 int s;
338 int e;
339 long fhi, flo;
340 double x;
341
342 /* First byte */
343 s = (*p>>7) & 1;
344 e = (*p & 0x7F) << 4;
345 p += incr;
346
347 /* Second byte */
348 e |= (*p>>4) & 0xF;
349 fhi = (*p & 0xF) << 24;
350 p += incr;
351
352 /* Third byte */
353 fhi |= (*p & 0xFF) << 16;
354 p += incr;
355
356 /* Fourth byte */
357 fhi |= (*p & 0xFF) << 8;
358 p += incr;
359
360 /* Fifth byte */
361 fhi |= *p & 0xFF;
362 p += incr;
363
364 /* Sixth byte */
365 flo = (*p & 0xFF) << 16;
366 p += incr;
367
368 /* Seventh byte */
369 flo |= (*p & 0xFF) << 8;
370 p += incr;
371
372 /* Eighth byte */
373 flo |= *p & 0xFF;
374 p += incr;
375
376 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
377 x /= 268435456.0; /* 2**28 */
378
379 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000380 if (e == 0)
381 e = -1022;
382 else {
383 x += 1.0;
384 e -= 1023;
385 }
386 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000387
388 if (s)
389 x = -x;
390
391 return PyFloat_FromDouble(x);
392}
393
394
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000395/* The translation function for each format character is table driven */
396
397typedef struct _formatdef {
398 char format;
399 int size;
400 int alignment;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000401 PyObject* (*unpack)(const char *,
402 const struct _formatdef *);
403 int (*pack)(char *, PyObject *,
404 const struct _formatdef *);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000405} formatdef;
406
407static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000408nu_char(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000409{
410 return PyString_FromStringAndSize(p, 1);
411}
412
413static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000414nu_byte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000415{
416 return PyInt_FromLong((long) *(signed char *)p);
417}
418
419static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000420nu_ubyte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000421{
422 return PyInt_FromLong((long) *(unsigned char *)p);
423}
424
425static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000426nu_short(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000427{
428 return PyInt_FromLong((long) *(short *)p);
429}
430
431static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000432nu_ushort(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000433{
434 return PyInt_FromLong((long) *(unsigned short *)p);
435}
436
437static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000438nu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000439{
440 return PyInt_FromLong((long) *(int *)p);
441}
442
443static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000444nu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000445{
446 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000447 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000448}
449
450static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000451nu_long(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000452{
453 return PyInt_FromLong(*(long *)p);
454}
455
456static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000457nu_ulong(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000458{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000459 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000460}
461
462static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000463nu_float(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000464{
465 float x;
466 memcpy((char *)&x, p, sizeof(float));
467 return PyFloat_FromDouble((double)x);
468}
469
470static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000471nu_double(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000472{
473 double x;
474 memcpy((char *)&x, p, sizeof(double));
475 return PyFloat_FromDouble(x);
476}
477
Guido van Rossum78694d91998-09-18 14:14:13 +0000478static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000479nu_void_p(const char *p, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000480{
481 return PyLong_FromVoidPtr(*(void **)p);
482}
483
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000484static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000485np_byte(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000486{
487 long x;
488 if (get_long(v, &x) < 0)
489 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000490 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000491 return 0;
492}
493
494static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000495np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000496{
497 if (!PyString_Check(v) || PyString_Size(v) != 1) {
498 PyErr_SetString(StructError,
499 "char format require string of length 1");
500 return -1;
501 }
502 *p = *PyString_AsString(v);
503 return 0;
504}
505
506static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000507np_short(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000508{
509 long x;
510 if (get_long(v, &x) < 0)
511 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000512 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000513 return 0;
514}
515
516static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000517np_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000518{
519 long x;
520 if (get_long(v, &x) < 0)
521 return -1;
522 * (int *)p = x;
523 return 0;
524}
525
526static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000527np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000528{
529 unsigned long x;
530 if (get_ulong(v, &x) < 0)
531 return -1;
532 * (unsigned int *)p = x;
533 return 0;
534}
535
536static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000537np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000538{
539 long x;
540 if (get_long(v, &x) < 0)
541 return -1;
542 * (long *)p = x;
543 return 0;
544}
545
546static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000547np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000548{
549 unsigned long x;
550 if (get_ulong(v, &x) < 0)
551 return -1;
552 * (unsigned long *)p = x;
553 return 0;
554}
555
556static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000557np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000558{
559 float x = (float)PyFloat_AsDouble(v);
560 if (x == -1 && PyErr_Occurred()) {
561 PyErr_SetString(StructError,
562 "required argument is not a float");
563 return -1;
564 }
565 memcpy(p, (char *)&x, sizeof(float));
566 return 0;
567}
568
569static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000570np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000571{
572 double x = PyFloat_AsDouble(v);
573 if (x == -1 && PyErr_Occurred()) {
574 PyErr_SetString(StructError,
575 "required argument is not a float");
576 return -1;
577 }
578 memcpy(p, (char *)&x, sizeof(double));
579 return 0;
580}
581
Guido van Rossum78694d91998-09-18 14:14:13 +0000582static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000583np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000584{
585 void *x = PyLong_AsVoidPtr(v);
586 if (x == NULL && PyErr_Occurred()) {
587 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
588 if (PyErr_ExceptionMatches(PyExc_TypeError))
589 PyErr_SetString(StructError,
590 "required argument is not an integer");
591 return -1;
592 }
593 *(void **)p = x;
594 return 0;
595}
596
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000597static formatdef native_table[] = {
598 {'x', sizeof(char), 0, NULL},
599 {'b', sizeof(char), 0, nu_byte, np_byte},
600 {'B', sizeof(char), 0, nu_ubyte, np_byte},
601 {'c', sizeof(char), 0, nu_char, np_char},
602 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000603 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000604 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
605 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
606 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000607 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000608 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000609 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000610 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
611 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000612 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000613 {0}
614};
615
616static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000617bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000618{
619 long x = 0;
620 int i = f->size;
621 do {
622 x = (x<<8) | (*p++ & 0xFF);
623 } while (--i > 0);
624 i = 8*(sizeof(long) - f->size);
625 if (i) {
626 x <<= i;
627 x >>= i;
628 }
629 return PyInt_FromLong(x);
630}
631
632static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000633bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000634{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000635 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000636 int i = f->size;
637 do {
638 x = (x<<8) | (*p++ & 0xFF);
639 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000640 if (f->size >= 4)
641 return PyLong_FromUnsignedLong(x);
642 else
643 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000644}
645
Guido van Rossum74679b41997-01-02 22:21:36 +0000646static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000647bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000648{
649 return unpack_float(p, 1);
650}
651
652static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000653bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000654{
655 return unpack_double(p, 1);
656}
657
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000658static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000659bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000660{
661 long x;
662 int i;
663 if (get_long(v, &x) < 0)
664 return -1;
665 i = f->size;
666 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000667 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000668 x >>= 8;
669 } while (i > 0);
670 return 0;
671}
672
Guido van Rossum60c50611996-12-31 16:29:52 +0000673static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000674bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000675{
676 unsigned long x;
677 int i;
678 if (get_ulong(v, &x) < 0)
679 return -1;
680 i = f->size;
681 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000682 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000683 x >>= 8;
684 } while (i > 0);
685 return 0;
686}
687
Guido van Rossum74679b41997-01-02 22:21:36 +0000688static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000689bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000690{
691 double x = PyFloat_AsDouble(v);
692 if (x == -1 && PyErr_Occurred()) {
693 PyErr_SetString(StructError,
694 "required argument is not a float");
695 return -1;
696 }
697 return pack_float(x, p, 1);
698}
699
700static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000701bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000702{
703 double x = PyFloat_AsDouble(v);
704 if (x == -1 && PyErr_Occurred()) {
705 PyErr_SetString(StructError,
706 "required argument is not a float");
707 return -1;
708 }
709 return pack_double(x, p, 1);
710}
711
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000712static formatdef bigendian_table[] = {
713 {'x', 1, 0, NULL},
714 {'b', 1, 0, bu_int, bp_int},
715 {'B', 1, 0, bu_uint, bp_int},
716 {'c', 1, 0, nu_char, np_char},
717 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000718 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000719 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000720 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000721 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000722 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000723 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000724 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000725 {'f', 4, 0, bu_float, bp_float},
726 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000727 {0}
728};
729
730static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000731lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000732{
733 long x = 0;
734 int i = f->size;
735 do {
736 x = (x<<8) | (p[--i] & 0xFF);
737 } while (i > 0);
738 i = 8*(sizeof(long) - f->size);
739 if (i) {
740 x <<= i;
741 x >>= i;
742 }
743 return PyInt_FromLong(x);
744}
745
746static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000747lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000748{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000749 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000750 int i = f->size;
751 do {
752 x = (x<<8) | (p[--i] & 0xFF);
753 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000754 if (f->size >= 4)
755 return PyLong_FromUnsignedLong(x);
756 else
757 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000758}
759
Guido van Rossum74679b41997-01-02 22:21:36 +0000760static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000761lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000762{
763 return unpack_float(p+3, -1);
764}
765
766static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000767lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000768{
769 return unpack_double(p+7, -1);
770}
771
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000772static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000773lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000774{
775 long x;
776 int i;
777 if (get_long(v, &x) < 0)
778 return -1;
779 i = f->size;
780 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000781 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000782 x >>= 8;
783 } while (--i > 0);
784 return 0;
785}
786
Guido van Rossum60c50611996-12-31 16:29:52 +0000787static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000788lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000789{
790 unsigned long x;
791 int i;
792 if (get_ulong(v, &x) < 0)
793 return -1;
794 i = f->size;
795 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000796 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000797 x >>= 8;
798 } while (--i > 0);
799 return 0;
800}
801
Guido van Rossum74679b41997-01-02 22:21:36 +0000802static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000803lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000804{
805 double x = PyFloat_AsDouble(v);
806 if (x == -1 && PyErr_Occurred()) {
807 PyErr_SetString(StructError,
808 "required argument is not a float");
809 return -1;
810 }
811 return pack_float(x, p+3, -1);
812}
813
814static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000815lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000816{
817 double x = PyFloat_AsDouble(v);
818 if (x == -1 && PyErr_Occurred()) {
819 PyErr_SetString(StructError,
820 "required argument is not a float");
821 return -1;
822 }
823 return pack_double(x, p+7, -1);
824}
825
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000826static formatdef lilendian_table[] = {
827 {'x', 1, 0, NULL},
828 {'b', 1, 0, lu_int, lp_int},
829 {'B', 1, 0, lu_uint, lp_int},
830 {'c', 1, 0, nu_char, np_char},
831 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000832 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000833 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000834 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000835 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000836 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000837 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000838 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000839 {'f', 4, 0, lu_float, lp_float},
840 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000841 {0}
842};
843
844
845static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000846whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000847{
848 const char *fmt = (*pfmt)++; /* May be backed out of later */
849 switch (*fmt) {
850 case '<':
851 return lilendian_table;
852 case '>':
853 case '!': /* Network byte order is big-endian */
854 return bigendian_table;
855 case '=': { /* Host byte order -- different from native in aligment! */
856 int n = 1;
857 char *p = (char *) &n;
858 if (*p == 1)
859 return lilendian_table;
860 else
861 return bigendian_table;
862 }
863 default:
864 --*pfmt; /* Back out of pointer increment */
865 /* Fall through */
866 case '@':
867 return native_table;
868 }
869}
870
871
872/* Get the table entry for a format code */
873
874static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000875getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000876{
877 for (; f->format != '\0'; f++) {
878 if (f->format == c) {
879 return f;
880 }
881 }
882 PyErr_SetString(StructError, "bad char in struct format");
883 return NULL;
884}
885
886
Guido van Rossum02975121992-08-17 08:55:12 +0000887/* Align a size according to a format code */
888
889static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000890align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +0000891{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000892 if (e->format == c) {
893 if (e->alignment) {
894 size = ((size + e->alignment - 1)
895 / e->alignment)
896 * e->alignment;
897 }
Guido van Rossum02975121992-08-17 08:55:12 +0000898 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000899 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000900}
901
902
903/* calculate the size of a format string */
904
905static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000906calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +0000907{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000908 const formatdef *e;
909 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000910 char c;
911 int size, num, itemsize, x;
912
913 s = fmt;
914 size = 0;
915 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +0000916 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +0000917 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000918 if ('0' <= c && c <= '9') {
919 num = c - '0';
920 while ('0' <= (c = *s++) && c <= '9') {
921 x = num*10 + (c - '0');
922 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000923 PyErr_SetString(
924 StructError,
925 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000926 return -1;
927 }
928 num = x;
929 }
930 if (c == '\0')
931 break;
932 }
933 else
934 num = 1;
935
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000936 e = getentry(c, f);
937 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000938 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000939 itemsize = e->size;
940 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000941 x = num * itemsize;
942 size += x;
943 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000944 PyErr_SetString(StructError,
945 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000946 return -1;
947 }
Guido van Rossum02975121992-08-17 08:55:12 +0000948 }
949
950 return size;
951}
952
953
Guido van Rossum414fd481997-12-19 04:24:24 +0000954static char calcsize__doc__[] = "\
955calcsize(fmt) -> int\n\
956Return size of C struct described by format string fmt.\n\
957See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +0000958
Barry Warsaw30695fa1996-12-12 23:32:31 +0000959static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000960struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +0000961{
962 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000963 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000964 int size;
965
Guido van Rossum43713e52000-02-29 13:59:29 +0000966 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +0000967 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000968 f = whichtable(&fmt);
969 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +0000970 if (size < 0)
971 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000972 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +0000973}
974
975
Guido van Rossum414fd481997-12-19 04:24:24 +0000976static char pack__doc__[] = "\
977pack(fmt, v1, v2, ...) -> string\n\
978Return string containing values v1, v2, ... packed according to fmt.\n\
979See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +0000980
Barry Warsaw30695fa1996-12-12 23:32:31 +0000981static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000982struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +0000983{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000984 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000985 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +0000986 char *fmt;
987 int size, num;
988 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +0000989 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +0000990 char c;
Guido van Rossum02975121992-08-17 08:55:12 +0000991
Barry Warsaw30695fa1996-12-12 23:32:31 +0000992 if (args == NULL || !PyTuple_Check(args) ||
993 (n = PyTuple_Size(args)) < 1)
994 {
Fred Drake137507e2000-06-01 02:02:46 +0000995 PyErr_SetString(PyExc_TypeError,
996 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +0000997 return NULL;
998 }
Barry Warsaw30695fa1996-12-12 23:32:31 +0000999 format = PyTuple_GetItem(args, 0);
1000 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001001 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001002 f = whichtable(&fmt);
1003 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001004 if (size < 0)
1005 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001006 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001007 if (result == NULL)
1008 return NULL;
1009
1010 s = fmt;
1011 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001012 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001013
1014 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001015 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001016 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001017 if ('0' <= c && c <= '9') {
1018 num = c - '0';
1019 while ('0' <= (c = *s++) && c <= '9')
1020 num = num*10 + (c - '0');
1021 if (c == '\0')
1022 break;
1023 }
1024 else
1025 num = 1;
1026
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001027 e = getentry(c, f);
1028 if (e == NULL)
1029 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001030 nres = restart + align((int)(res-restart), c, e);
1031 /* Fill padd bytes with zeros */
1032 while (res < nres)
1033 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001034 if (num == 0 && c != 's')
1035 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001036 do {
1037 if (c == 'x') {
1038 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001039 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001040 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001041 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001042 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001043 if (i >= n) {
1044 PyErr_SetString(StructError,
1045 "insufficient arguments to pack");
1046 goto fail;
1047 }
1048 v = PyTuple_GetItem(args, i++);
1049 if (v == NULL)
1050 goto fail;
1051 if (c == 's') {
1052 /* num is string size, not repeat count */
1053 int n;
1054 if (!PyString_Check(v)) {
1055 PyErr_SetString(StructError,
1056 "argument for 's' must be a string");
1057 goto fail;
1058 }
1059 n = PyString_Size(v);
1060 if (n > num)
1061 n = num;
1062 if (n > 0)
1063 memcpy(res, PyString_AsString(v), n);
1064 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001065 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001066 res += num;
1067 break;
1068 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001069 else if (c == 'p') {
1070 /* num is string size + 1,
1071 to fit in the count byte */
1072 int n;
1073 num--; /* now num is max string size */
1074 if (!PyString_Check(v)) {
1075 PyErr_SetString(StructError,
1076 "argument for 'p' must be a string");
1077 goto fail;
1078 }
1079 n = PyString_Size(v);
1080 if (n > num)
1081 n = num;
1082 if (n > 0)
1083 memcpy(res+1, PyString_AsString(v), n);
1084 if (n < num)
1085 /* no real need, just to be nice */
1086 memset(res+1+n, '\0', num-n);
1087 *res++ = n; /* store the length byte */
1088 res += num;
1089 break;
1090 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001091 else {
1092 if (e->pack(res, v, e) < 0)
1093 goto fail;
1094 res += e->size;
1095 }
1096 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001097 }
1098
1099 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001100 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001101 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001102 goto fail;
1103 }
1104
1105 return result;
1106
1107 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001108 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001109 return NULL;
1110}
1111
1112
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001113static char unpack__doc__[] = "\
1114unpack(fmt, string) -> (v1, v2, ...)\n\
1115Unpack the string, containing packed C structure data, according\n\
1116to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001117See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001118
Barry Warsaw30695fa1996-12-12 23:32:31 +00001119static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001120struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001121{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001122 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001123 char *str, *start, *fmt, *s;
1124 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001125 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001126 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001127
Guido van Rossum43713e52000-02-29 13:59:29 +00001128 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001129 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001130 f = whichtable(&fmt);
1131 size = calcsize(fmt, f);
1132 if (size < 0)
1133 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001134 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001135 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001136 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001137 return NULL;
1138 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001139 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001140 if (res == NULL)
1141 return NULL;
1142 str = start;
1143 s = fmt;
1144 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001145 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001146 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001147 if ('0' <= c && c <= '9') {
1148 num = c - '0';
1149 while ('0' <= (c = *s++) && c <= '9')
1150 num = num*10 + (c - '0');
1151 if (c == '\0')
1152 break;
1153 }
1154 else
1155 num = 1;
1156
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001157 e = getentry(c, f);
1158 if (e == NULL)
1159 goto fail;
1160 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001161 if (num == 0 && c != 's')
1162 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001163
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001164 do {
1165 if (c == 'x') {
1166 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001167 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001168 }
1169 if (c == 's') {
1170 /* num is string size, not repeat count */
1171 v = PyString_FromStringAndSize(str, num);
1172 if (v == NULL)
1173 goto fail;
1174 str += num;
1175 num = 0;
1176 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001177 else if (c == 'p') {
1178 /* num is string buffer size,
1179 not repeat count */
1180 int n = *(unsigned char*)str;
1181 /* first byte (unsigned) is string size */
1182 if (n >= num)
1183 n = num-1;
1184 v = PyString_FromStringAndSize(str+1, n);
1185 if (v == NULL)
1186 goto fail;
1187 str += num;
1188 num = 0;
1189 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001190 else {
1191 v = e->unpack(str, e);
1192 if (v == NULL)
1193 goto fail;
1194 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001195 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001196 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001197 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001198 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001199 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001200 }
1201
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001202 v = PyList_AsTuple(res);
1203 Py_DECREF(res);
1204 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001205
1206 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001207 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001208 return NULL;
1209}
1210
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001211
Guido van Rossum02975121992-08-17 08:55:12 +00001212/* List of functions */
1213
Barry Warsaw30695fa1996-12-12 23:32:31 +00001214static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001215 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1216 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1217 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001218 {NULL, NULL} /* sentinel */
1219};
1220
1221
1222/* Module initialization */
1223
Guido van Rossum3886bb61998-12-04 18:50:17 +00001224DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001225initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001226{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001227 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001228
1229 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001230 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1231 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001232
1233 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001234 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001235 StructError = PyErr_NewException("struct.error", NULL, NULL);
1236 if (StructError == NULL)
1237 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001238 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001239}