runtime/typemapping.py
branchpython3
changeset 3771 67a0df6478b3
parent 3756 8db203310f68
child 3813 6f3e20690172
equal deleted inserted replaced
3770:1eee037e81f7 3771:67a0df6478b3
     2 # -*- coding: utf-8 -*-
     2 # -*- coding: utf-8 -*-
     3 #
     3 #
     4 # See COPYING.Runtime file for copyrights details.
     4 # See COPYING.Runtime file for copyrights details.
     5 #
     5 #
     6 
     6 
     7 import ctypes
       
     8 from ctypes import *
     7 from ctypes import *
     9 from datetime import timedelta as td
     8 from datetime import timedelta as td
    10 
       
    11 ctypes.pythonapi.PyUnicode_AsUTF8.argtypes = (ctypes.c_void_p,)
       
    12 ctypes.pythonapi.PyUnicode_AsUTF8.restype = ctypes.POINTER(ctypes.c_char)
       
    13 
       
    14 
     9 
    15 class IEC_STRING(Structure):
    10 class IEC_STRING(Structure):
    16     """
    11     """
    17     Must be changed according to changes in iec_types.h
    12     Must be changed according to changes in iec_types.h
    18     """
    13     """
    26     """
    21     """
    27     _fields_ = [("s", c_long),   # tv_sec
    22     _fields_ = [("s", c_long),   # tv_sec
    28                 ("ns", c_long)]  # tv_nsec
    23                 ("ns", c_long)]  # tv_nsec
    29 
    24 
    30 
    25 
    31 def _t(t, u=lambda x: x.value, p=lambda t, x: t(x)):
    26 def _t(t, u=lambda x: x.contents, p=lambda t, x: t(x)):
    32     return (t, u, p)
    27     return (t, u, p)
    33 
    28 
    34 
    29 
    35 def _ttime():
    30 def _ttime():
    36     return (IEC_TIME,
    31     return (IEC_TIME,
    37             lambda x: td(0, x.s, x.ns/1000.0),
    32             lambda x: td(0, x.contents.s, x.contents.ns/1000.0),
    38             lambda t, x: t(x.days * 24 * 3600 + x.seconds, x.microseconds*1000))
    33             lambda t, x: t(x.days * 24 * 3600 + x.seconds, x.microseconds*1000))
    39 
    34 
    40 
    35 
    41 SameEndianessTypeTranslator = {
    36 SameEndianessTypeTranslator = {
    42     "BOOL":       _t(c_uint8, lambda x: x.value != 0),
    37     "BOOL":       _t(c_uint8, lambda x: bool(x.contents)),
    43     "STEP":       _t(c_uint8),
    38     "STEP":       _t(c_uint8),
    44     "TRANSITION": _t(c_uint8),
    39     "TRANSITION": _t(c_uint8),
    45     "ACTION":     _t(c_uint8),
    40     "ACTION":     _t(c_uint8),
    46     "SINT":       _t(c_int8),
    41     "SINT":       _t(c_int8),
    47     "USINT":      _t(c_uint8),
    42     "USINT":      _t(c_uint8),
    48     "BYTE":       _t(c_uint8),
    43     "BYTE":       _t(c_uint8),
    49     "STRING":     (IEC_STRING,
    44     "STRING":     (IEC_STRING,
    50                    lambda x: x.body[:x.len],
    45                    lambda x: x.contents.body[:x.contents.len],
    51                    lambda t, x: t(len(x), x)),
    46                    lambda t, x: t(len(x), x)),
    52     "INT":        _t(c_int16),
    47     "INT":        _t(c_int16),
    53     "UINT":       _t(c_uint16),
    48     "UINT":       _t(c_uint16),
    54     "WORD":       _t(c_uint16),
    49     "WORD":       _t(c_uint16),
    55     "DINT":       _t(c_int32),
    50     "DINT":       _t(c_int32),
    78 
    73 
    79 def UnpackDebugBuffer(buff, indexes):
    74 def UnpackDebugBuffer(buff, indexes):
    80     res = []
    75     res = []
    81     buffoffset = 0
    76     buffoffset = 0
    82     buffsize = len(buff)
    77     buffsize = len(buff)
    83     buffptr = cast(ctypes.pythonapi.PyString_AsString(id(buff)), c_void_p).value
    78     buffptr = cast(cast(buff, c_char_p), c_void_p).value
    84     for iectype in indexes:
    79     for iectype in indexes:
    85         c_type, unpack_func, _pack_func = \
    80         c_type, unpack_func, _pack_func = TypeTranslator.get(iectype,
    86             TypeTranslator.get(iectype, (None, None, None))
    81                                                              (None, None, None))
    87 
    82 
    88         cursor = c_void_p(buffptr + buffoffset)
    83         cursor = c_void_p(buffptr + buffoffset)
    89         if iectype == "STRING":
    84         if iectype == "STRING":
    90             # strlen is stored in c_uint8 and sizeof(c_uint8) is 1
    85             # strlen is stored in c_uint8 and sizeof(c_uint8) is 1
    91             # first check we can read size
    86             # first check we can read size
    95                 return None
    90                 return None
    96         else:
    91         else:
    97             size = sizeof(c_type)
    92             size = sizeof(c_type)
    98 
    93 
    99         if c_type is not None and (buffoffset + size) <= buffsize:
    94         if c_type is not None and (buffoffset + size) <= buffsize:
   100             value = unpack_func(cast(cursor,
    95             n = cast(cursor, POINTER(c_type))
   101                                      POINTER(c_type)).contents)
    96             value = unpack_func(n)
       
    97             if iectype not in ["BOOL", "DATE", "DT", "STRING", "TIME", "TOD"]:
       
    98                 value = value.value
       
    99             elif iectype == "STRING":
       
   100                 value = value.decode()
   102             buffoffset += size
   101             buffoffset += size
   103             res.append(value)
   102             res.append(value)
   104         else:
   103         else:
   105             return None
   104             return None
   106     if buffoffset and buffoffset == buffsize:
   105     if buffoffset and buffoffset == buffsize: