| 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 | """
|
|---|
| 28 | __version__ = '0.1'
|
|---|
| 29 |
|
|---|
| 30 | from _struct import Struct, error
|
|---|
| 31 |
|
|---|
| 32 | _MAXCACHE = 100
|
|---|
| 33 | _cache = {}
|
|---|
| 34 |
|
|---|
| 35 | def _compile(fmt):
|
|---|
| 36 | # Internal: compile struct pattern
|
|---|
| 37 | if len(_cache) >= _MAXCACHE:
|
|---|
| 38 | _cache.clear()
|
|---|
| 39 | s = Struct(fmt)
|
|---|
| 40 | _cache[fmt] = s
|
|---|
| 41 | return s
|
|---|
| 42 |
|
|---|
| 43 | def calcsize(fmt):
|
|---|
| 44 | """
|
|---|
| 45 | Return size of C struct described by format string fmt.
|
|---|
| 46 | See struct.__doc__ for more on format strings.
|
|---|
| 47 | """
|
|---|
| 48 | try:
|
|---|
| 49 | o = _cache[fmt]
|
|---|
| 50 | except KeyError:
|
|---|
| 51 | o = _compile(fmt)
|
|---|
| 52 | return o.size
|
|---|
| 53 |
|
|---|
| 54 | def pack(fmt, *args):
|
|---|
| 55 | """
|
|---|
| 56 | Return string containing values v1, v2, ... packed according to fmt.
|
|---|
| 57 | See struct.__doc__ for more on format strings.
|
|---|
| 58 | """
|
|---|
| 59 | try:
|
|---|
| 60 | o = _cache[fmt]
|
|---|
| 61 | except KeyError:
|
|---|
| 62 | o = _compile(fmt)
|
|---|
| 63 | return o.pack(*args)
|
|---|
| 64 |
|
|---|
| 65 | def pack_into(fmt, buf, offset, *args):
|
|---|
| 66 | """
|
|---|
| 67 | Pack the values v1, v2, ... according to fmt, write
|
|---|
| 68 | the packed bytes into the writable buffer buf starting at offset.
|
|---|
| 69 | See struct.__doc__ for more on format strings.
|
|---|
| 70 | """
|
|---|
| 71 | try:
|
|---|
| 72 | o = _cache[fmt]
|
|---|
| 73 | except KeyError:
|
|---|
| 74 | o = _compile(fmt)
|
|---|
| 75 | return o.pack_into(buf, offset, *args)
|
|---|
| 76 |
|
|---|
| 77 | def unpack(fmt, s):
|
|---|
| 78 | """
|
|---|
| 79 | Unpack the string, containing packed C structure data, according
|
|---|
| 80 | to fmt. Requires len(string)==calcsize(fmt).
|
|---|
| 81 | See struct.__doc__ for more on format strings.
|
|---|
| 82 | """
|
|---|
| 83 | try:
|
|---|
| 84 | o = _cache[fmt]
|
|---|
| 85 | except KeyError:
|
|---|
| 86 | o = _compile(fmt)
|
|---|
| 87 | return o.unpack(s)
|
|---|
| 88 |
|
|---|
| 89 | def unpack_from(fmt, buf, offset=0):
|
|---|
| 90 | """
|
|---|
| 91 | Unpack the buffer, containing packed C structure data, according to
|
|---|
| 92 | fmt starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt).
|
|---|
| 93 | See struct.__doc__ for more on format strings.
|
|---|
| 94 | """
|
|---|
| 95 | try:
|
|---|
| 96 | o = _cache[fmt]
|
|---|
| 97 | except KeyError:
|
|---|
| 98 | o = _compile(fmt)
|
|---|
| 99 | return o.unpack_from(buf, offset)
|
|---|