1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 '''
31 Matchers specifically for binary data (most LEPL matchers can be used with
32 binary data, but additional support is needed when the matching involves a
33 literal comparison or generation of a binary result).
34 '''
35
36 if bytes is str:
37 print('Binary parsing unsupported in this Python version')
38 else:
39
40 from lepl.bin.bits import unpack_length, BitString, STRICT
41 from lepl.matchers.support import OperatorMatcher
42 from lepl.core.parser import tagged
43 from lepl.stream.core import s_next
44
45
46
47
48
49
50
51 - class _Constant(OperatorMatcher):
52 '''
53 Support class for matching constant values.
54 '''
55
56
57
58
60 '''
61 Match a given bit string.
62
63 This is typically not used directly, but via the functions below
64 (which specify a value as integer, bytes, etc).
65 '''
66 super(_Constant, self).__init__()
67 self._arg(value=value)
68
69 @tagged
71 '''
72 Do the matching (return a generator that provides successive
73 (result, stream) tuples).
74
75 Need to be careful here to use only the restricted functionality
76 provided by the stream interface.
77 '''
78 (value, next_stream) = s_next(stream, count=len(self.value))
79 if self.value == value:
80 yield ([self.value], next_stream)
81
82
83 - class Const(_Constant):
84 '''
85 Match a given value, which is parsed as for `BitString.from_int`.
86 '''
87
92
95 '''
96 Support class for matching a given number of bits.
97 '''
98
99
100
101
105
106 @tagged
108 '''
109 Do the matching (return a generator that provides successive
110 (result, stream) tuples).
111
112 Need to be careful here to use only the restricted functionality
113 provided by the stream interface.
114 '''
115 (value, next_stream) = s_next(stream, count=self.length)
116 yield ([self._convert(value)], next_stream)
117
119 '''
120 By default, just return the bits.
121 '''
122 return bits
123
126 '''
127 Support class for matching a given number of bytes.
128 '''
129
131 '''
132 Match a given number of bytes.
133 '''
134 if not isinstance(length, int):
135 raise TypeError('Number of bytes must be an integer')
136 super(_ByteArray, self).__init__(length)
137
139 '''
140 Convert from bits to bytes,
141 '''
142 return bits.to_bytes()
143
144
145 - class BEnd(_Variable):
146 '''
147 Convert a given number of bits (multiple of 8) to a big-endian number.
148 '''
149
151 '''
152 Match a given number of bits, converting them to a big-endian int.
153 '''
154 length = unpack_length(length)
155 if length % 8:
156 raise ValueError('Big endian int must a length that is a '
157 'multiple of 8.')
158 super(BEnd, self).__init__(length)
159
161 '''
162 Convert to int.
163 '''
164 return bits.to_int(big_endian=True)
165
166
167 - class LEnd(_Variable):
168 '''
169 Convert a given number of bits to a little-endian number.
170 '''
171
173 '''
174 Convert to int.
175 '''
176 return bits.to_int()
177
180 '''
181 Match or read a bit string (to read a value, give the number of bits).
182 '''
183 if isinstance(value, int):
184 return _Variable(value)
185 else:
186 return _Constant(value)
187
188
189 - def Byte(value=None):
190 '''
191 Match or read a byte (if a value is given, it must match).
192 '''
193 if value is None:
194 return BEnd(8)
195 else:
196 return _Constant(BitString.from_byte(value))
197
200 '''
201 Match or read an array of bytes (to read a value, give the number
202 of bytes).
203 '''
204 if isinstance(value, int):
205 return _ByteArray(value)
206 else:
207 return _Constant(BitString.from_bytearray(value))
208
211 '''
212 Factory method for big-endian values.
213 '''
214 def matcher(value=None):
215 '''
216 Generate the matcher, given a value.
217 '''
218 if value is None:
219 return BEnd(length)
220 else:
221 return _Constant(BitString.from_int(value, length=length,
222 big_endian=True))
223 return matcher
224
226 '''
227 Factory method for little-endian values.
228 '''
229 def matcher(value=None):
230 '''
231 Generate the matcher, given a value.
232 '''
233 if value is None:
234 return LEnd(length)
235 else:
236 return _Constant(BitString.from_int(value, length=length,
237 big_endian=False))
238 return matcher
239
240
241
242
243 BInt16 = _bint(16)
244 '''
245 Match or read an 16-bit big-endian integer (if a value is given, it
246 must match).
247 '''
248
249 LInt16 = _lint(16)
250 '''
251 Match or read an 16-bit little-endian integer (if a value is given, it
252 must match).
253 '''
254
255 BInt32 = _bint(32)
256 '''
257 Match or read an 32-bit big-endian integer (if a value is given, it
258 must match).
259 '''
260
261 LInt32 = _lint(32)
262 '''
263 Match or read an 32-bit little-endian integer (if a value is given, it
264 must match).
265 '''
266
267 BInt64 = _bint(64)
268 '''
269 Match or read an 64-bit big-endian integer (if a value is given, it
270 must match).
271 '''
272
273 LInt64 = _lint(64)
274 '''
275 Match or read an 64-bit little-endian integer (if a value is given, it
276 must match).
277 '''
278
279
280 - class _String(_ByteArray):
281 '''
282 Support class for reading a string.
283 '''
284
285
286
287
292
298
309