Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 1 | """ |
| 2 | Functions to convert between Python values and C structs. |
| 3 | Python strings are used to hold the data representing the C struct |
| 4 | and also as format strings to describe the layout of data in the C struct. |
| 5 | |
| 6 | The optional first format char indicates byte order, size and alignment: |
| 7 | @: native order, size & alignment (default) |
| 8 | =: native order, std. size & alignment |
| 9 | <: little-endian, std. size & alignment |
| 10 | >: big-endian, std. size & alignment |
| 11 | !: same as > |
| 12 | |
| 13 | The remaining chars indicate types of args and must match exactly; |
| 14 | these can be preceded by a decimal repeat count: |
| 15 | x: pad byte (no data); c:char; b:signed byte; B:unsigned byte; |
| 16 | h:short; H:unsigned short; i:int; I:unsigned int; |
| 17 | l:long; L:unsigned long; f:float; d:double. |
| 18 | Special cases (preceding decimal count indicates length): |
| 19 | s:string (array of char); p: pascal string (with count byte). |
| 20 | Special case (only available in native format): |
| 21 | P:an integer type that is wide enough to hold a pointer. |
| 22 | Special case (not in native mode unless 'long long' in platform C): |
| 23 | q:long long; Q:unsigned long long |
| 24 | Whitespace between formats is ignored. |
| 25 | |
| 26 | The variable struct.error is an exception raised on errors. |
| 27 | """ |
Guido van Rossum | 2e6a4b3 | 2007-05-04 19:56:22 +0000 | [diff] [blame] | 28 | |
| 29 | # XXX Move the bytes and str8 casts into the _struct module |
| 30 | |
| 31 | __version__ = '3.0' |
| 32 | |
Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 33 | |
Guido van Rossum | e625fd5 | 2007-05-27 09:19:04 +0000 | [diff] [blame] | 34 | from _struct import Struct as _Struct, error |
| 35 | |
| 36 | class Struct(_Struct): |
| 37 | def __init__(self, fmt): |
| 38 | if isinstance(fmt, str): |
| 39 | fmt = str8(fmt) |
| 40 | _Struct.__init__(self, fmt) |
Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 41 | |
| 42 | _MAXCACHE = 100 |
| 43 | _cache = {} |
| 44 | |
| 45 | def _compile(fmt): |
| 46 | # Internal: compile struct pattern |
| 47 | if len(_cache) >= _MAXCACHE: |
| 48 | _cache.clear() |
Guido van Rossum | e625fd5 | 2007-05-27 09:19:04 +0000 | [diff] [blame] | 49 | s = Struct(fmt) |
Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 50 | _cache[fmt] = s |
| 51 | return s |
| 52 | |
| 53 | def calcsize(fmt): |
| 54 | """ |
| 55 | Return size of C struct described by format string fmt. |
| 56 | See struct.__doc__ for more on format strings. |
| 57 | """ |
| 58 | try: |
| 59 | o = _cache[fmt] |
| 60 | except KeyError: |
| 61 | o = _compile(fmt) |
| 62 | return o.size |
| 63 | |
| 64 | def pack(fmt, *args): |
| 65 | """ |
| 66 | Return string containing values v1, v2, ... packed according to fmt. |
| 67 | See struct.__doc__ for more on format strings. |
| 68 | """ |
| 69 | try: |
| 70 | o = _cache[fmt] |
| 71 | except KeyError: |
| 72 | o = _compile(fmt) |
Guido van Rossum | 2e6a4b3 | 2007-05-04 19:56:22 +0000 | [diff] [blame] | 73 | return bytes(o.pack(*args)) |
Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 74 | |
Thomas Wouters | 73e5a5b | 2006-06-08 15:35:45 +0000 | [diff] [blame] | 75 | def pack_into(fmt, buf, offset, *args): |
Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 76 | """ |
Thomas Wouters | 0e3f591 | 2006-08-11 14:57:12 +0000 | [diff] [blame] | 77 | Pack the values v1, v2, ... according to fmt, write |
Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 78 | the packed bytes into the writable buffer buf starting at offset. |
| 79 | See struct.__doc__ for more on format strings. |
| 80 | """ |
| 81 | try: |
| 82 | o = _cache[fmt] |
| 83 | except KeyError: |
| 84 | o = _compile(fmt) |
Guido van Rossum | e625fd5 | 2007-05-27 09:19:04 +0000 | [diff] [blame] | 85 | o.pack_into(buf, offset, *args) |
Thomas Wouters | 477c8d5 | 2006-05-27 19:21:47 +0000 | [diff] [blame] | 86 | |
| 87 | def unpack(fmt, s): |
| 88 | """ |
| 89 | Unpack the string, containing packed C structure data, according |
| 90 | to fmt. Requires len(string)==calcsize(fmt). |
| 91 | See struct.__doc__ for more on format strings. |
| 92 | """ |
| 93 | try: |
| 94 | o = _cache[fmt] |
| 95 | except KeyError: |
| 96 | o = _compile(fmt) |
| 97 | return o.unpack(s) |
| 98 | |
| 99 | def unpack_from(fmt, buf, offset=0): |
| 100 | """ |
| 101 | Unpack the buffer, containing packed C structure data, according to |
| 102 | fmt starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt). |
| 103 | See struct.__doc__ for more on format strings. |
| 104 | """ |
| 105 | try: |
| 106 | o = _cache[fmt] |
| 107 | except KeyError: |
| 108 | o = _compile(fmt) |
| 109 | return o.unpack_from(buf, offset) |