| 379 | |
| 380 | |
| 381 | class ConditionalField(_FieldContainer): |
| 382 | __slots__ = ["fld", "cond"] |
| 383 | |
| 384 | def __init__(self, |
| 385 | fld, # type: AnyField |
| 386 | cond # type: Callable[[Packet], bool] |
| 387 | ): |
| 388 | # type: (...) -> None |
| 389 | self.fld = fld |
| 390 | self.cond = cond |
| 391 | |
| 392 | def _evalcond(self, pkt): |
| 393 | # type: (Packet) -> bool |
| 394 | return bool(self.cond(pkt)) |
| 395 | |
| 396 | def any2i(self, pkt, x): |
| 397 | # type: (Optional[Packet], Any) -> Any |
| 398 | # BACKWARD COMPATIBILITY |
| 399 | # Note: we shouldn't need this function. (it's not correct) |
| 400 | # However, having i2h implemented (#2364), it changes the default |
| 401 | # behavior and broke all packets that wrongly use two ConditionalField |
| 402 | # with the same name. Those packets are the problem: they are wrongly |
| 403 | # built (they should either be reusing the same conditional field, or |
| 404 | # using a MultipleTypeField). |
| 405 | # But I don't want to dive into fixing all of them just yet, |
| 406 | # so for now, let's keep this this way, even though it's not correct. |
| 407 | if type(self.fld) is Field: |
| 408 | return x |
| 409 | return self.fld.any2i(pkt, x) |
| 410 | |
| 411 | def i2h(self, pkt, val): |
| 412 | # type: (Optional[Packet], Any) -> Any |
| 413 | if pkt and not self._evalcond(pkt): |
| 414 | return None |
| 415 | return self.fld.i2h(pkt, val) |
| 416 | |
| 417 | def getfield(self, pkt, s): |
| 418 | # type: (Packet, bytes) -> Tuple[bytes, Any] |
| 419 | if self._evalcond(pkt): |
| 420 | return self.fld.getfield(pkt, s) |
| 421 | else: |
| 422 | return s, None |
| 423 | |
| 424 | def addfield(self, pkt, s, val): |
| 425 | # type: (Packet, bytes, Any) -> bytes |
| 426 | if self._evalcond(pkt): |
| 427 | return self.fld.addfield(pkt, s, val) |
| 428 | else: |
| 429 | return s |
| 430 | |
| 431 | def __getattr__(self, attr): |
| 432 | # type: (str) -> Any |
| 433 | return getattr(self.fld, attr) |
| 434 | |
| 435 | |
| 436 | class MultipleTypeField(_FieldContainer): |
no outgoing calls
no test coverage detected