1
1
# SPDX-License-Identifier: MIT
2
2
from dataclasses import dataclass
3
- from typing import List , Optional
3
+ from enum import Enum
4
+ from typing import List , Optional , cast
4
5
from xml .etree import ElementTree
5
6
6
7
from typing_extensions import override
15
16
from .utils import dataclass_fields_asdict
16
17
17
18
19
+ class Termination (Enum ):
20
+ END_OF_PDU = "END-OF-PDU"
21
+ ZERO = "ZERO"
22
+ HEX_FF = "HEX-FF"
23
+
24
+
18
25
@dataclass
19
26
class MinMaxLengthType (DiagCodedType ):
20
27
min_length : int
21
28
max_length : Optional [int ]
22
- termination : str
29
+ termination : Termination
23
30
24
31
@property
25
32
def dct_type (self ) -> DctType :
@@ -35,7 +42,13 @@ def from_et(et_element: ElementTree.Element,
35
42
max_length = None
36
43
if et_element .find ("MAX-LENGTH" ) is not None :
37
44
max_length = int (odxrequire (et_element .findtext ("MAX-LENGTH" )))
38
- termination = odxrequire (et_element .get ("TERMINATION" ))
45
+
46
+ termination_str = odxrequire (et_element .get ("TERMINATION" ))
47
+ try :
48
+ termination = Termination (termination_str )
49
+ except ValueError :
50
+ termination = cast (Termination , None )
51
+ odxraise (f"Encountered unknown termination type '{ termination_str } '" )
39
52
40
53
return MinMaxLengthType (
41
54
min_length = min_length , max_length = max_length , termination = termination , ** kwargs )
@@ -49,23 +62,18 @@ def __post_init__(self) -> None:
49
62
DataType .A_UNICODE2STRING ,
50
63
DataType .A_UTF8STRING ,
51
64
], f"A min-max length type cannot have the base data type { self .base_data_type } ." )
52
- odxassert (self .termination in [
53
- "ZERO" ,
54
- "HEX-FF" ,
55
- "END-OF-PDU" ,
56
- ], f"A min-max length type cannot have the termination { self .termination } " )
57
65
58
66
def __termination_sequence (self ) -> bytes :
59
67
"""Returns the termination byte sequence if it isn't defined."""
60
68
# The termination sequence is actually not specified by ASAM
61
69
# for A_BYTEFIELD but I assume it is only one byte.
62
70
termination_sequence = b''
63
- if self .termination == " ZERO" :
71
+ if self .termination == Termination . ZERO :
64
72
if self .base_data_type not in [DataType .A_UNICODE2STRING ]:
65
73
termination_sequence = bytes ([0x0 ])
66
74
else :
67
75
termination_sequence = bytes ([0x0 , 0x0 ])
68
- elif self .termination == "HEX-FF" :
76
+ elif self .termination == Termination . HEX_FF :
69
77
if self .base_data_type not in [DataType .A_UNICODE2STRING ]:
70
78
termination_sequence = bytes ([0xFF ])
71
79
else :
@@ -121,7 +129,7 @@ def encode_into_pdu(self, internal_value: AtomicOdxType, encode_state: EncodeSta
121
129
# encountered within the encoded value.
122
130
123
131
odxassert (
124
- self .termination != "END-OF-PDU" or encode_state .is_end_of_pdu ,
132
+ self .termination != Termination . END_OF_PDU or encode_state .is_end_of_pdu ,
125
133
"Encountered a MIN-MAX-LENGTH type with END-OF-PDU termination "
126
134
"which is not located at the end of the PDU" )
127
135
if encode_state .is_end_of_pdu or data_length == self .max_length :
@@ -153,7 +161,7 @@ def decode_from_pdu(self, decode_state: DecodeState) -> AtomicOdxType:
153
161
if self .max_length is not None :
154
162
max_terminator_pos = min (max_terminator_pos , orig_cursor_pos + self .max_length )
155
163
156
- if self .termination != "END-OF-PDU" :
164
+ if self .termination != Termination . END_OF_PDU :
157
165
# The parameter either ends after the maximum length, at
158
166
# the end of the PDU or if a termination sequence is
159
167
# found.
0 commit comments