| 2402 | return s |
| 2403 | |
| 2404 | def getfield(self, # type: ignore |
| 2405 | pkt, # type: Packet |
| 2406 | s, # type: Union[Tuple[bytes, int], bytes] |
| 2407 | ): |
| 2408 | # type: (...) -> Union[Tuple[Tuple[bytes, int], I], Tuple[bytes, I]] # noqa: E501 |
| 2409 | if isinstance(s, tuple): |
| 2410 | s, bn = s |
| 2411 | else: |
| 2412 | bn = 0 |
| 2413 | # Apply LE if necessary |
| 2414 | if self.rev and self.tot_size > 1: |
| 2415 | s = s[:self.tot_size][::-1] + s[self.tot_size:] |
| 2416 | |
| 2417 | # we don't want to process all the string |
| 2418 | nb_bytes = (self.size + bn - 1) // 8 + 1 |
| 2419 | w = s[:nb_bytes] |
| 2420 | |
| 2421 | # split the substring byte by byte |
| 2422 | _bytes = struct.unpack('!%dB' % nb_bytes, w) |
| 2423 | |
| 2424 | b = 0 |
| 2425 | for c in range(nb_bytes): |
| 2426 | b |= int(_bytes[c]) << (nb_bytes - c - 1) * 8 |
| 2427 | |
| 2428 | # get rid of high order bits |
| 2429 | b &= (1 << (nb_bytes * 8 - bn)) - 1 |
| 2430 | |
| 2431 | # remove low order bits |
| 2432 | b = b >> (nb_bytes * 8 - self.size - bn) |
| 2433 | |
| 2434 | bn += self.size |
| 2435 | s = s[bn // 8:] |
| 2436 | bn = bn % 8 |
| 2437 | b2 = self.m2i(pkt, b) |
| 2438 | if bn: |
| 2439 | return (s, bn), b2 |
| 2440 | else: |
| 2441 | return s, b2 |
| 2442 | |
| 2443 | def randval(self): |
| 2444 | # type: () -> RandNum |