Begins creating a custom BinaryView. This function may only be called from the `create_custom_view` function of a `CustomBinaryViewType`. `parent` specifies the view that the core will treat as the parent view, that Segments created against the created view will be backed by `parent`. It will usually be (but is not required to be) the `data` argument of the `create_custom_view` callback. `const
(self, parent: &BinaryView, view_args: V::Args)
| 494 | /// to be returned by the `AsRef<BinaryView>` implementation required by the `BinaryViewBase` trait. |
| 495 | /// TODO FIXME whelp this is broke going to need 2 init callbacks |
| 496 | pub fn create<V>(self, parent: &BinaryView, view_args: V::Args) -> Result<CustomView<'a>> |
| 497 | where |
| 498 | V: CustomBinaryView, |
| 499 | { |
| 500 | let file = self.actual_parent.file(); |
| 501 | let view_type = self.view_type; |
| 502 | |
| 503 | let view_name = view_type.name(); |
| 504 | |
| 505 | if let Some(bv) = file.view_of_type(view_name.as_str()) { |
| 506 | // while it seems to work most of the time, you can get really unlucky |
| 507 | // if the a free of the existing view of the same type kicks off while |
| 508 | // BNCreateBinaryViewOfType is still running. the freeObject callback |
| 509 | // will run for the new view before we've even finished initializing, |
| 510 | // and that's all she wrote. |
| 511 | // |
| 512 | // even if we deal with it gracefully in cb_free_object, |
| 513 | // BNCreateBinaryViewOfType is still going to crash, so we're just |
| 514 | // going to try and stop this from happening in the first place. |
| 515 | log::error!( |
| 516 | "attempt to create duplicate view of type '{}' (existing: {:?})", |
| 517 | view_name.as_str(), |
| 518 | bv.handle |
| 519 | ); |
| 520 | |
| 521 | return Err(()); |
| 522 | } |
| 523 | |
| 524 | // struct representing the context of a BNCustomBinaryView. Can be safely |
| 525 | // dropped at any moment. |
| 526 | struct CustomViewContext<V> |
| 527 | where |
| 528 | V: CustomBinaryView, |
| 529 | { |
| 530 | raw_handle: *mut BNBinaryView, |
| 531 | state: CustomViewContextState<V>, |
| 532 | } |
| 533 | |
| 534 | enum CustomViewContextState<V> |
| 535 | where |
| 536 | V: CustomBinaryView, |
| 537 | { |
| 538 | Uninitialized { args: V::Args }, |
| 539 | Initialized { view: V }, |
| 540 | // dummy state, used as a helper to change states, only happen if the |
| 541 | // `new` or `init` function fails. |
| 542 | None, |
| 543 | } |
| 544 | |
| 545 | impl<V: CustomBinaryView> CustomViewContext<V> { |
| 546 | fn assume_init_ref(&self) -> &V { |
| 547 | let CustomViewContextState::Initialized { view } = &self.state else { |
| 548 | panic!("CustomViewContextState in invalid state"); |
| 549 | }; |
| 550 | view |
| 551 | } |
| 552 | } |
| 553 |
nothing calls this directly
no test coverage detected