Enumerated support including *_ws methods.
This commit is contained in:
parent
ecddbd4d23
commit
07a8b63d1a
|
@ -1529,6 +1529,65 @@ Specific attribute:
|
||||||
def _to_jval(self):
|
def _to_jval(self):
|
||||||
return self._val
|
return self._val
|
||||||
|
|
||||||
|
###
|
||||||
|
# conversion between internal value and ASN.1 OER/COER encoding
|
||||||
|
###
|
||||||
|
|
||||||
|
def _get_index(self):
|
||||||
|
try:
|
||||||
|
ind = self._cont[self._val]
|
||||||
|
except KeyError:
|
||||||
|
if self._ext is not None:
|
||||||
|
# Just try to convert the value into an index
|
||||||
|
try:
|
||||||
|
ind = int(self._val)
|
||||||
|
except ValueError:
|
||||||
|
try:
|
||||||
|
# The pycrate "_ext_" format
|
||||||
|
ind = int(self._val[5:])
|
||||||
|
except ValueError:
|
||||||
|
raise ASN1OEREncodeErr(
|
||||||
|
"{0}: invalid ENUMERATED value, {1}".format(
|
||||||
|
self.fullname(),
|
||||||
|
self._val))
|
||||||
|
return ind
|
||||||
|
|
||||||
|
def _get_index_value(self, index):
|
||||||
|
try:
|
||||||
|
val = self._cont_rev[index]
|
||||||
|
except (KeyError):
|
||||||
|
if self._ext is not None:
|
||||||
|
if not self._SILENT:
|
||||||
|
asnlog('ENUM._from_oer: %s, unknown extension value %r' \
|
||||||
|
% (self._name, index))
|
||||||
|
# Just try to convert the value into an index
|
||||||
|
val = '_ext_%r' % index
|
||||||
|
else:
|
||||||
|
raise (ASN1OERDecodeErr(
|
||||||
|
'{0}: invalid ENUMERATED value, {1}'.format(self.fullname(),
|
||||||
|
index)))
|
||||||
|
|
||||||
|
return val
|
||||||
|
|
||||||
|
def _from_oer_ws(self, char):
|
||||||
|
index, _gen = ASN1CodecOER.decode_enumerated_ws(char)
|
||||||
|
self._val = self._get_index_value(index)
|
||||||
|
self._struct = Envelope(self._name, GEN=tuple(_gen))
|
||||||
|
|
||||||
|
def _from_oer(self, char):
|
||||||
|
self._val = self._get_index_value(ASN1CodecOER.decode_enumerated(char))
|
||||||
|
|
||||||
|
def _to_oer_ws(self):
|
||||||
|
self._struct = Envelope(self._name, GEN=(
|
||||||
|
ASN1CodecOER.encode_enumerated_ws(self._get_index()),
|
||||||
|
))
|
||||||
|
return self._struct
|
||||||
|
|
||||||
|
def _to_oer(self):
|
||||||
|
return ASN1CodecOER.encode_enumerated(self._get_index())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class _OID(ASN1Obj):
|
class _OID(ASN1Obj):
|
||||||
|
|
||||||
|
|
|
@ -1878,12 +1878,63 @@ class ASN1CodecOER(ASN1Codec):
|
||||||
# No lower bound -> encode with length determinant
|
# No lower bound -> encode with length determinant
|
||||||
return cls.decode_intunconst_ws(char)
|
return cls.decode_intunconst_ws(char)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def encode_enumerated(cls, val):
|
||||||
|
# Always canonical (implementing non-canonical doesn't make sense)
|
||||||
|
_gen = []
|
||||||
|
if 0 <= val <= 127:
|
||||||
|
# short form
|
||||||
|
_gen.append((T_UINT, val, 8))
|
||||||
|
else:
|
||||||
|
# long form
|
||||||
|
dl = int_bytelen(val)
|
||||||
|
_gen.extend([(T_UINT, 1, 1),
|
||||||
|
(T_UINT, dl, 7),
|
||||||
|
(T_INT, val, dl * 8)
|
||||||
|
])
|
||||||
|
|
||||||
|
return _gen
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def encode_ieee754_32(cls, val):
|
def encode_enumerated_ws(cls, val):
|
||||||
GEN = [
|
if 0 <= val <= 127:
|
||||||
(T_UINT, )
|
# short form
|
||||||
]
|
_gen = (
|
||||||
|
Uint('Form', val=0, bl=1, dic=cls.LenFormLUT),
|
||||||
|
Uint('Val', val=val, bl=7)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# long form
|
||||||
|
dl = int_bytelen(val)
|
||||||
|
_gen = (
|
||||||
|
Uint('Form', val=1, bl=1, dic=cls.LenFormLUT),
|
||||||
|
Uint('Len', val=dl, bl=7),
|
||||||
|
Int('Val', val=val, bl=dl*8)
|
||||||
|
)
|
||||||
|
|
||||||
|
return Envelope('L', GEN=_gen)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decode_enumerated(cls, char):
|
||||||
|
long_form = char.get_uint(1)
|
||||||
|
val = char.get_uint(7)
|
||||||
|
if long_form:
|
||||||
|
val = char.get_int(val*8)
|
||||||
|
return val
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def decode_enumerated_ws(cls, char):
|
||||||
|
t_enum = Envelope('L', GEN=(
|
||||||
|
Uint('Form', bl=1, dic=cls.LenFormLUT),
|
||||||
|
Uint('Val', bl=7)
|
||||||
|
))
|
||||||
|
t_enum._from_char(char)
|
||||||
|
long_form = t_enum[0].get_val()
|
||||||
|
enum_val = t_enum[1].get_val()
|
||||||
|
if long_form:
|
||||||
|
t_enum[1]._name = "Len"
|
||||||
|
val = Int('Val', bl=8*enum_val)
|
||||||
|
val._from_char(char)
|
||||||
|
enum_val = val.get_val()
|
||||||
|
t_enum.append(val)
|
||||||
|
return enum_val, t_enum
|
||||||
|
|
|
@ -85,3 +85,8 @@ class ASN1JERDecodeErr(ASN1CodecErr):
|
||||||
#class ASN1GSERDecodeErr(ASN1CodecErr):
|
#class ASN1GSERDecodeErr(ASN1CodecErr):
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
|
class ASN1OERDecodeErr(ASN1CodecErr):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class ASN1OEREncodeErr(ASN1CodecErr):
|
||||||
|
pass
|
||||||
|
|
|
@ -1076,6 +1076,8 @@ def _test_rt_base():
|
||||||
assert( Enu01.to_ber() == Enu01.to_ber_ws() == b'\n\x01\x02' )
|
assert( Enu01.to_ber() == Enu01.to_ber_ws() == b'\n\x01\x02' )
|
||||||
assert( Enu01.to_cer() == Enu01.to_cer_ws() == b'\n\x01\x02' )
|
assert( Enu01.to_cer() == Enu01.to_cer_ws() == b'\n\x01\x02' )
|
||||||
assert( Enu01.to_der() == Enu01.to_der_ws() == b'\n\x01\x02' )
|
assert( Enu01.to_der() == Enu01.to_der_ws() == b'\n\x01\x02' )
|
||||||
|
assert( Enu01.to_oer() == Enu01.to_oer_ws() == b'\x02' )
|
||||||
|
assert( Enu01.to_coer() == Enu01.to_coer_ws() == b'\x02' )
|
||||||
# decoding
|
# decoding
|
||||||
Enu01.from_aper(b'\x80')
|
Enu01.from_aper(b'\x80')
|
||||||
assert( Enu01._val == 'coffee' )
|
assert( Enu01._val == 'coffee' )
|
||||||
|
@ -1102,6 +1104,15 @@ def _test_rt_base():
|
||||||
assert( Enu01.to_jer() == '"coffee"' )
|
assert( Enu01.to_jer() == '"coffee"' )
|
||||||
Enu01.from_jer('"coffee"')
|
Enu01.from_jer('"coffee"')
|
||||||
assert( Enu01._val == 'coffee' )
|
assert( Enu01._val == 'coffee' )
|
||||||
|
# OER/COER
|
||||||
|
Enu01.from_oer(b'\x02')
|
||||||
|
assert( Enu01._val == 'coffee' )
|
||||||
|
Enu01.from_oer_ws(b'\x02')
|
||||||
|
assert( Enu01._val == 'coffee' )
|
||||||
|
Enu01.from_coer(b'\x02')
|
||||||
|
assert( Enu01._val == 'coffee' )
|
||||||
|
Enu01.from_coer_ws(b'\x02')
|
||||||
|
assert( Enu01._val == 'coffee' )
|
||||||
|
|
||||||
# Enu04 ::= ENUMERATED {cheese, ..., cake, coffee, tea}
|
# Enu04 ::= ENUMERATED {cheese, ..., cake, coffee, tea}
|
||||||
Enu04 = Mod['Enu04']
|
Enu04 = Mod['Enu04']
|
||||||
|
@ -1112,6 +1123,8 @@ def _test_rt_base():
|
||||||
assert( Enu04.to_ber() == Enu04.to_ber_ws() == b'\n\x01\x03' )
|
assert( Enu04.to_ber() == Enu04.to_ber_ws() == b'\n\x01\x03' )
|
||||||
assert( Enu04.to_cer() == Enu04.to_cer_ws() == b'\n\x01\x03' )
|
assert( Enu04.to_cer() == Enu04.to_cer_ws() == b'\n\x01\x03' )
|
||||||
assert( Enu04.to_der() == Enu04.to_der_ws() == b'\n\x01\x03' )
|
assert( Enu04.to_der() == Enu04.to_der_ws() == b'\n\x01\x03' )
|
||||||
|
assert( Enu04.to_oer() == Enu04.to_oer_ws() == b'\x03' )
|
||||||
|
assert( Enu04.to_coer() == Enu04.to_coer_ws() == b'\x03' )
|
||||||
# decoding
|
# decoding
|
||||||
Enu04.from_aper(b'\x82')
|
Enu04.from_aper(b'\x82')
|
||||||
assert( Enu04._val == 'tea' )
|
assert( Enu04._val == 'tea' )
|
||||||
|
@ -1133,6 +1146,14 @@ def _test_rt_base():
|
||||||
assert( Enu04._val == 'tea' )
|
assert( Enu04._val == 'tea' )
|
||||||
Enu04.from_der_ws(b'\n\x01\x03')
|
Enu04.from_der_ws(b'\n\x01\x03')
|
||||||
assert( Enu04._val == 'tea' )
|
assert( Enu04._val == 'tea' )
|
||||||
|
Enu04.from_oer(b'\x03')
|
||||||
|
assert( Enu04._val == 'tea' )
|
||||||
|
Enu04.from_oer_ws(b'\x03')
|
||||||
|
assert( Enu04._val == 'tea' )
|
||||||
|
Enu04.from_coer(b'\x03')
|
||||||
|
assert( Enu04._val == 'tea' )
|
||||||
|
Enu04.from_coer_ws(b'\x03')
|
||||||
|
assert( Enu04._val == 'tea' )
|
||||||
|
|
||||||
# Oid01 ::= OBJECT IDENTIFIER
|
# Oid01 ::= OBJECT IDENTIFIER
|
||||||
Oid01 = Mod['Oid01']
|
Oid01 = Mod['Oid01']
|
||||||
|
|
Loading…
Reference in New Issue