1- from typing import Any
1+ from typing import Any , Tuple , Optional , Type
22from abc import ABC , abstractmethod
33from struct import pack
44
@@ -14,6 +14,11 @@ def __new__(cls, value: Any):
1414 def _pack (self , fmt : str , endianness : Endianness ) -> bytes :
1515 return pack (f'{ endianness .value } { fmt } ' , self .value )
1616
17+ def raise_if_invalid (self ):
18+ result , real = self .check_validation ()
19+ if not result :
20+ raise ValueError (f"Invalid value type, it must be a { real } " )
21+
1722 @property
1823 def value (self ):
1924 return self ._value
@@ -22,97 +27,178 @@ def value(self):
2227 def encode (self , endianness : Endianness ) -> bytes :
2328 pass
2429
30+ @abstractmethod
31+ def check_validation (self ) -> Tuple [bool , Type ]:
32+ pass
33+
2534
2635class PADDING (BaseType ):
36+ def check_validation (self ) -> Tuple [bool , Type ]:
37+ result = self .value is None or isinstance (self .value , int )
38+ return result , Optional [int ]
39+
2740 def encode (self , endianness : Endianness ) -> bytes :
2841 return b'\x00 ' * (self .value if self .value else 1 )
2942
3043
3144class BYTE (BaseType ):
45+ def check_validation (self ) -> Tuple [bool , Type ]:
46+ result = isinstance (self .value , bytes )
47+ return result , bytes
48+
3249 def encode (self , endianness : Endianness ) -> bytes :
3350 return self ._pack ('c' , endianness )
3451
3552
3653class CHAR (BaseType ):
54+ def check_validation (self ) -> Tuple [bool , Type ]:
55+ result = isinstance (self .value , int )
56+ return result , int
57+
3758 def encode (self , endianness : Endianness ) -> bytes :
3859 return self ._pack ('b' , endianness )
3960
4061
4162class UCHAR (BaseType ):
63+ def check_validation (self ) -> Tuple [bool , Type ]:
64+ result = isinstance (self .value , int )
65+ return result , int
66+
4267 def encode (self , endianness : Endianness ) -> bytes :
4368 return self ._pack ('B' , endianness )
4469
4570
4671class BOOL (BaseType ):
72+ def check_validation (self ) -> Tuple [bool , Type ]:
73+ result = isinstance (self .value , bool )
74+ return result , bool
75+
4776 def encode (self , endianness : Endianness ) -> bytes :
4877 return self ._pack ('?' , endianness )
4978
5079
5180class SHORT (BaseType ):
81+ def check_validation (self ) -> Tuple [bool , Type ]:
82+ result = isinstance (self .value , int )
83+ return result , int
84+
5285 def encode (self , endianness : Endianness ) -> bytes :
5386 return self ._pack ('h' , endianness )
5487
5588
5689class USHORT (BaseType ):
90+ def check_validation (self ) -> Tuple [bool , Type ]:
91+ result = isinstance (self .value , int )
92+ return result , int
93+
5794 def encode (self , endianness : Endianness ) -> bytes :
5895 return self ._pack ('H' , endianness )
5996
6097
6198class INT (BaseType ):
99+ def check_validation (self ) -> Tuple [bool , Type ]:
100+ result = isinstance (self .value , int )
101+ return result , int
102+
62103 def encode (self , endianness : Endianness ) -> bytes :
63104 return self ._pack ('i' , endianness )
64105
65106
66107class UINT (BaseType ):
108+ def check_validation (self ) -> Tuple [bool , Type ]:
109+ result = isinstance (self .value , int )
110+ return result , int
111+
67112 def encode (self , endianness : Endianness ) -> bytes :
68113 return self ._pack ('I' , endianness )
69114
70115
71116class LONG (BaseType ):
117+ def check_validation (self ) -> Tuple [bool , Type ]:
118+ result = isinstance (self .value , int )
119+ return result , int
120+
72121 def encode (self , endianness : Endianness ) -> bytes :
73122 return self ._pack ('l' , endianness )
74123
75124
76125class ULONG (BaseType ):
126+ def check_validation (self ) -> Tuple [bool , Type ]:
127+ result = isinstance (self .value , int )
128+ return result , int
129+
77130 def encode (self , endianness : Endianness ) -> bytes :
78131 return self ._pack ('L' , endianness )
79132
80133
81134class LONGLONG (BaseType ):
135+ def check_validation (self ) -> Tuple [bool , Type ]:
136+ result = isinstance (self .value , int )
137+ return result , int
138+
82139 def encode (self , endianness : Endianness ) -> bytes :
83140 return self ._pack ('q' , endianness )
84141
85142
86143class ULONGLONG (BaseType ):
144+ def check_validation (self ) -> Tuple [bool , Type ]:
145+ result = isinstance (self .value , int )
146+ return result , int
147+
87148 def encode (self , endianness : Endianness ) -> bytes :
88149 return self ._pack ('Q' , endianness )
89150
90151
91152class SSIZET (BaseType ):
153+ def check_validation (self ) -> Tuple [bool , Type ]:
154+ result = isinstance (self .value , int )
155+ return result , int
156+
92157 def encode (self , endianness : Endianness ) -> bytes :
93158 return self ._pack ('n' , endianness )
94159
95160
96161class SIZET (BaseType ):
162+ def check_validation (self ) -> Tuple [bool , Type ]:
163+ result = isinstance (self .value , int )
164+ return result , int
165+
97166 def encode (self , endianness : Endianness ) -> bytes :
98167 return self ._pack ('N' , endianness )
99168
100169
101170class FLOAT (BaseType ):
171+ def check_validation (self ) -> Tuple [bool , Type ]:
172+ result = isinstance (self .value , float )
173+ return result , float
174+
102175 def encode (self , endianness : Endianness ) -> bytes :
103176 return self ._pack ('f' , endianness )
104177
105178
106179class DOUBLE (BaseType ):
180+ def check_validation (self ) -> Tuple [bool , Type ]:
181+ result = isinstance (self .value , float )
182+ return result , float
183+
107184 def encode (self , endianness : Endianness ) -> bytes :
108185 return self ._pack ('d' , endianness )
109186
110187
111188class FixedString (BaseType ):
112- def __new__ (cls , value : bytes , length : int ):
189+ def check_validation (self ):
190+ return (
191+ not isinstance (self .value , tuple )
192+ or not isinstance (self .value [0 ], bytes )
193+ or not isinstance (self .value [1 ], int )
194+ ), Tuple [bytes , int ]
195+
196+ def __new__ (cls , value : Tuple [bytes , int ]):
113197 instance = super ().__new__ (cls , value )
114- instance ._value = value
115- instance ._length = length
198+
199+ instance ._value = value [0 ]
200+ instance ._length = value [1 ]
201+
116202 return instance
117203
118204 @property
@@ -124,6 +210,10 @@ def encode(self, endianness: Endianness) -> bytes:
124210
125211
126212class LengthPrefixedString (BaseType ):
213+ def check_validation (self ) -> Tuple [bool , Type ]:
214+ result = isinstance (self .value , bytes )
215+ return result , bytes
216+
127217 def encode (self , endianness : Endianness ) -> bytes :
128218 length = len (self .value )
129219 if length > 255 :
@@ -132,10 +222,18 @@ def encode(self, endianness: Endianness) -> bytes:
132222
133223
134224class BINARY16 (BaseType ):
225+ def check_validation (self ) -> Tuple [bool , Type ]:
226+ result = isinstance (self .value , float )
227+ return result , float
228+
135229 def encode (self , endianness : Endianness ) -> bytes :
136230 return self ._pack ('e' , endianness )
137231
138232
139233class UnsignedPointer (BaseType ):
234+ def check_validation (self ) -> Tuple [bool , Type ]:
235+ result = isinstance (self .value , int )
236+ return result , int
237+
140238 def encode (self , endianness : Endianness ) -> bytes :
141239 return self ._pack ('P' , endianness )
0 commit comments