| 3375 | |
| 3376 | |
| 3377 | class FixedPointField(BitField): |
| 3378 | __slots__ = ['frac_bits'] |
| 3379 | |
| 3380 | def __init__(self, name, default, size, frac_bits=16): |
| 3381 | # type: (str, int, int, int) -> None |
| 3382 | self.frac_bits = frac_bits |
| 3383 | super(FixedPointField, self).__init__(name, default, size) |
| 3384 | |
| 3385 | def any2i(self, pkt, val): |
| 3386 | # type: (Optional[Packet], Optional[float]) -> Optional[int] |
| 3387 | if val is None: |
| 3388 | return val |
| 3389 | ival = int(val) |
| 3390 | fract = int((val - ival) * 2**self.frac_bits) |
| 3391 | return (ival << self.frac_bits) | fract |
| 3392 | |
| 3393 | def i2h(self, pkt, val): |
| 3394 | # type: (Optional[Packet], Optional[int]) -> Optional[EDecimal] |
| 3395 | # A bit of trickery to get precise floats |
| 3396 | if val is None: |
| 3397 | return val |
| 3398 | int_part = val >> self.frac_bits |
| 3399 | pw = 2.0**self.frac_bits |
| 3400 | frac_part = EDecimal(val & (1 << self.frac_bits) - 1) |
| 3401 | frac_part /= pw # type: ignore |
| 3402 | return int_part + frac_part.normalize(int(math.log10(pw))) |
| 3403 | |
| 3404 | def i2repr(self, pkt, val): |
| 3405 | # type: (Optional[Packet], int) -> str |
| 3406 | return str(self.i2h(pkt, val)) |
| 3407 | |
| 3408 | |
| 3409 | # Base class for IPv4 and IPv6 Prefixes inspired by IPField and IP6Field. |
no outgoing calls
no test coverage detected
searching dependent graphs…