Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 22 additions & 36 deletions pycrate_asn1c/asnobj.py
Original file line number Diff line number Diff line change
Expand Up @@ -6325,7 +6325,7 @@ def _to_asn1(self, val):
elif self.REPR_VAL == b'N' and val[1] == 10:
return '%iE%i' % (val[0], val[2])
else:
return '{mantissa %i, base %i, exponent %i}'.format(*val)
return '{mantissa %i, base %i, exponent %i}' % (*val,)

class ENUM(ASN1Obj):
__doc__ = """
Expand Down Expand Up @@ -6430,7 +6430,7 @@ def _to_asn1(self, val):
# an ASN.1 compliant value
if self.REPR_VAL == b'H' and not val[1]%4:
# hstr
hstr = hex(val[0])[2:]
hstr = hex(val[0])[2:].upper()
if 4*len(hstr) < val[1]:
hstr = (val[1]//4 - len(hstr))*'0' + hstr
return '\'%s\'H' % hstr
Expand Down Expand Up @@ -6481,21 +6481,15 @@ def _to_asn1(self, val):
# to be applied to an internal single value `val' to get
# an ASN.1 compliant value
if isinstance(val, tuple):
if self.REPR_VAL == b'H':
return '\'%s\'H' % hexlify(val[0]).upper()
else:
bstr = bin(bytes_to_uint(val[0], len(val[0])))[2:]
if len(bstr) < 8*len(val[0]):
bstr = (8*len(val[0]) - len(bstr))*'0' + bstr
return '\'%s\'B' % bstr
val = val[0]
if self.REPR_VAL == b'H':
return '\'%s\'H' % hexlify(val).decode('ascii').upper()
else:
if self.REPR_VAL == b'H':
return '\'%s\'H' % hexlify(val).upper()
else:
bstr = bin(bytes_to_uint(val, len(val)))[2:]
if len(bstr) < 8*len(val):
bstr = (8*len(val) - len(bstr))*'0' + bstr
return '\'%s\'B' % bstr
valbits = 8*len(val)
bstr = bin(bytes_to_uint(val, valbits))[2:]
if len(bstr) < valbits:
bstr = (valbits - len(bstr))*'0' + bstr
return '\'%s\'B' % bstr


_String_docstring = """
Expand Down Expand Up @@ -6701,7 +6695,7 @@ class TIME_UTC(_Time):
__doc__ = """
ASN.1 basic type UTCTime object

single value: Python 7-tuple of int (AA, MM, DD, HH, MM, [SS,] Z),
single value: Python 7-tuple of str (AA, MM, DD, HH, MM, [SS,] Z),
SS is optional, hence 6th element can be None
Z corresponds to the UTC decay

Expand All @@ -6715,22 +6709,18 @@ class TIME_UTC(_Time):
def _to_asn1(self, val):
# to be applied to an internal single value `val' to get
# an ASN.1 compliant value
ret = '%.2i%.2i%.2i%.2i%.2i' % val[:5]
ret = ''.join(val[:5])
if val[5] is not None:
ret += '%.2i' % val[5]
if val[6] == 0:
ret += 'Z'
elif val[6] > 0:
ret += '+%.4i' % val[6]
else:
ret += '%.4i' % val[6]
ret += val[5]
if val[6] is not None:
ret += val[6]
return ret

class TIME_GEN(_Time):
__doc__ = """
ASN.1 basic type GeneralizedTime object

single value: Python 8-tuple of int
single value: Python 8-tuple of str
(AAAA, MM, DD, HH, [MM, [SS, [FFFF,]]], Z),
MM, SS and FFFF are optional, hence 5th, 6th and 7th element can be None
Z corresponds to the UTC decay and is optional, hence 8th element
Expand All @@ -6746,19 +6736,15 @@ class TIME_GEN(_Time):
def _to_asn1(self, val):
# to be applied to an internal single value `val' to get
# an ASN.1 compliant value
ret = '%.4i%.2i%.2i%.2i' % val[:4]
ret = ''.join(val[:4])
if val[4] is not None:
ret += '%.2i' % val[4]
ret += val[4]
if val[5] is not None:
ret += '%.2i' % val[5]
ret += val[5]
if val[6] is not None:
ret += '.%.4i' % val[6]
if val[7] == 0:
ret += 'Z'
elif val[7] > 0:
ret += '+%.4i' % val[7]
elif val[7] < 0:
ret += '%.4i' % val[7]
ret += '.' + val[6]
if val[7] is not None:
ret += val[7]
return ret

#///////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\#
Expand Down
47 changes: 46 additions & 1 deletion test/test_pycrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,52 @@ def test_asn1c_imports(self):
with open('./test/res/Imports.json') as inj, \
open('./test_asn_todelete/Imports.json') as outj:
self.assertListEqual(list(inj), list(outj))
print('[<>] all ASN.1 modules loaded successfully')
GLOBAL.clear()

# asn1c _to_asn1()
def test_asn1c_to_asn1(self):
print('[<>] testing pycrate_asn1c _to_asn1() methods')
# compile and generate the Hardcore ASN.1 module
with open('./test/res/Hardcore.asn', 'r') as fd:
asntext = fd.read()
compile_text(asntext)

# check various types
hc = GLOBAL.MOD['HardcoreSyntax']
hc['bs01'].REPR_VAL = b'H' # force BIT STRING hex repr
hc['os01'].REPR_VAL = b'H' # force OCTET STRING hex repr
hc['real00'].REPR_VAL = b'N' # force REAL numeric repr
hc['real01'].REPR_VAL = b'N' # force REAL numeric repr
hc['real02'].REPR_VAL = b'N' # force REAL numeric repr
for var, expect in {
'null00': 'NULL',
'bool00': 'TRUE',
'int00': '-1',
'int01': '0',
'int02': '1024',
'real00': '25386E9', # 25.386e12
'real01': '1024E-56',
'real02': '-10000E1', # -100.00e3
'real03': '{mantissa 25386, base 10, exponent 9}',
'real04': '{mantissa 3, base 2, exponent -128}',
'enum01': 'eX',
'bs00': '\'00111110000110011101101110001101\'B',
'bs01': '\'0123456789ABCDEF\'H',
'os00': '\'00111110000110011101101110001101\'B',
'os01': '\'0123456789ABCDEF\'H',
'oid01': '{0 0 13 28 59}',
'roid01': '{28 59 2569 6533125}',
'utim00': '1606251200Z',
'utim01': '160625123055-0230',
'gtim00': '2016062512+0200',
'gtim01': '20160625124539.5290',
'gtim02': '20160625124539.5290Z', # fractional always '.'
# TODO: should _String._to_val() be doubling quotes or returning as-is?
'str00': '"abcd """"ABCD"""" efgh """"EFGH"""" \'test\' OK; go-there !"',
}.items():
print(f'[<>] check {var}={expect}')
self.assertEqual(hc[var]._to_asn1(hc[var]._val), expect)

GLOBAL.clear()

# asn1rt
Expand Down
Loading