runtime/typemapping.py
changeset 1902 2b7e2db31d81
parent 1881 091005ec69c4
child 1973 cc7a46953471
equal deleted inserted replaced
1901:e8cf68d69447 1902:2b7e2db31d81
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 #
       
     4 # See COPYING.Runtime file for copyrights details.
       
     5 #
       
     6 
       
     7 from __future__ import absolute_import
       
     8 import ctypes
       
     9 from ctypes import *
       
    10 from datetime import timedelta as td
       
    11 
       
    12 ctypes.pythonapi.PyString_AsString.argtypes = (ctypes.c_void_p,)
       
    13 ctypes.pythonapi.PyString_AsString.restype = ctypes.POINTER(ctypes.c_char)
       
    14 
       
    15 
       
    16 class IEC_STRING(Structure):
       
    17     """
       
    18     Must be changed according to changes in iec_types.h
       
    19     """
       
    20     _fields_ = [("len", c_uint8),
       
    21                 ("body", c_char * 126)]
       
    22 
       
    23 
       
    24 class IEC_TIME(Structure):
       
    25     """
       
    26     Must be changed according to changes in iec_types.h
       
    27     """
       
    28     _fields_ = [("s", c_long),   # tv_sec
       
    29                 ("ns", c_long)]  # tv_nsec
       
    30 
       
    31 
       
    32 def _t(t, u=lambda x: x.value, p=lambda t, x: t(x)):
       
    33     return (t, u, p)
       
    34 
       
    35 
       
    36 def _ttime():
       
    37     return (IEC_TIME,
       
    38             lambda x: td(0, x.s, x.ns/1000),
       
    39             lambda t, x: t(x.days * 24 * 3600 + x.seconds, x.microseconds*1000))
       
    40 
       
    41 
       
    42 SameEndianessTypeTranslator = {
       
    43     "BOOL":       _t(c_uint8, lambda x: x.value != 0),
       
    44     "STEP":       _t(c_uint8),
       
    45     "TRANSITION": _t(c_uint8),
       
    46     "ACTION":     _t(c_uint8),
       
    47     "SINT":       _t(c_int8),
       
    48     "USINT":      _t(c_uint8),
       
    49     "BYTE":       _t(c_uint8),
       
    50     "STRING":     (IEC_STRING,
       
    51                    lambda x: x.body[:x.len],
       
    52                    lambda t, x: t(len(x), x)),
       
    53     "INT":        _t(c_int16),
       
    54     "UINT":       _t(c_uint16),
       
    55     "WORD":       _t(c_uint16),
       
    56     "DINT":       _t(c_int32),
       
    57     "UDINT":      _t(c_uint32),
       
    58     "DWORD":      _t(c_uint32),
       
    59     "LINT":       _t(c_int64),
       
    60     "ULINT":      _t(c_uint64),
       
    61     "LWORD":      _t(c_uint64),
       
    62     "REAL":       _t(c_float),
       
    63     "LREAL":      _t(c_double),
       
    64     "TIME":       _ttime(),
       
    65     "TOD":        _ttime(),
       
    66     "DATE":       _ttime(),
       
    67     "DT":         _ttime(),
       
    68     }
       
    69 
       
    70 SwapedEndianessTypeTranslator = {
       
    71     # TODO
       
    72     }
       
    73 
       
    74 TypeTranslator = SameEndianessTypeTranslator
       
    75 
       
    76 # Construct debugger natively supported types
       
    77 DebugTypesSize = dict([(key, sizeof(t)) for key, (t, p, u) in SameEndianessTypeTranslator.iteritems() if t is not None])
       
    78 
       
    79 
       
    80 def UnpackDebugBuffer(buff, indexes):
       
    81     res = []
       
    82     buffoffset = 0
       
    83     buffsize = len(buff)
       
    84     buffptr = cast(ctypes.pythonapi.PyString_AsString(id(buff)), c_void_p).value
       
    85     for iectype in indexes:
       
    86         c_type, unpack_func, _pack_func = \
       
    87             TypeTranslator.get(iectype, (None, None, None))
       
    88         if c_type is not None and buffoffset < buffsize:
       
    89             cursor = c_void_p(buffptr + buffoffset)
       
    90             value = unpack_func(cast(cursor,
       
    91                                      POINTER(c_type)).contents)
       
    92             buffoffset += sizeof(c_type) if iectype != "STRING" else len(value)+1
       
    93             res.append(value)
       
    94         else:
       
    95             break
       
    96     if buffoffset and buffoffset == buffsize:
       
    97         return res
       
    98     return None