| """ |
| Functions to convert between Python values and C structs. |
| Python strings are used to hold the data representing the C struct |
| and also as format strings to describe the layout of data in the C struct. |
| |
| The optional first format char indicates byte order, size and alignment: |
| @: native order, size & alignment (default) |
| =: native order, std. size & alignment |
| <: little-endian, std. size & alignment |
| >: big-endian, std. size & alignment |
| !: same as > |
| |
| The remaining chars indicate types of args and must match exactly; |
| these can be preceded by a decimal repeat count: |
| x: pad byte (no data); c:char; b:signed byte; B:unsigned byte; |
| h:short; H:unsigned short; i:int; I:unsigned int; |
| l:long; L:unsigned long; f:float; d:double. |
| Special cases (preceding decimal count indicates length): |
| s:string (array of char); p: pascal string (with count byte). |
| Special case (only available in native format): |
| P:an integer type that is wide enough to hold a pointer. |
| Special case (not in native mode unless 'long long' in platform C): |
| q:long long; Q:unsigned long long |
| Whitespace between formats is ignored. |
| |
| The variable struct.error is an exception raised on errors. |
| """ |
| |
| # XXX Move the bytes and str8 casts into the _struct module |
| |
| __version__ = '3.0' |
| |
| |
| from _struct import Struct as _Struct, error |
| |
| class Struct(_Struct): |
| def __init__(self, fmt): |
| if isinstance(fmt, str): |
| fmt = str8(fmt) |
| _Struct.__init__(self, fmt) |
| |
| _MAXCACHE = 100 |
| _cache = {} |
| |
| def _compile(fmt): |
| # Internal: compile struct pattern |
| if len(_cache) >= _MAXCACHE: |
| _cache.clear() |
| s = Struct(fmt) |
| _cache[fmt] = s |
| return s |
| |
| def calcsize(fmt): |
| """ |
| Return size of C struct described by format string fmt. |
| See struct.__doc__ for more on format strings. |
| """ |
| try: |
| o = _cache[fmt] |
| except KeyError: |
| o = _compile(fmt) |
| return o.size |
| |
| def pack(fmt, *args): |
| """ |
| Return string containing values v1, v2, ... packed according to fmt. |
| See struct.__doc__ for more on format strings. |
| """ |
| try: |
| o = _cache[fmt] |
| except KeyError: |
| o = _compile(fmt) |
| return bytes(o.pack(*args)) |
| |
| def pack_into(fmt, buf, offset, *args): |
| """ |
| Pack the values v1, v2, ... according to fmt, write |
| the packed bytes into the writable buffer buf starting at offset. |
| See struct.__doc__ for more on format strings. |
| """ |
| try: |
| o = _cache[fmt] |
| except KeyError: |
| o = _compile(fmt) |
| o.pack_into(buf, offset, *args) |
| |
| def unpack(fmt, s): |
| """ |
| Unpack the string, containing packed C structure data, according |
| to fmt. Requires len(string)==calcsize(fmt). |
| See struct.__doc__ for more on format strings. |
| """ |
| try: |
| o = _cache[fmt] |
| except KeyError: |
| o = _compile(fmt) |
| return o.unpack(s) |
| |
| def unpack_from(fmt, buf, offset=0): |
| """ |
| Unpack the buffer, containing packed C structure data, according to |
| fmt starting at offset. Requires len(buffer[offset:]) >= calcsize(fmt). |
| See struct.__doc__ for more on format strings. |
| """ |
| try: |
| o = _cache[fmt] |
| except KeyError: |
| o = _compile(fmt) |
| return o.unpack_from(buf, offset) |