Commit cf73a5cc authored by Maxime Perrotin's avatar Maxime Perrotin
Browse files

Replace the SWIG interface with ctypes

parent 74c99302
......@@ -34,6 +34,7 @@ LICENSE: LGPL - see LICENSE file
CHANGELOG:
1.2.0 - Align with dmt 1.2.0 (use ctypes in place of swig)
1.1.4 - Better support empty sequences
1.1.3 - Use Opengeode logo when simulating SDL systems
1.1.2 - Call manually the startup function of the SDL model
......
......@@ -16,7 +16,7 @@
__author__ = "Maxime Perrotin"
__license__ = "LGPLv3"
__version__ = "1.1.4"
__version__ = "1.2.0"
__url__ = "http://taste.tuxfamily.org"
import sys
......@@ -541,21 +541,21 @@ class asn1Editor(QTreeView):
raw = vn.toASN1ValueNotation(data).strip()
return raw if not use_dash else raw.replace('_', '-')
def to_asn1scc_swig(self, root, dest, ASN1Swig, sort, ASN1_AST):
''' Helper API function: read variable and set ASN.1 SWIG variable
def to_asn1scc_ctypes(self, root, dest, ASN1Mod, sort, ASN1_AST):
''' Helper API function: read variable and set ASN.1 Native variable
Inputs: root: select which variable to parse
dest: Swig variable (will be modified)
ASN1Swig: python module containing SWIG DV access
dest: Native ctypes variable (will be modified)
ASN1Mod: python module containing ctypes DV access
sort: root ASN.1 typename (with dash, no underscores)
ASN1_AST: full AST generated by ASN1SCC
'''
var = self.getVariable(root).popitem()[1]
vn.valueNotationToSwig(gser=None,
var=var,
dest=dest,
ASN1Swig=ASN1Swig,
sort=sort,
ASN1_AST=ASN1_AST)
vn.valueNotationToCTypes(gser=None,
var=var,
dest=dest,
ASN1Mod=ASN1Mod,
sort=sort,
ASN1_AST=ASN1_AST)
def sendTC(self):
......
......@@ -538,18 +538,18 @@ class sdlHandler(QObject):
# get internal variables, translate them to swig, and print them
setter_ptr = getattr(target, "_set_{}".format(var))
value_asn1 = target_state[idx]
try:
value_swig_ptr = int(value_asn1._ptr)
except TypeError:
# for some types, swig uses a proxy class, in which case the
# pointer is not in _ptr but in _ptr.this
value_swig_ptr = int(value_asn1._ptr.this)
value_ptr = ctypes.cast(value_swig_ptr,
ctypes.POINTER(ctypes.c_uint32))
setter_ptr(value_ptr)
# try:
# value_swig_ptr = int(value_asn1._ptr)
# except TypeError:
# # for some types, swig uses a proxy class, in which case the
# # pointer is not in _ptr but in _ptr.this
# value_swig_ptr = int(value_asn1._ptr.this)
# value_ptr = ctypes.cast(value_swig_ptr,
# ctypes.POINTER(ctypes.c_uint32))
# setter_ptr(value_ptr)
setter_ptr(value_asn1._ptr)
state_value = target_state[idx+1]
set_state = getattr(target, "_set_state")
print state_value
set_state(ctypes.c_char_p(state_value.encode('latin1')))
if target is self.dll:
self.check_state()
......@@ -566,9 +566,9 @@ class sdlHandler(QObject):
typename = sort.ReferencedTypeName.replace('-', '_')
asn1_type = self.proc.dataview[sort.ReferencedTypeName]
asn1_instance = getattr(ASN1, typename)()
# Fill up the SWIG ASN.1 instance
self.asn1_editor.to_asn1scc_swig(root=self.tree_items[var],
dest=asn1_instance, ASN1Swig=ASN1,
# Fill up the ASN.1 instance
self.asn1_editor.to_asn1scc_ctypes(root=self.tree_items[var],
dest=asn1_instance, ASN1Mod=ASN1,
sort=sort,
ASN1_AST=self.proc.dataview)
new_state.append(asn1_instance)
......@@ -599,17 +599,10 @@ class sdlHandler(QObject):
size = get_size()
# ctypes hint: don't use c_char_p except for text strings
get_value = getattr(self.dll, "{}_value".format(var))
get_value.restype = ctypes.POINTER(ctypes.c_char)
get_value.restype = ctypes.c_void_p # ctypes.POINTER(ctypes.c_char) # CHECKME
value = get_value()
swig_ptr = ASN1.DV.new_byte_SWIG_PTR(size)
for idx in xrange(size):
ASN1.DV.byte_SWIG_PTR_setitem(swig_ptr,
idx,
ord(value[idx])
if value[idx] else 0)
asn1_instance = getattr(ASN1, typename)()
setter = getattr(ASN1.DV, "SetDataFor_{}".format(typename))
setter(asn1_instance._ptr, swig_ptr)
asn1_instance.SetData(value)
gser = asn1_instance.GSER()
as_pyside = vn.fromValueNotationToPySide(var, gser)
self.asn1_editor.updateVariable(as_pyside,
......@@ -618,9 +611,6 @@ class sdlHandler(QObject):
# Add the SDL state to the new global state
complete_state.append(self.current_sdl_state)
# Update the SDL state in the global state panel
# state_as_pyside = vn.fromValueNotationToPySide('Current SDL state',
# '{}'.format(self.current_sdl_state.lower().replace('_', '-')
# .replace(UNICODE_SEP, '--')))
readable_state = self.current_sdl_state.replace(UNICODE_SEP, '--')
state_as_pyside = vn.fromValueNotationToPySide('Current SDL state',
readable_state.lower().replace('_', '-'))
......@@ -844,15 +834,7 @@ class sdlHandler(QObject):
# Send the TC
if param:
# Cast the SWIG type (ASN.1 Native format) to a ctypes pointer
try:
swig_ptr = int(param._ptr)
except TypeError:
# when swig uses a proxy class, pointer is in _ptr.this
swig_ptr = int(param._ptr.this)
param_ptr = ctypes.cast(swig_ptr,
ctypes.POINTER(ctypes.c_uint32))
tc_func_ptr(param_ptr)
tc_func_ptr(param._ptr)
else:
tc_func_ptr()
......@@ -888,25 +870,16 @@ class sdlHandler(QObject):
# Decode all input and output parameters and create native ASN.1 values
for spec, (val, size) in zip(procedure.fpar, params):
# Cast the void* to an array of unsigned bytes, knowing the size:
as_bytes = ctypes.cast(val,
ctypes.POINTER((ctypes.c_ubyte * (size / 8))))
# as_bytes = ctypes.cast(val,
# ctypes.POINTER((ctypes.c_ubyte * (size / 8))))
# Create native ASN.1 type
typename = spec['type'].ReferencedTypeName.replace('-', '_')
asn1_instance = getattr(ASN1, typename)()
asn1_instance = getattr(ASN1, typename)(ptr=val)
# Input parameters: copy the content in the ASN.1 Swig type
if spec['direction'] == 'in':
# Create a SWIG buffer of the same size:
swig_ptr = ASN1.DV.new_byte_SWIG_PTR(size / 8)
# Copy the content of the input buffer to the SWIG buffer:
for idx in xrange(size / 8):
ASN1.DV.byte_SWIG_PTR_setitem(swig_ptr,
idx,
as_bytes.contents[idx])
setter = getattr(ASN1.DV, "SetDataFor_{}".format(typename))
setter(asn1_instance._ptr, swig_ptr)
interface['in'].append((spec, asn1_instance))
else:
interface['out'].append((spec, as_bytes, asn1_instance))
interface['out'].append((spec, val, asn1_instance))
# make the function call
vdm_cls = getattr(procedure, "vdm_instance", None)
if vdm_cls:
......@@ -922,24 +895,27 @@ class sdlHandler(QObject):
outp = self.vdm.call_function(vdm_cls, name,
','.join(inp_as_vdm))
print "CALLED VDM. Result =", outp
#outp = outp.replace('[', '{').replace(']', '}')
spec, _, out_asn1_inst = interface['out'][0]
# assuming 1 return parameter
vdm_vn.vdm_to_swig(vdm=outp,
dest=out_asn1_inst,
sort=spec['type'],
ASN1_AST=self.proc.dataview,
ASN1Swig=ASN1)
vdm_vn.vdm_to_ctypes(vdm=outp,
dest=out_asn1_inst,
sort=spec['type'],
ASN1_AST=self.proc.dataview,
ASN1Mod=ASN1)
# Copy the OUT parameters back from SWIG to ctypes
for spec, as_bytes, asn1_instance in interface['out']:
# Create new SWIG byte array
swig_ptr = ASN1.DV.new_byte_SWIG_PTR(len(as_bytes.contents))
typename = spec['type'].ReferencedTypeName.replace('-', '_')
setter = getattr(ASN1.DV, "SetDataFor_{}".format(typename))
setter(swig_ptr, asn1_instance._ptr)
for idx in xrange(len(as_bytes.contents)):
as_bytes.contents[idx] = \
ASN1.DV.byte_SWIG_PTR_getitem(swig_ptr, idx)
# MP: with the new ctypes interface I think there is nothing to keep
# here. The vdm_to_ctypes should have filled the value directly...
# ! TESTME !
# for spec, val, asn1_instance in interface['out']:
# asn1_instance.SetData(val)
# # Create new SWIG byte array
# swig_ptr = ASN1.DV.new_byte_SWIG_PTR(len(as_bytes.contents))
# typename = spec['type'].ReferencedTypeName.replace('-', '_')
# setter = getattr(ASN1.DV, "SetDataFor_{}".format(typename))
# setter(swig_ptr, asn1_instance._ptr)
# for idx in xrange(len(as_bytes.contents)):
# as_bytes.contents[idx] = \
# ASN1.DV.byte_SWIG_PTR_getitem(swig_ptr, idx)
# Display the call on the MSC
inp, outp = [], []
for _, asn1_instance in interface['in']:
......
......@@ -154,12 +154,12 @@ def pyside_to_vdm(val, sort=None, ASN1_AST=None):
return result
def vdm_to_swig(vdm, dest, sort, ASN1Swig, ASN1_AST, var=None):
''' Parse a VDM value and fill a SWIG variable with it
def vdm_to_ctypes(vdm, dest, sort, ASN1Mod, ASN1_AST, var=None):
''' Parse a VDM value and fill a native ASN1/ctypes variable with it
Inputs:
vdm : input string in VDM value notation
dest : output SWIG instance to be filled
ASN1Swig : python module containing SWIG DV access
dest : output ctypes instance to be filled
ASN1Mod : python module containing SWIG DV access
sort: ASN1 typename, with dashes, no underscores
ASN1_AST : AST generated by ASN1SCC
var : optional already pyside-converted input string
......@@ -222,7 +222,7 @@ def vdm_to_swig(vdm, dest, sort, ASN1Swig, ASN1_AST, var=None):
# Get proper enum id from the ASN1SCC AST
enum_id = sort.type.EnumValues[
inp['Enum'].replace('_', '-')].EnumID
val = getattr(ASN1Swig.DV, enum_id)
val = getattr(ASN1Mod.DV, enum_id)
outp.Set(val)
elif kind == 'ChoiceType':
# choice : determinant is not set in the vdm string input
......@@ -267,7 +267,7 @@ def vdm_to_swig(vdm, dest, sort, ASN1Swig, ASN1_AST, var=None):
# child_name = inp['Choice']
# ch_ty = sort.type.Children[child_name.replace('_', '-')]
# enum_val = getattr(ASN1Swig.DV, ch_ty.EnumID)
# enum_val = getattr(ASN1Mod.DV, ch_ty.EnumID)
# outp.kind.Set(enum_val)
# rec(inp[child_name],
# getattr(outp,
......
......@@ -14,8 +14,8 @@
2) toASN1ValueNotation(val)
Does the reverse (from Qt widget to ASN.1 Value Notation/GSER)
3) valueNotationToSwig(gser, dest, sort, ASN1Swig, ASN1_AST, var=None)
Parse a Value Notation string and fill a SWIG instance with the values
3) valueNotationToCtypes(gser, dest, sort, ASN1Mod, ASN1_AST, var=None)
Parse a Value Notation string and fill a ctypes instance with the values
Copyright (c) 2012-2015 European Space Agency
......@@ -212,12 +212,12 @@ def toASN1ValueNotation(val):
return result
def valueNotationToSwig(gser, dest, sort, ASN1Swig, ASN1_AST, var=None):
''' Parse a GSER value and fill a SWIG variable with it
def valueNotationToCTypes(gser, dest, sort, ASN1Mod, ASN1_AST, var=None):
''' Parse a GSER value and fill a Native (ctypes) variable with it
Inputs:
gser : input GSER string
dest : output SWIG instance to be filled
ASN1Swig : python module containing SWIG DV access
dest : output ctypes instance to be filled
ASN1Mod : python module containing ctypes DV access
sort: ASN1 typename, with dashes, no underscores
ASN1_AST : AST generated by ASN1SCC
var : optional already pyside-converted GSER string
......@@ -227,7 +227,7 @@ def valueNotationToSwig(gser, dest, sort, ASN1Swig, ASN1_AST, var=None):
if var is None:
var = value.parseString(gser, True)[0]
def reach(field, orig, idx=True):
''' Helper: move swig pointer to the next field, and optionaly
''' Helper: move native pointer to the next field, and optionaly
index (if idx=True)
Inputs: field is a string with optional index (e.g. "a[0]")
orig is the swig pointer
......@@ -267,12 +267,12 @@ def valueNotationToSwig(gser, dest, sort, ASN1Swig, ASN1_AST, var=None):
# Get proper enum id from the ASN1SCC AST
enum_id = sort.type.EnumValues[
inp['Enum'].replace('_', '-')].EnumID
val = getattr(ASN1Swig.DV, enum_id)
val = getattr(ASN1Mod.DV, enum_id)
outp.Set(val)
elif 'Choice' in inp:
child_name = inp['Choice']
ch_ty = sort.type.Children[child_name.replace('_', '-')]
enum_val = getattr(ASN1Swig.DV, ch_ty.EnumID)
enum_val = getattr(ASN1Mod.DV, ch_ty.EnumID)
state = outp.GetState()
outp.kind.Set(enum_val)
outp.Reset(state)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment