blob: 1b38c673fcddb39bcd5698a4fb401b624c71e374 [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;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000480 if (x < -128 || x > 127){
481 PyErr_SetString(StructError,
482 "byte format requires -128<=number<=127");
483 return -1;
484 }
485 *p = (char)x;
486 return 0;
487}
488
489static int
490np_ubyte(char *p, PyObject *v, const formatdef *f)
491{
492 long x;
493 if (get_long(v, &x) < 0)
494 return -1;
495 if (x < 0 || x > 255){
496 PyErr_SetString(StructError,
497 "ubyte format requires 0<=number<=255");
498 return -1;
499 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000500 *p = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000501 return 0;
502}
503
504static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000505np_char(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000506{
507 if (!PyString_Check(v) || PyString_Size(v) != 1) {
508 PyErr_SetString(StructError,
509 "char format require string of length 1");
510 return -1;
511 }
512 *p = *PyString_AsString(v);
513 return 0;
514}
515
516static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000517np_short(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;
Martin v. Löwis66de5492000-09-15 07:31:57 +0000522 if (x < -32768 || x > 32767){
523 PyErr_SetString(StructError,
524 "short format requires -32768<=number<=32767");
525 return -1;
526 }
Guido van Rossum7844e381997-04-11 20:44:04 +0000527 * (short *)p = (short)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000528 return 0;
529}
530
531static int
Martin v. Löwis66de5492000-09-15 07:31:57 +0000532np_ushort(char *p, PyObject *v, const formatdef *f)
533{
534 long x;
535 if (get_long(v, &x) < 0)
536 return -1;
537 if (x < 0 || x > 65535){
538 PyErr_SetString(StructError,
539 "short format requires 0<=number<=65535");
540 return -1;
541 }
542 * (unsigned short *)p = (unsigned short)x;
543 return 0;
544}
545
546static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000547np_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000548{
549 long x;
550 if (get_long(v, &x) < 0)
551 return -1;
552 * (int *)p = x;
553 return 0;
554}
555
556static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000557np_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000558{
559 unsigned long x;
560 if (get_ulong(v, &x) < 0)
561 return -1;
562 * (unsigned int *)p = x;
563 return 0;
564}
565
566static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000567np_long(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000568{
569 long x;
570 if (get_long(v, &x) < 0)
571 return -1;
572 * (long *)p = x;
573 return 0;
574}
575
576static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000577np_ulong(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000578{
579 unsigned long x;
580 if (get_ulong(v, &x) < 0)
581 return -1;
582 * (unsigned long *)p = x;
583 return 0;
584}
585
586static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000587np_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000588{
589 float x = (float)PyFloat_AsDouble(v);
590 if (x == -1 && PyErr_Occurred()) {
591 PyErr_SetString(StructError,
592 "required argument is not a float");
593 return -1;
594 }
595 memcpy(p, (char *)&x, sizeof(float));
596 return 0;
597}
598
599static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000600np_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000601{
602 double x = PyFloat_AsDouble(v);
603 if (x == -1 && PyErr_Occurred()) {
604 PyErr_SetString(StructError,
605 "required argument is not a float");
606 return -1;
607 }
608 memcpy(p, (char *)&x, sizeof(double));
609 return 0;
610}
611
Guido van Rossum78694d91998-09-18 14:14:13 +0000612static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000613np_void_p(char *p, PyObject *v, const formatdef *f)
Guido van Rossum78694d91998-09-18 14:14:13 +0000614{
615 void *x = PyLong_AsVoidPtr(v);
616 if (x == NULL && PyErr_Occurred()) {
617 /* ### hrm. PyLong_AsVoidPtr raises SystemError */
618 if (PyErr_ExceptionMatches(PyExc_TypeError))
619 PyErr_SetString(StructError,
620 "required argument is not an integer");
621 return -1;
622 }
623 *(void **)p = x;
624 return 0;
625}
626
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000627static formatdef native_table[] = {
628 {'x', sizeof(char), 0, NULL},
629 {'b', sizeof(char), 0, nu_byte, np_byte},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000630 {'B', sizeof(char), 0, nu_ubyte, np_ubyte},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000631 {'c', sizeof(char), 0, nu_char, np_char},
632 {'s', sizeof(char), 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000633 {'p', sizeof(char), 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000634 {'h', sizeof(short), SHORT_ALIGN, nu_short, np_short},
Martin v. Löwis66de5492000-09-15 07:31:57 +0000635 {'H', sizeof(short), SHORT_ALIGN, nu_ushort, np_ushort},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000636 {'i', sizeof(int), INT_ALIGN, nu_int, np_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000637 {'I', sizeof(int), INT_ALIGN, nu_uint, np_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000638 {'l', sizeof(long), LONG_ALIGN, nu_long, np_long},
Guido van Rossum60c50611996-12-31 16:29:52 +0000639 {'L', sizeof(long), LONG_ALIGN, nu_ulong, np_ulong},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000640 {'f', sizeof(float), FLOAT_ALIGN, nu_float, np_float},
641 {'d', sizeof(double), DOUBLE_ALIGN, nu_double, np_double},
Guido van Rossum78694d91998-09-18 14:14:13 +0000642 {'P', sizeof(void *), VOID_P_ALIGN, nu_void_p, np_void_p},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000643 {0}
644};
645
646static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000647bu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000648{
649 long x = 0;
650 int i = f->size;
651 do {
652 x = (x<<8) | (*p++ & 0xFF);
653 } while (--i > 0);
654 i = 8*(sizeof(long) - f->size);
655 if (i) {
656 x <<= i;
657 x >>= i;
658 }
659 return PyInt_FromLong(x);
660}
661
662static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000663bu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000664{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000665 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000666 int i = f->size;
667 do {
668 x = (x<<8) | (*p++ & 0xFF);
669 } while (--i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000670 if (f->size >= 4)
671 return PyLong_FromUnsignedLong(x);
672 else
673 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000674}
675
Guido van Rossum74679b41997-01-02 22:21:36 +0000676static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000677bu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000678{
679 return unpack_float(p, 1);
680}
681
682static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000683bu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000684{
685 return unpack_double(p, 1);
686}
687
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000688static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000689bp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000690{
691 long x;
692 int i;
693 if (get_long(v, &x) < 0)
694 return -1;
695 i = f->size;
696 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000697 p[--i] = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000698 x >>= 8;
699 } while (i > 0);
700 return 0;
701}
702
Guido van Rossum60c50611996-12-31 16:29:52 +0000703static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000704bp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000705{
706 unsigned long x;
707 int i;
708 if (get_ulong(v, &x) < 0)
709 return -1;
710 i = f->size;
711 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000712 p[--i] = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000713 x >>= 8;
714 } while (i > 0);
715 return 0;
716}
717
Guido van Rossum74679b41997-01-02 22:21:36 +0000718static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000719bp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000720{
721 double x = PyFloat_AsDouble(v);
722 if (x == -1 && PyErr_Occurred()) {
723 PyErr_SetString(StructError,
724 "required argument is not a float");
725 return -1;
726 }
727 return pack_float(x, p, 1);
728}
729
730static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000731bp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000732{
733 double x = PyFloat_AsDouble(v);
734 if (x == -1 && PyErr_Occurred()) {
735 PyErr_SetString(StructError,
736 "required argument is not a float");
737 return -1;
738 }
739 return pack_double(x, p, 1);
740}
741
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000742static formatdef bigendian_table[] = {
743 {'x', 1, 0, NULL},
744 {'b', 1, 0, bu_int, bp_int},
745 {'B', 1, 0, bu_uint, bp_int},
746 {'c', 1, 0, nu_char, np_char},
747 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000748 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000749 {'h', 2, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000750 {'H', 2, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000751 {'i', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000752 {'I', 4, 0, bu_uint, bp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000753 {'l', 4, 0, bu_int, bp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000754 {'L', 4, 0, bu_uint, bp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000755 {'f', 4, 0, bu_float, bp_float},
756 {'d', 8, 0, bu_double, bp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000757 {0}
758};
759
760static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000761lu_int(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000762{
763 long x = 0;
764 int i = f->size;
765 do {
766 x = (x<<8) | (p[--i] & 0xFF);
767 } while (i > 0);
768 i = 8*(sizeof(long) - f->size);
769 if (i) {
770 x <<= i;
771 x >>= i;
772 }
773 return PyInt_FromLong(x);
774}
775
776static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000777lu_uint(const char *p, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000778{
Guido van Rossum6c87eca1997-01-03 19:08:16 +0000779 unsigned long x = 0;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000780 int i = f->size;
781 do {
782 x = (x<<8) | (p[--i] & 0xFF);
783 } while (i > 0);
Guido van Rossum39ef2271998-06-29 04:00:40 +0000784 if (f->size >= 4)
785 return PyLong_FromUnsignedLong(x);
786 else
787 return PyInt_FromLong((long)x);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000788}
789
Guido van Rossum74679b41997-01-02 22:21:36 +0000790static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000791lu_float(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000792{
793 return unpack_float(p+3, -1);
794}
795
796static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000797lu_double(const char *p, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000798{
799 return unpack_double(p+7, -1);
800}
801
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000802static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000803lp_int(char *p, PyObject *v, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000804{
805 long x;
806 int i;
807 if (get_long(v, &x) < 0)
808 return -1;
809 i = f->size;
810 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000811 *p++ = (char)x;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000812 x >>= 8;
813 } while (--i > 0);
814 return 0;
815}
816
Guido van Rossum60c50611996-12-31 16:29:52 +0000817static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000818lp_uint(char *p, PyObject *v, const formatdef *f)
Guido van Rossum60c50611996-12-31 16:29:52 +0000819{
820 unsigned long x;
821 int i;
822 if (get_ulong(v, &x) < 0)
823 return -1;
824 i = f->size;
825 do {
Guido van Rossum7844e381997-04-11 20:44:04 +0000826 *p++ = (char)x;
Guido van Rossum60c50611996-12-31 16:29:52 +0000827 x >>= 8;
828 } while (--i > 0);
829 return 0;
830}
831
Guido van Rossum74679b41997-01-02 22:21:36 +0000832static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000833lp_float(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000834{
835 double x = PyFloat_AsDouble(v);
836 if (x == -1 && PyErr_Occurred()) {
837 PyErr_SetString(StructError,
838 "required argument is not a float");
839 return -1;
840 }
841 return pack_float(x, p+3, -1);
842}
843
844static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000845lp_double(char *p, PyObject *v, const formatdef *f)
Guido van Rossum74679b41997-01-02 22:21:36 +0000846{
847 double x = PyFloat_AsDouble(v);
848 if (x == -1 && PyErr_Occurred()) {
849 PyErr_SetString(StructError,
850 "required argument is not a float");
851 return -1;
852 }
853 return pack_double(x, p+7, -1);
854}
855
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000856static formatdef lilendian_table[] = {
857 {'x', 1, 0, NULL},
858 {'b', 1, 0, lu_int, lp_int},
859 {'B', 1, 0, lu_uint, lp_int},
860 {'c', 1, 0, nu_char, np_char},
861 {'s', 1, 0, NULL},
Guido van Rossum9eb671f1997-09-05 07:08:39 +0000862 {'p', 1, 0, NULL},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000863 {'h', 2, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000864 {'H', 2, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000865 {'i', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000866 {'I', 4, 0, lu_uint, lp_uint},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000867 {'l', 4, 0, lu_int, lp_int},
Guido van Rossum60c50611996-12-31 16:29:52 +0000868 {'L', 4, 0, lu_uint, lp_uint},
Guido van Rossum74679b41997-01-02 22:21:36 +0000869 {'f', 4, 0, lu_float, lp_float},
870 {'d', 8, 0, lu_double, lp_double},
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000871 {0}
872};
873
874
875static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000876whichtable(char **pfmt)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000877{
878 const char *fmt = (*pfmt)++; /* May be backed out of later */
879 switch (*fmt) {
880 case '<':
881 return lilendian_table;
882 case '>':
883 case '!': /* Network byte order is big-endian */
884 return bigendian_table;
885 case '=': { /* Host byte order -- different from native in aligment! */
886 int n = 1;
887 char *p = (char *) &n;
888 if (*p == 1)
889 return lilendian_table;
890 else
891 return bigendian_table;
892 }
893 default:
894 --*pfmt; /* Back out of pointer increment */
895 /* Fall through */
896 case '@':
897 return native_table;
898 }
899}
900
901
902/* Get the table entry for a format code */
903
904static const formatdef *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000905getentry(int c, const formatdef *f)
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000906{
907 for (; f->format != '\0'; f++) {
908 if (f->format == c) {
909 return f;
910 }
911 }
912 PyErr_SetString(StructError, "bad char in struct format");
913 return NULL;
914}
915
916
Guido van Rossum02975121992-08-17 08:55:12 +0000917/* Align a size according to a format code */
918
919static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000920align(int size, int c, const formatdef *e)
Guido van Rossum02975121992-08-17 08:55:12 +0000921{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000922 if (e->format == c) {
923 if (e->alignment) {
924 size = ((size + e->alignment - 1)
925 / e->alignment)
926 * e->alignment;
927 }
Guido van Rossum02975121992-08-17 08:55:12 +0000928 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000929 return size;
Guido van Rossum02975121992-08-17 08:55:12 +0000930}
931
932
933/* calculate the size of a format string */
934
935static int
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000936calcsize(const char *fmt, const formatdef *f)
Guido van Rossum02975121992-08-17 08:55:12 +0000937{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000938 const formatdef *e;
939 const char *s;
Guido van Rossum02975121992-08-17 08:55:12 +0000940 char c;
941 int size, num, itemsize, x;
942
943 s = fmt;
944 size = 0;
945 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +0000946 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +0000947 continue;
Guido van Rossum02975121992-08-17 08:55:12 +0000948 if ('0' <= c && c <= '9') {
949 num = c - '0';
950 while ('0' <= (c = *s++) && c <= '9') {
951 x = num*10 + (c - '0');
952 if (x/10 != num) {
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000953 PyErr_SetString(
954 StructError,
955 "overflow in item count");
Guido van Rossum02975121992-08-17 08:55:12 +0000956 return -1;
957 }
958 num = x;
959 }
960 if (c == '\0')
961 break;
962 }
963 else
964 num = 1;
965
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000966 e = getentry(c, f);
967 if (e == NULL)
Guido van Rossum02975121992-08-17 08:55:12 +0000968 return -1;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000969 itemsize = e->size;
970 size = align(size, c, e);
Guido van Rossum02975121992-08-17 08:55:12 +0000971 x = num * itemsize;
972 size += x;
973 if (x/itemsize != num || size < 0) {
Barry Warsaw30695fa1996-12-12 23:32:31 +0000974 PyErr_SetString(StructError,
975 "total struct size too long");
Guido van Rossum02975121992-08-17 08:55:12 +0000976 return -1;
977 }
Guido van Rossum02975121992-08-17 08:55:12 +0000978 }
979
980 return size;
981}
982
983
Guido van Rossum414fd481997-12-19 04:24:24 +0000984static char calcsize__doc__[] = "\
985calcsize(fmt) -> int\n\
986Return size of C struct described by format string fmt.\n\
987See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +0000988
Barry Warsaw30695fa1996-12-12 23:32:31 +0000989static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +0000990struct_calcsize(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +0000991{
992 char *fmt;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000993 const formatdef *f;
Guido van Rossum02975121992-08-17 08:55:12 +0000994 int size;
995
Guido van Rossum43713e52000-02-29 13:59:29 +0000996 if (!PyArg_ParseTuple(args, "s:calcsize", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +0000997 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +0000998 f = whichtable(&fmt);
999 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001000 if (size < 0)
1001 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001002 return PyInt_FromLong((long)size);
Guido van Rossum02975121992-08-17 08:55:12 +00001003}
1004
1005
Guido van Rossum414fd481997-12-19 04:24:24 +00001006static char pack__doc__[] = "\
1007pack(fmt, v1, v2, ...) -> string\n\
1008Return string containing values v1, v2, ... packed according to fmt.\n\
1009See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001010
Barry Warsaw30695fa1996-12-12 23:32:31 +00001011static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001012struct_pack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001013{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001014 const formatdef *f, *e;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001015 PyObject *format, *result, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001016 char *fmt;
1017 int size, num;
1018 int i, n;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001019 char *s, *res, *restart, *nres;
Guido van Rossum02975121992-08-17 08:55:12 +00001020 char c;
Guido van Rossum02975121992-08-17 08:55:12 +00001021
Barry Warsaw30695fa1996-12-12 23:32:31 +00001022 if (args == NULL || !PyTuple_Check(args) ||
1023 (n = PyTuple_Size(args)) < 1)
1024 {
Fred Drake137507e2000-06-01 02:02:46 +00001025 PyErr_SetString(PyExc_TypeError,
1026 "struct.pack requires at least one argument");
Guido van Rossum02975121992-08-17 08:55:12 +00001027 return NULL;
1028 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001029 format = PyTuple_GetItem(args, 0);
1030 if (!PyArg_Parse(format, "s", &fmt))
Guido van Rossum02975121992-08-17 08:55:12 +00001031 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001032 f = whichtable(&fmt);
1033 size = calcsize(fmt, f);
Guido van Rossum02975121992-08-17 08:55:12 +00001034 if (size < 0)
1035 return NULL;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001036 result = PyString_FromStringAndSize((char *)NULL, size);
Guido van Rossum02975121992-08-17 08:55:12 +00001037 if (result == NULL)
1038 return NULL;
1039
1040 s = fmt;
1041 i = 1;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001042 res = restart = PyString_AsString(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001043
1044 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001045 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001046 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001047 if ('0' <= c && c <= '9') {
1048 num = c - '0';
1049 while ('0' <= (c = *s++) && c <= '9')
1050 num = num*10 + (c - '0');
1051 if (c == '\0')
1052 break;
1053 }
1054 else
1055 num = 1;
1056
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001057 e = getentry(c, f);
1058 if (e == NULL)
1059 goto fail;
Guido van Rossumb9d338c1997-01-03 15:40:33 +00001060 nres = restart + align((int)(res-restart), c, e);
1061 /* Fill padd bytes with zeros */
1062 while (res < nres)
1063 *res++ = '\0';
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001064 if (num == 0 && c != 's')
1065 continue;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001066 do {
1067 if (c == 'x') {
1068 /* doesn't consume arguments */
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001069 memset(res, '\0', num);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001070 res += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001071 break;
Guido van Rossum02975121992-08-17 08:55:12 +00001072 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001073 if (i >= n) {
1074 PyErr_SetString(StructError,
1075 "insufficient arguments to pack");
1076 goto fail;
1077 }
1078 v = PyTuple_GetItem(args, i++);
1079 if (v == NULL)
1080 goto fail;
1081 if (c == 's') {
1082 /* num is string size, not repeat count */
1083 int n;
1084 if (!PyString_Check(v)) {
1085 PyErr_SetString(StructError,
1086 "argument for 's' must be a string");
1087 goto fail;
1088 }
1089 n = PyString_Size(v);
1090 if (n > num)
1091 n = num;
1092 if (n > 0)
1093 memcpy(res, PyString_AsString(v), n);
1094 if (n < num)
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001095 memset(res+n, '\0', num-n);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001096 res += num;
1097 break;
1098 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001099 else if (c == 'p') {
1100 /* num is string size + 1,
1101 to fit in the count byte */
1102 int n;
1103 num--; /* now num is max string size */
1104 if (!PyString_Check(v)) {
1105 PyErr_SetString(StructError,
1106 "argument for 'p' must be a string");
1107 goto fail;
1108 }
1109 n = PyString_Size(v);
1110 if (n > num)
1111 n = num;
1112 if (n > 0)
1113 memcpy(res+1, PyString_AsString(v), n);
1114 if (n < num)
1115 /* no real need, just to be nice */
1116 memset(res+1+n, '\0', num-n);
1117 *res++ = n; /* store the length byte */
1118 res += num;
1119 break;
1120 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001121 else {
1122 if (e->pack(res, v, e) < 0)
1123 goto fail;
1124 res += e->size;
1125 }
1126 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001127 }
1128
1129 if (i < n) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001130 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001131 "too many arguments for pack format");
Guido van Rossum02975121992-08-17 08:55:12 +00001132 goto fail;
1133 }
1134
1135 return result;
1136
1137 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001138 Py_DECREF(result);
Guido van Rossum02975121992-08-17 08:55:12 +00001139 return NULL;
1140}
1141
1142
Guido van Rossum9897f0f1997-12-21 06:46:20 +00001143static char unpack__doc__[] = "\
1144unpack(fmt, string) -> (v1, v2, ...)\n\
1145Unpack the string, containing packed C structure data, according\n\
1146to fmt. Requires len(string)==calcsize(fmt).\n\
Guido van Rossum414fd481997-12-19 04:24:24 +00001147See struct.__doc__ for more on format strings.";
Guido van Rossum02975121992-08-17 08:55:12 +00001148
Barry Warsaw30695fa1996-12-12 23:32:31 +00001149static PyObject *
Peter Schneider-Kamp41c36ff2000-07-10 12:29:26 +00001150struct_unpack(PyObject *self, PyObject *args)
Guido van Rossum02975121992-08-17 08:55:12 +00001151{
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001152 const formatdef *f, *e;
Guido van Rossum02975121992-08-17 08:55:12 +00001153 char *str, *start, *fmt, *s;
1154 char c;
Barry Warsawb9a781e1997-01-03 00:26:28 +00001155 int len, size, num;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001156 PyObject *res, *v;
Guido van Rossum02975121992-08-17 08:55:12 +00001157
Guido van Rossum43713e52000-02-29 13:59:29 +00001158 if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len))
Guido van Rossum02975121992-08-17 08:55:12 +00001159 return NULL;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001160 f = whichtable(&fmt);
1161 size = calcsize(fmt, f);
1162 if (size < 0)
1163 return NULL;
Guido van Rossum02975121992-08-17 08:55:12 +00001164 if (size != len) {
Barry Warsaw30695fa1996-12-12 23:32:31 +00001165 PyErr_SetString(StructError,
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001166 "unpack str size does not match format");
Guido van Rossum02975121992-08-17 08:55:12 +00001167 return NULL;
1168 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001169 res = PyList_New(0);
Guido van Rossum02975121992-08-17 08:55:12 +00001170 if (res == NULL)
1171 return NULL;
1172 str = start;
1173 s = fmt;
1174 while ((c = *s++) != '\0') {
Guido van Rossum730806d1998-04-10 22:27:42 +00001175 if (isspace((int)c))
Guido van Rossume20aef51997-08-26 20:39:54 +00001176 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001177 if ('0' <= c && c <= '9') {
1178 num = c - '0';
1179 while ('0' <= (c = *s++) && c <= '9')
1180 num = num*10 + (c - '0');
1181 if (c == '\0')
1182 break;
1183 }
1184 else
1185 num = 1;
1186
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001187 e = getentry(c, f);
1188 if (e == NULL)
1189 goto fail;
1190 str = start + align((int)(str-start), c, e);
Guido van Rossum3aa27fd1996-12-31 02:10:45 +00001191 if (num == 0 && c != 's')
1192 continue;
Guido van Rossum02975121992-08-17 08:55:12 +00001193
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001194 do {
1195 if (c == 'x') {
1196 str += num;
Guido van Rossum02975121992-08-17 08:55:12 +00001197 break;
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001198 }
1199 if (c == 's') {
1200 /* num is string size, not repeat count */
1201 v = PyString_FromStringAndSize(str, num);
1202 if (v == NULL)
1203 goto fail;
1204 str += num;
1205 num = 0;
1206 }
Guido van Rossum9eb671f1997-09-05 07:08:39 +00001207 else if (c == 'p') {
1208 /* num is string buffer size,
1209 not repeat count */
1210 int n = *(unsigned char*)str;
1211 /* first byte (unsigned) is string size */
1212 if (n >= num)
1213 n = num-1;
1214 v = PyString_FromStringAndSize(str+1, n);
1215 if (v == NULL)
1216 goto fail;
1217 str += num;
1218 num = 0;
1219 }
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001220 else {
1221 v = e->unpack(str, e);
1222 if (v == NULL)
1223 goto fail;
1224 str += e->size;
Guido van Rossum02975121992-08-17 08:55:12 +00001225 }
Barry Warsaw30695fa1996-12-12 23:32:31 +00001226 if (v == NULL || PyList_Append(res, v) < 0)
Guido van Rossum02975121992-08-17 08:55:12 +00001227 goto fail;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001228 Py_DECREF(v);
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001229 } while (--num > 0);
Guido van Rossum02975121992-08-17 08:55:12 +00001230 }
1231
Guido van Rossumf7e6b4b1996-12-31 01:41:25 +00001232 v = PyList_AsTuple(res);
1233 Py_DECREF(res);
1234 return v;
Guido van Rossum02975121992-08-17 08:55:12 +00001235
1236 fail:
Barry Warsaw30695fa1996-12-12 23:32:31 +00001237 Py_DECREF(res);
Guido van Rossum02975121992-08-17 08:55:12 +00001238 return NULL;
1239}
1240
Guido van Rossum90ddb7b1992-08-19 16:44:15 +00001241
Guido van Rossum02975121992-08-17 08:55:12 +00001242/* List of functions */
1243
Barry Warsaw30695fa1996-12-12 23:32:31 +00001244static PyMethodDef struct_methods[] = {
Guido van Rossum414fd481997-12-19 04:24:24 +00001245 {"calcsize", struct_calcsize, METH_VARARGS, calcsize__doc__},
1246 {"pack", struct_pack, METH_VARARGS, pack__doc__},
1247 {"unpack", struct_unpack, METH_VARARGS, unpack__doc__},
Guido van Rossum02975121992-08-17 08:55:12 +00001248 {NULL, NULL} /* sentinel */
1249};
1250
1251
1252/* Module initialization */
1253
Guido van Rossum3886bb61998-12-04 18:50:17 +00001254DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001255initstruct(void)
Guido van Rossum02975121992-08-17 08:55:12 +00001256{
Barry Warsaw30695fa1996-12-12 23:32:31 +00001257 PyObject *m, *d;
Guido van Rossum02975121992-08-17 08:55:12 +00001258
1259 /* Create the module and add the functions */
Guido van Rossum414fd481997-12-19 04:24:24 +00001260 m = Py_InitModule4("struct", struct_methods, struct__doc__,
1261 (PyObject*)NULL, PYTHON_API_VERSION);
Guido van Rossum02975121992-08-17 08:55:12 +00001262
1263 /* Add some symbolic constants to the module */
Barry Warsaw30695fa1996-12-12 23:32:31 +00001264 d = PyModule_GetDict(m);
Guido van Rossum0cb96de1997-10-01 04:29:29 +00001265 StructError = PyErr_NewException("struct.error", NULL, NULL);
1266 if (StructError == NULL)
1267 return;
Barry Warsaw30695fa1996-12-12 23:32:31 +00001268 PyDict_SetItemString(d, "error", StructError);
Guido van Rossum02975121992-08-17 08:55:12 +00001269}