Edouard@592: #!/usr/bin/env python Edouard@592: # -*- coding: utf-8 -*- Edouard@592: # andrej@1667: # See COPYING.Runtime file for copyrights details. Edouard@592: # andrej@1881: andrej@1881: from __future__ import absolute_import Edouard@1433: import ctypes andrej@1783: from ctypes import * andrej@1783: from datetime import timedelta as td andrej@1783: Edouard@1433: ctypes.pythonapi.PyString_AsString.argtypes = (ctypes.c_void_p,) Edouard@1433: ctypes.pythonapi.PyString_AsString.restype = ctypes.POINTER(ctypes.c_char) Edouard@1433: Edouard@1433: Edouard@592: class IEC_STRING(Structure): Edouard@592: """ Edouard@592: Must be changed according to changes in iec_types.h Edouard@592: """ Edouard@592: _fields_ = [("len", c_uint8), Edouard@1433: ("body", c_char * 126)] Edouard@592: andrej@1736: Edouard@592: class IEC_TIME(Structure): Edouard@592: """ Edouard@592: Must be changed according to changes in iec_types.h Edouard@592: """ andrej@1737: _fields_ = [("s", c_long), # tv_sec andrej@1737: ("ns", c_long)] # tv_nsec Edouard@592: andrej@1736: andrej@1835: def _t(t, u=lambda x: x.value, p=lambda t, x: t(x)): andrej@1835: return (t, u, p) andrej@1736: andrej@1736: andrej@1835: def _ttime(): andrej@1835: return (IEC_TIME, surkovsv93@1963: lambda x: td(0, x.s, x.ns/1000.0), andrej@1835: lambda t, x: t(x.days * 24 * 3600 + x.seconds, x.microseconds*1000)) Edouard@592: andrej@1749: Edouard@592: SameEndianessTypeTranslator = { andrej@1774: "BOOL": _t(c_uint8, lambda x: x.value != 0), andrej@1739: "STEP": _t(c_uint8), andrej@1739: "TRANSITION": _t(c_uint8), andrej@1739: "ACTION": _t(c_uint8), andrej@1739: "SINT": _t(c_int8), andrej@1739: "USINT": _t(c_uint8), andrej@1739: "BYTE": _t(c_uint8), andrej@1739: "STRING": (IEC_STRING, andrej@1740: lambda x: x.body[:x.len], andrej@1740: lambda t, x: t(len(x), x)), andrej@1739: "INT": _t(c_int16), andrej@1739: "UINT": _t(c_uint16), andrej@1739: "WORD": _t(c_uint16), andrej@1739: "DINT": _t(c_int32), andrej@1739: "UDINT": _t(c_uint32), andrej@1739: "DWORD": _t(c_uint32), andrej@1739: "LINT": _t(c_int64), andrej@1739: "ULINT": _t(c_uint64), andrej@1739: "LWORD": _t(c_uint64), andrej@1739: "REAL": _t(c_float), andrej@1739: "LREAL": _t(c_double), andrej@1739: "TIME": _ttime(), andrej@1739: "TOD": _ttime(), andrej@1739: "DATE": _ttime(), andrej@1739: "DT": _ttime(), Edouard@1433: } Edouard@592: Edouard@592: SwapedEndianessTypeTranslator = { andrej@1733: # TODO Edouard@1433: } Edouard@592: andrej@1742: TypeTranslator = SameEndianessTypeTranslator Edouard@1075: Edouard@592: # Construct debugger natively supported types andrej@1758: DebugTypesSize = dict([(key, sizeof(t)) for key, (t, p, u) in SameEndianessTypeTranslator.iteritems() if t is not None]) Edouard@592: andrej@1736: Edouard@1433: def UnpackDebugBuffer(buff, indexes): andrej@1758: res = [] Edouard@1433: buffoffset = 0 Edouard@1433: buffsize = len(buff) andrej@1740: buffptr = cast(ctypes.pythonapi.PyString_AsString(id(buff)), c_void_p).value Edouard@1433: for iectype in indexes: andrej@1847: c_type, unpack_func, _pack_func = \ andrej@1767: TypeTranslator.get(iectype, (None, None, None)) Edouard@3395: Edouard@3395: cursor = c_void_p(buffptr + buffoffset) Edouard@3395: if iectype == "STRING": Edouard@3395: # strlen is stored in c_uint8 and sizeof(c_uint8) is 1 Edouard@3395: # first check we can read size Edouard@3395: if (buffoffset + 1) <= buffsize: Edouard@3395: size = 1 + cast(cursor,POINTER(c_type)).contents.len Edouard@3395: else: Edouard@3395: return None Edouard@3395: else: Edouard@3395: size = sizeof(c_type) Edouard@3395: Edouard@3395: if c_type is not None and (buffoffset + size) <= buffsize: andrej@1747: value = unpack_func(cast(cursor, andrej@1768: POINTER(c_type)).contents) Edouard@3395: buffoffset += size Edouard@1433: res.append(value) Edouard@1075: else: Edouard@2741: return None Edouard@1433: if buffoffset and buffoffset == buffsize: Edouard@1075: return res Edouard@1075: return None