blob: c253a76df78f375ad95a08985bdc291d7afd1f91 [file] [log] [blame]
Guido van Rossum02975121992-08-17 08:55:12 +00001
2/* struct module -- pack values into and (out of) strings */
3
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00004/* New version supporting byte order, alignment and size options,
5 character strings, and unsigned numbers */
6
Guido van Rossum414fd481997-12-19 04:24:24 +00007static char struct__doc__[] = "\
8Functions to convert between Python values and C structs.\n\
9Python strings are used to hold the data representing the C struct\n\
10and also as format strings to describe the layout of data in the C struct.\n\
11\n\
12The optional first format char indicates byte ordering and alignment:\n\
13 @: native w/native alignment(default)\n\
14 =: native w/standard alignment\n\
15 <: little-endian, std. alignment\n\
16 >: big-endian, std. alignment\n\
17 !: network, std (same as >)\n\
18\n\
19The remaining chars indicate types of args and must match exactly;\n\
20these can be preceded by a decimal repeat count:\n\
21 x: pad byte (no data); c:char; b:signed byte; B:unsigned byte;\n\
22 h:short; H:unsigned short; i:int; I:unsigned int;\n\
23 l:long; L:unsigned long; f:float; d:double.\n\
24Special cases (preceding decimal count indicates length):\n\
25 s:string (array of char); p: pascal string (w. count byte).\n\
Guido van Rossum78694d91998-09-18 14:14:13 +000026Special case (only available in native format):\n\
27 P:an integer type that is wide enough to hold a pointer.\n\
Guido van Rossum414fd481997-12-19 04:24:24 +000028Whitespace between formats is ignored.\n\
29\n\
30The variable struct.error is an exception raised on errors.";
31
Barry Warsaw30695fa1996-12-12 23:32:31 +000032#include "Python.h"
Guido van Rossum02975121992-08-17 08:55:12 +000033
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000034#include <limits.h>
Guido van Rossume20aef51997-08-26 20:39:54 +000035#include <ctype.h>
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000036
37
38/* Exception */
39
Barry Warsaw30695fa1996-12-12 23:32:31 +000040static PyObject *StructError;
Guido van Rossum02975121992-08-17 08:55:12 +000041
42
43/* Define various structs to figure out the alignments of types */
44
Jack Jansen971e1df1995-02-02 14:29:10 +000045#ifdef __MWERKS__
46/*
47** XXXX We have a problem here. There are no unique alignment rules
48** on the PowerPC mac.
49*/
50#ifdef __powerc
51#pragma options align=mac68k
52#endif
53#endif /* __MWERKS__ */
54
Guido van Rossum02975121992-08-17 08:55:12 +000055typedef struct { char c; short x; } s_short;
56typedef struct { char c; int x; } s_int;
57typedef struct { char c; long x; } s_long;
58typedef struct { char c; float x; } s_float;
59typedef struct { char c; double x; } s_double;
Guido van Rossum78694d91998-09-18 14:14:13 +000060typedef struct { char c; void *x; } s_void_p;
Guido van Rossum02975121992-08-17 08:55:12 +000061
62#define SHORT_ALIGN (sizeof(s_short) - sizeof(short))
63#define INT_ALIGN (sizeof(s_int) - sizeof(int))
64#define LONG_ALIGN (sizeof(s_long) - sizeof(long))
65#define FLOAT_ALIGN (sizeof(s_float) - sizeof(float))
66#define DOUBLE_ALIGN (sizeof(s_double) - sizeof(double))
Guido van Rossum78694d91998-09-18 14:14:13 +000067#define VOID_P_ALIGN (sizeof(s_void_p) - sizeof(void *))
Guido van Rossum02975121992-08-17 08:55:12 +000068
Jack Jansen971e1df1995-02-02 14:29:10 +000069#ifdef __powerc
70#pragma options align=reset
71#endif
72
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000073/* Helper routine to get a Python integer and raise the appropriate error
74 if it isn't one */
75
76static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000077get_long(PyObject *v, long *p)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000078{
79 long x = PyInt_AsLong(v);
80 if (x == -1 && PyErr_Occurred()) {
Fred Draked3dbb381998-05-28 04:35:49 +000081 if (PyErr_ExceptionMatches(PyExc_TypeError))
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +000082 PyErr_SetString(StructError,
83 "required argument is not an integer");
84 return -1;
85 }
86 *p = x;
87 return 0;
88}
89
90
Guido van Rossum60c50611996-12-31 16:29:52 +000091/* Same, but handling unsigned long */
92
93static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +000094get_ulong(PyObject *v, unsigned long *p)
Guido van Rossum60c50611996-12-31 16:29:52 +000095{
Guido van Rossum6c87eca1997-01-03 19:08:16 +000096 if (PyLong_Check(v)) {
97 unsigned long x = PyLong_AsUnsignedLong(v);
98 if (x == (unsigned long)(-1) && PyErr_Occurred())
Guido van Rossum60c50611996-12-31 16:29:52 +000099 return -1;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000100 *p = x;
101 return 0;
Guido van Rossum60c50611996-12-31 16:29:52 +0000102 }
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000103 else {
104 return get_long(v, (long *)p);
105 }
Guido van Rossum60c50611996-12-31 16:29:52 +0000106}
107
108
Guido van Rossum74679b41997-01-02 22:21:36 +0000109/* Floating point helpers */
110
111/* These use ANSI/IEEE Standard 754-1985 (Standard for Binary Floating
112 Point Arithmetic). See the following URL:
113 http://www.psc.edu/general/software/packages/ieee/ieee.html */
114
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000115/* XXX Inf/NaN are not handled quite right (but underflow is!) */
Guido van Rossum74679b41997-01-02 22:21:36 +0000116
117static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000118pack_float(double x, /* The number to pack */
119 char *p, /* Where to pack the high order byte */
120 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000121{
122 int s;
123 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000124 double f;
125 long fbits;
Guido van Rossum74679b41997-01-02 22:21:36 +0000126
127 if (x < 0) {
128 s = 1;
129 x = -x;
130 }
131 else
132 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000133
134 f = frexp(x, &e);
135
136 /* Normalize f to be in the range [1.0, 2.0) */
137 if (0.5 <= f && f < 1.0) {
138 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000139 e--;
140 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000141 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000142 e = 0;
143 }
144 else {
145 PyErr_SetString(PyExc_SystemError,
146 "frexp() result out of range");
147 return -1;
148 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000149
150 if (e >= 128) {
151 /* XXX 128 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000152 PyErr_SetString(PyExc_OverflowError,
153 "float too large to pack with f format");
154 return -1;
155 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000156 else if (e < -126) {
157 /* Gradual underflow */
158 f = ldexp(f, 126 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000159 e = 0;
160 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000161 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000162 e += 127;
163 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000164 }
165
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000166 f *= 8388608.0; /* 2**23 */
167 fbits = (long) floor(f + 0.5); /* Round */
168
Guido van Rossum74679b41997-01-02 22:21:36 +0000169 /* First byte */
170 *p = (s<<7) | (e>>1);
171 p += incr;
172
173 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000174 *p = (char) (((e&1)<<7) | (fbits>>16));
Guido van Rossum74679b41997-01-02 22:21:36 +0000175 p += incr;
176
177 /* Third byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000178 *p = (fbits>>8) & 0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000179 p += incr;
180
181 /* Fourth byte */
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000182 *p = fbits&0xFF;
Guido van Rossum74679b41997-01-02 22:21:36 +0000183
184 /* Done */
185 return 0;
186}
187
188static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000189pack_double(double x, /* The number to pack */
190 char *p, /* Where to pack the high order byte */
191 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000192{
193 int s;
194 int e;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000195 double f;
Guido van Rossum74679b41997-01-02 22:21:36 +0000196 long fhi, flo;
197
198 if (x < 0) {
199 s = 1;
200 x = -x;
201 }
202 else
203 s = 0;
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000204
205 f = frexp(x, &e);
206
207 /* Normalize f to be in the range [1.0, 2.0) */
208 if (0.5 <= f && f < 1.0) {
209 f *= 2.0;
Guido van Rossum74679b41997-01-02 22:21:36 +0000210 e--;
211 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000212 else if (f == 0.0) {
Guido van Rossum74679b41997-01-02 22:21:36 +0000213 e = 0;
214 }
215 else {
216 PyErr_SetString(PyExc_SystemError,
217 "frexp() result out of range");
218 return -1;
219 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000220
221 if (e >= 1024) {
222 /* XXX 1024 itself is reserved for Inf/NaN */
Guido van Rossum74679b41997-01-02 22:21:36 +0000223 PyErr_SetString(PyExc_OverflowError,
224 "float too large to pack with d format");
225 return -1;
226 }
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000227 else if (e < -1022) {
228 /* Gradual underflow */
229 f = ldexp(f, 1022 + e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000230 e = 0;
231 }
Guido van Rossum8f3c8121997-11-04 17:12:33 +0000232 else if (!(e == 0 && f == 0.0)) {
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000233 e += 1023;
234 f -= 1.0; /* Get rid of leading 1 */
Guido van Rossum74679b41997-01-02 22:21:36 +0000235 }
236
Guido van Rossum4ccc5311997-01-02 23:23:20 +0000237 /* fhi receives the high 28 bits; flo the low 24 bits (== 52 bits) */
238 f *= 268435456.0; /* 2**28 */
239 fhi = (long) floor(f); /* Truncate */
240 f -= (double)fhi;
241 f *= 16777216.0; /* 2**24 */
242 flo = (long) floor(f + 0.5); /* Round */
243
Guido van Rossum74679b41997-01-02 22:21:36 +0000244 /* First byte */
245 *p = (s<<7) | (e>>4);
246 p += incr;
247
248 /* Second byte */
Guido van Rossum7844e381997-04-11 20:44:04 +0000249 *p = (char) (((e&0xF)<<4) | (fhi>>24));
Guido van Rossum74679b41997-01-02 22:21:36 +0000250 p += incr;
251
252 /* Third byte */
253 *p = (fhi>>16) & 0xFF;
254 p += incr;
255
256 /* Fourth byte */
257 *p = (fhi>>8) & 0xFF;
258 p += incr;
259
260 /* Fifth byte */
261 *p = fhi & 0xFF;
262 p += incr;
263
264 /* Sixth byte */
265 *p = (flo>>16) & 0xFF;
266 p += incr;
267
268 /* Seventh byte */
269 *p = (flo>>8) & 0xFF;
270 p += incr;
271
272 /* Eighth byte */
273 *p = flo & 0xFF;
274 p += incr;
275
276 /* Done */
277 return 0;
278}
279
280static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000281unpack_float(const char *p, /* Where the high order byte is */
282 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000283{
284 int s;
285 int e;
286 long f;
287 double x;
288
289 /* First byte */
290 s = (*p>>7) & 1;
291 e = (*p & 0x7F) << 1;
292 p += incr;
293
294 /* Second byte */
295 e |= (*p>>7) & 1;
296 f = (*p & 0x7F) << 16;
297 p += incr;
298
299 /* Third byte */
300 f |= (*p & 0xFF) << 8;
301 p += incr;
302
303 /* Fourth byte */
304 f |= *p & 0xFF;
305
306 x = (double)f / 8388608.0;
307
308 /* XXX This sadly ignores Inf/NaN issues */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000309 if (e == 0)
310 e = -126;
311 else {
312 x += 1.0;
313 e -= 127;
314 }
315 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000316
317 if (s)
318 x = -x;
319
320 return PyFloat_FromDouble(x);
321}
322
323static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000324unpack_double(const char *p, /* Where the high order byte is */
325 int incr) /* 1 for big-endian; -1 for little-endian */
Guido van Rossum74679b41997-01-02 22:21:36 +0000326{
327 int s;
328 int e;
329 long fhi, flo;
330 double x;
331
332 /* First byte */
333 s = (*p>>7) & 1;
334 e = (*p & 0x7F) << 4;
335 p += incr;
336
337 /* Second byte */
338 e |= (*p>>4) & 0xF;
339 fhi = (*p & 0xF) << 24;
340 p += incr;
341
342 /* Third byte */
343 fhi |= (*p & 0xFF) << 16;
344 p += incr;
345
346 /* Fourth byte */
347 fhi |= (*p & 0xFF) << 8;
348 p += incr;
349
350 /* Fifth byte */
351 fhi |= *p & 0xFF;
352 p += incr;
353
354 /* Sixth byte */
355 flo = (*p & 0xFF) << 16;
356 p += incr;
357
358 /* Seventh byte */
359 flo |= (*p & 0xFF) << 8;
360 p += incr;
361
362 /* Eighth byte */
363 flo |= *p & 0xFF;
364 p += incr;
365
366 x = (double)fhi + (double)flo / 16777216.0; /* 2**24 */
367 x /= 268435456.0; /* 2**28 */
368
369 /* XXX This sadly ignores Inf/NaN */
Guido van Rossum07ef6551997-01-02 22:31:07 +0000370 if (e == 0)
371 e = -1022;
372 else {
373 x += 1.0;
374 e -= 1023;
375 }
376 x = ldexp(x, e);
Guido van Rossum74679b41997-01-02 22:21:36 +0000377
378 if (s)
379 x = -x;
380
381 return PyFloat_FromDouble(x);
382}
383
384
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000385/* The translation function for each format character is table driven */
386
387typedef struct _formatdef {
388 char format;
389 int size;
390 int alignment;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000391 PyObject* (*unpack)(const char *,
392 const struct _formatdef *);
393 int (*pack)(char *, PyObject *,
394 const struct _formatdef *);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000395} formatdef;
396
397static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000398nu_char(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000399{
400 return PyString_FromStringAndSize(p, 1);
401}
402
403static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000404nu_byte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000405{
406 return PyInt_FromLong((long) *(signed char *)p);
407}
408
409static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000410nu_ubyte(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000411{
412 return PyInt_FromLong((long) *(unsigned char *)p);
413}
414
415static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000416nu_short(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000417{
418 return PyInt_FromLong((long) *(short *)p);
419}
420
421static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000422nu_ushort(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000423{
424 return PyInt_FromLong((long) *(unsigned short *)p);
425}
426
427static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000428nu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000429{
430 return PyInt_FromLong((long) *(int *)p);
431}
432
433static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000434nu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000435{
436 unsigned int x = *(unsigned int *)p;
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000437 return PyLong_FromUnsignedLong((unsigned long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000438}
439
440static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000441nu_long(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000442{
443 return PyInt_FromLong(*(long *)p);
444}
445
446static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000447nu_ulong(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000448{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000449 return PyLong_FromUnsignedLong(*(unsigned long *)p);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000450}
451
452static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000453nu_float(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000454{
455 float x;
456 memcpy((char *)&x, p, sizeof(float));
457 return PyFloat_FromDouble((double)x);
458}
459
460static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000461nu_double(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000462{
463 double x;
464 memcpy((char *)&x, p, sizeof(double));
465 return PyFloat_FromDouble(x);
466}
467
Guido van Rossum78694d91998-09-18 14:14:13 +0000468static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000469nu_void_p(const char *p, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000470{
471 return PyLong_FromVoidPtr(*(void **)p);
472}
473
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000474static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000475np_byte(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000476{
477 long x;
478 if (get_long(v, &x) < 0)
479 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000480 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000481 return 0;
482}
483
484static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000485np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000486{
487 if (!PyString_Check(v) || PyString_Size(v) != 1) {
488 PyErr_SetString(StructError,
489 "char format require string of length 1");
490 return -1;
491 }
492 *p = *PyString_AsString(v);
493 return 0;
494}
495
496static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000497np_short(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000498{
499 long x;
500 if (get_long(v, &x) < 0)
501 return -1;
Guido van Rossum7844e381997-04-11 20:44:04 +0000502 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000503 return 0;
504}
505
506static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000507np_int(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;
512 * (int *)p = x;
513 return 0;
514}
515
516static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000517np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000518{
519 unsigned long x;
520 if (get_ulong(v, &x) < 0)
521 return -1;
522 * (unsigned int *)p = x;
523 return 0;
524}
525
526static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000527np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000528{
529 long x;
530 if (get_long(v, &x) < 0)
531 return -1;
532 * (long *)p = x;
533 return 0;
534}
535
536static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000537np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000538{
539 unsigned long x;
540 if (get_ulong(v, &x) < 0)
541 return -1;
542 * (unsigned long *)p = x;
543 return 0;
544}
545
546static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000547np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000548{
549 float x = (float)PyFloat_AsDouble(v);
550 if (x == -1 && PyErr_Occurred()) {
551 PyErr_SetString(StructError,
552 "required argument is not a float");
553 return -1;
554 }
555 memcpy(p, (char *)&x, sizeof(float));
556 return 0;
557}
558
559static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000560np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000561{
562 double x = PyFloat_AsDouble(v);
563 if (x == -1 && PyErr_Occurred()) {
564 PyErr_SetString(StructError,
565 "required argument is not a float");
566 return -1;
567 }
568 memcpy(p, (char *)&x, sizeof(double));
569 return 0;
570}
571
Guido van Rossum78694d91998-09-18 14:14:13 +0000572static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000573np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000574{
575 void *x = PyLong_AsVoidPtr(v);
576 if (x == NULL && PyErr_Occurred()) {
577 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
578 if (PyErr_ExceptionMatches(PyExc_TypeError))
579 PyErr_SetString(StructError,
580 "required argument is not an integer");
581 return -1;
582 }
583 *(void **)p = x;
584 return 0;
585}
586
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000587static formatdef native_table[] = {
588 {'x', sizeof(char), 0, NULL},
589 {'b', sizeof(char), 0, nu_byte, np_byte},
590 {'B', sizeof(char), 0, nu_ubyte, np_byte},
591 {'c', sizeof(char), 0, nu_char, np_char},
592 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000593 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000594 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
595 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_short},
596 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000597 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000598 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000599 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000600 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
601 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000602 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000603 {0}
604};
605
606static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000607bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000608{
609 long x = 0;
610 int i = f->size;
611 do {
612 x = (x<<8) | (*p++ & 0xFF);
613 } while (--i > 0);
614 i = 8*(sizeof(long) - f->size);
615 if (i) {
616 x <<= i;
617 x >>= i;
618 }
619 return PyInt_FromLong(x);
620}
621
622static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000623bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000624{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000625 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000626 int i = f->size;
627 do {
628 x = (x<<8) | (*p++ & 0xFF);
629 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000630 if (f->size >= 4)
631 return PyLong_FromUnsignedLong(x);
632 else
633 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000634}
635
Guido van Rossum74679b41997-01-02 22:21:36 +0000636static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000637bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000638{
639 return unpack_float(p, 1);
640}
641
642static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000643bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000644{
645 return unpack_double(p, 1);
646}
647
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000648static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000649bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000650{
651 long x;
652 int i;
653 if (get_long(v, &x) < 0)
654 return -1;
655 i = f->size;
656 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000657 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000658 x >>= 8;
659 } while (i > 0);
660 return 0;
661}
662
Guido van Rossum60c50611996-12-31 16:29:52 +0000663static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000664bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000665{
666 unsigned long x;
667 int i;
668 if (get_ulong(v, &x) < 0)
669 return -1;
670 i = f->size;
671 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000672 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000673 x >>= 8;
674 } while (i > 0);
675 return 0;
676}
677
Guido van Rossum74679b41997-01-02 22:21:36 +0000678static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000679bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000680{
681 double x = PyFloat_AsDouble(v);
682 if (x == -1 && PyErr_Occurred()) {
683 PyErr_SetString(StructError,
684 "required argument is not a float");
685 return -1;
686 }
687 return pack_float(x, p, 1);
688}
689
690static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000691bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000692{
693 double x = PyFloat_AsDouble(v);
694 if (x == -1 && PyErr_Occurred()) {
695 PyErr_SetString(StructError,
696 "required argument is not a float");
697 return -1;
698 }
699 return pack_double(x, p, 1);
700}
701
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000702static formatdef bigendian_table[] = {
703 {'x', 1, 0, NULL},
704 {'b', 1, 0, bu_int, bp_int},
705 {'B', 1, 0, bu_uint, bp_int},
706 {'c', 1, 0, nu_char, np_char},
707 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000708 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000709 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000710 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000711 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000712 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000713 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000714 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000715 {'f', 4, 0, bu_float, bp_float},
716 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000717 {0}
718};
719
720static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000721lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000722{
723 long x = 0;
724 int i = f->size;
725 do {
726 x = (x<<8) | (p[--i] & 0xFF);
727 } while (i > 0);
728 i = 8*(sizeof(long) - f->size);
729 if (i) {
730 x <<= i;
731 x >>= i;
732 }
733 return PyInt_FromLong(x);
734}
735
736static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000737lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000738{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000739 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000740 int i = f->size;
741 do {
742 x = (x<<8) | (p[--i] & 0xFF);
743 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000744 if (f->size >= 4)
745 return PyLong_FromUnsignedLong(x);
746 else
747 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000748}
749
Guido van Rossum74679b41997-01-02 22:21:36 +0000750static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000751lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000752{
753 return unpack_float(p+3, -1);
754}
755
756static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000757lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000758{
759 return unpack_double(p+7, -1);
760}
761
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000762static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000763lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000764{
765 long x;
766 int i;
767 if (get_long(v, &x) < 0)
768 return -1;
769 i = f->size;
770 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000771 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000772 x >>= 8;
773 } while (--i > 0);
774 return 0;
775}
776
Guido van Rossum60c50611996-12-31 16:29:52 +0000777static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000778lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000779{
780 unsigned long x;
781 int i;
782 if (get_ulong(v, &x) < 0)
783 return -1;
784 i = f->size;
785 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000786 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000787 x >>= 8;
788 } while (--i > 0);
789 return 0;
790}
791
Guido van Rossum74679b41997-01-02 22:21:36 +0000792static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000793lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000794{
795 double x = PyFloat_AsDouble(v);
796 if (x == -1 && PyErr_Occurred()) {
797 PyErr_SetString(StructError,
798 "required argument is not a float");
799 return -1;
800 }
801 return pack_float(x, p+3, -1);
802}
803
804static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000805lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000806{
807 double x = PyFloat_AsDouble(v);
808 if (x == -1 && PyErr_Occurred()) {
809 PyErr_SetString(StructError,
810 "required argument is not a float");
811 return -1;
812 }
813 return pack_double(x, p+7, -1);
814}
815
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000816static formatdef lilendian_table[] = {
817 {'x', 1, 0, NULL},
818 {'b', 1, 0, lu_int, lp_int},
819 {'B', 1, 0, lu_uint, lp_int},
820 {'c', 1, 0, nu_char, np_char},
821 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000822 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000823 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000824 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000825 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000826 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000827 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000828 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000829 {'f', 4, 0, lu_float, lp_float},
830 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000831 {0}
832};
833
834
835static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000836whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000837{
838 const char *fmt = (*pfmt)++; /* May be backed out of later */
839 switch (*fmt) {
840 case '<':
841 return lilendian_table;
842 case '>':
843 case '!': /* Network byte order is big-endian */
844 return bigendian_table;
845 case '=': { /* Host byte order -- different from native in aligment! */
846 int n = 1;
847 char *p = (char *) &n;
848 if (*p == 1)
849 return lilendian_table;
850 else
851 return bigendian_table;
852 }
853 default:
854 --*pfmt; /* Back out of pointer increment */
855 /* Fall through */
856 case '@':
857 return native_table;
858 }
859}
860
861
862/* Get the table entry for a format code */
863
864static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000865getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000866{
867 for (; f->format != '\0'; f++) {
868 if (f->format == c) {
869 return f;
870 }
871 }
872 PyErr_SetString(StructError, "bad char in struct format");
873 return NULL;
874}
875
876
Guido van Rossum02975121992-08-17 08:55:12 +0000877/* Align a size according to a format code */
878
879static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000880align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +0000881{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000882 if (e->format == c) {
883 if (e->alignment) {
884 size = ((size + e->alignment - 1)
885 / e->alignment)
886 * e->alignment;
887 }
Guido van Rossum02975121992-08-17 08:55:12 +0000888 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000889 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000890}
891
892
893/* calculate the size of a format string */
894
895static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000896calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +0000897{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000898 const formatdef *e;
899 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000900 char c;
901 int size, num, itemsize, x;
902
903 s = fmt;
904 size = 0;
905 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +0000906 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +0000907 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000908 if ('0' <= c && c <= '9') {
909 num = c - '0';
910 while ('0' <= (c = *s++) && c <= '9') {
911 x = num*10 + (c - '0');
912 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000913 PyErr_SetString(
914 StructError,
915 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000916 return -1;
917 }
918 num = x;
919 }
920 if (c == '\0')
921 break;
922 }
923 else
924 num = 1;
925
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000926 e = getentry(c, f);
927 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000928 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000929 itemsize = e->size;
930 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000931 x = num * itemsize;
932 size += x;
933 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000934 PyErr_SetString(StructError,
935 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000936 return -1;
937 }
Guido van Rossum02975121992-08-17 08:55:12 +0000938 }
939
940 return size;
941}
942
943
Guido van Rossum414fd481997-12-19 04:24:24 +0000944static char calcsize__doc__[] = "\
945calcsize(fmt) -> int\n\
946Return size of C struct described by format string fmt.\n\
947See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +0000948
Barry Warsaw30695fa1996-12-12 23:32:31 +0000949static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000950struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +0000951{
952 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000953 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000954 int size;
955
Guido van Rossum43713e52000-02-29 13:59:29 +0000956 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +0000957 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000958 f = whichtable(&fmt);
959 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +0000960 if (size < 0)
961 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000962 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +0000963}
964
965
Guido van Rossum414fd481997-12-19 04:24:24 +0000966static char pack__doc__[] = "\
967pack(fmt, v1, v2, ...) -> string\n\
968Return string containing values v1, v2, ... packed according to fmt.\n\
969See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +0000970
Barry Warsaw30695fa1996-12-12 23:32:31 +0000971static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000972struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +0000973{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000974 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000975 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +0000976 char *fmt;
977 int size, num;
978 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +0000979 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +0000980 char c;
Guido van Rossum02975121992-08-17 08:55:12 +0000981
Barry Warsaw30695fa1996-12-12 23:32:31 +0000982 if (args == NULL || !PyTuple_Check(args) ||
983 (n = PyTuple_Size(args)) < 1)
984 {
Fred Drake137507e2000-06-01 02:02:46 +0000985 PyErr_SetString(PyExc_TypeError,
986 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +0000987 return NULL;
988 }
Barry Warsaw30695fa1996-12-12 23:32:31 +0000989 format = PyTuple_GetItem(args, 0);
990 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +0000991 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000992 f = whichtable(&fmt);
993 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +0000994 if (size < 0)
995 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +0000996 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +0000997 if (result == NULL)
998 return NULL;
999
1000 s = fmt;
1001 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001002 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001003
1004 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001005 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001006 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001007 if ('0' <= c && c <= '9') {
1008 num = c - '0';
1009 while ('0' <= (c = *s++) && c <= '9')
1010 num = num*10 + (c - '0');
1011 if (c == '\0')
1012 break;
1013 }
1014 else
1015 num = 1;
1016
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001017 e = getentry(c, f);
1018 if (e == NULL)
1019 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001020 nres = restart + align((int)(res-restart), c, e);
1021 /* Fill padd bytes with zeros */
1022 while (res < nres)
1023 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001024 if (num == 0 && c != 's')
1025 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001026 do {
1027 if (c == 'x') {
1028 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001029 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001030 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001031 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001032 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001033 if (i >= n) {
1034 PyErr_SetString(StructError,
1035 "insufficient arguments to pack");
1036 goto fail;
1037 }
1038 v = PyTuple_GetItem(args, i++);
1039 if (v == NULL)
1040 goto fail;
1041 if (c == 's') {
1042 /* num is string size, not repeat count */
1043 int n;
1044 if (!PyString_Check(v)) {
1045 PyErr_SetString(StructError,
1046 "argument for 's' must be a string");
1047 goto fail;
1048 }
1049 n = PyString_Size(v);
1050 if (n > num)
1051 n = num;
1052 if (n > 0)
1053 memcpy(res, PyString_AsString(v), n);
1054 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001055 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001056 res += num;
1057 break;
1058 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001059 else if (c == 'p') {
1060 /* num is string size + 1,
1061 to fit in the count byte */
1062 int n;
1063 num--; /* now num is max string size */
1064 if (!PyString_Check(v)) {
1065 PyErr_SetString(StructError,
1066 "argument for 'p' must be a string");
1067 goto fail;
1068 }
1069 n = PyString_Size(v);
1070 if (n > num)
1071 n = num;
1072 if (n > 0)
1073 memcpy(res+1, PyString_AsString(v), n);
1074 if (n < num)
1075 /* no real need, just to be nice */
1076 memset(res+1+n, '\0', num-n);
1077 *res++ = n; /* store the length byte */
1078 res += num;
1079 break;
1080 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001081 else {
1082 if (e->pack(res, v, e) < 0)
1083 goto fail;
1084 res += e->size;
1085 }
1086 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001087 }
1088
1089 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001090 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001091 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001092 goto fail;
1093 }
1094
1095 return result;
1096
1097 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001098 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001099 return NULL;
1100}
1101
1102
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001103static char unpack__doc__[] = "\
1104unpack(fmt, string) -> (v1, v2, ...)\n\
1105Unpack the string, containing packed C structure data, according\n\
1106to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001107See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001108
Barry Warsaw30695fa1996-12-12 23:32:31 +00001109static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001110struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001111{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001112 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001113 char *str, *start, *fmt, *s;
1114 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001115 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001116 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001117
Guido van Rossum43713e52000-02-29 13:59:29 +00001118 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001119 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001120 f = whichtable(&fmt);
1121 size = calcsize(fmt, f);
1122 if (size < 0)
1123 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001124 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001125 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001126 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001127 return NULL;
1128 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001129 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001130 if (res == NULL)
1131 return NULL;
1132 str = start;
1133 s = fmt;
1134 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001135 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001136 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001137 if ('0' <= c && c <= '9') {
1138 num = c - '0';
1139 while ('0' <= (c = *s++) && c <= '9')
1140 num = num*10 + (c - '0');
1141 if (c == '\0')
1142 break;
1143 }
1144 else
1145 num = 1;
1146
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001147 e = getentry(c, f);
1148 if (e == NULL)
1149 goto fail;
1150 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001151 if (num == 0 && c != 's')
1152 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001153
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001154 do {
1155 if (c == 'x') {
1156 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001157 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001158 }
1159 if (c == 's') {
1160 /* num is string size, not repeat count */
1161 v = PyString_FromStringAndSize(str, num);
1162 if (v == NULL)
1163 goto fail;
1164 str += num;
1165 num = 0;
1166 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001167 else if (c == 'p') {
1168 /* num is string buffer size,
1169 not repeat count */
1170 int n = *(unsigned char*)str;
1171 /* first byte (unsigned) is string size */
1172 if (n >= num)
1173 n = num-1;
1174 v = PyString_FromStringAndSize(str+1, n);
1175 if (v == NULL)
1176 goto fail;
1177 str += num;
1178 num = 0;
1179 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001180 else {
1181 v = e->unpack(str, e);
1182 if (v == NULL)
1183 goto fail;
1184 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001185 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001186 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001187 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001188 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001189 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001190 }
1191
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001192 v = PyList_AsTuple(res);
1193 Py_DECREF(res);
1194 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001195
1196 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001197 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001198 return NULL;
1199}
1200
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001201
Guido van Rossum02975121992-08-17 08:55:12 +00001202/* List of functions */
1203
Barry Warsaw30695fa1996-12-12 23:32:31 +00001204static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001205 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1206 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1207 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001208 {NULL, NULL} /* sentinel */
1209};
1210
1211
1212/* Module initialization */
1213
Guido van Rossum3886bb61998-12-04 18:50:17 +00001214DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001215initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001216{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001217 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001218
1219 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001220 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1221 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001222
1223 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001224 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001225 StructError = PyErr_NewException("struct.error", NULL, NULL);
1226 if (StructError == NULL)
1227 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001228 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001229}