1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use crate::interfaces::{nsIInterfaceRequestor, nsISupports}; 6 use crate::{GetterAddrefs, RefCounted, RefPtr}; 7 8 #[repr(C)] 9 #[derive(Copy, Clone, Eq, PartialEq)] 10 /// A "unique identifier". This is modeled after OSF DCE UUIDs. 11 pub struct nsID(pub u32, pub u16, pub u16, pub [u8; 8]); 12 13 /// Interface IDs 14 pub type nsIID = nsID; 15 /// Class IDs 16 pub type nsCID = nsID; 17 18 /// A type which implements XpCom must follow the following rules: 19 /// 20 /// * It must be a legal XPCOM interface. 21 /// * The result of a QueryInterface or similar call, passing IID, must return a 22 /// valid reference to an object of the given type. 23 /// * It must be valid to cast a &self reference to a &nsISupports reference. 24 pub unsafe trait XpCom: RefCounted { 25 const IID: nsIID; 26 27 /// Perform a QueryInterface call on this object, attempting to dynamically 28 /// cast it to the requested interface type. Returns Some(RefPtr<T>) if the 29 /// cast succeeded, and None otherwise. query_interface<T: XpCom>(&self) -> Option<RefPtr<T>>30 fn query_interface<T: XpCom>(&self) -> Option<RefPtr<T>> { 31 let mut ga = GetterAddrefs::<T>::new(); 32 unsafe { 33 if (*(self as *const Self as *const nsISupports)) 34 .QueryInterface(&T::IID, ga.void_ptr()) 35 .succeeded() 36 { 37 ga.refptr() 38 } else { 39 None 40 } 41 } 42 } 43 44 /// Perform a `GetInterface` call on this object, returning `None` if the 45 /// object doesn't implement `nsIInterfaceRequestor`, or can't access the 46 /// interface `T`. get_interface<T: XpCom>(&self) -> Option<RefPtr<T>>47 fn get_interface<T: XpCom>(&self) -> Option<RefPtr<T>> { 48 let ireq = self.query_interface::<nsIInterfaceRequestor>()?; 49 50 let mut ga = GetterAddrefs::<T>::new(); 51 unsafe { 52 if ireq.GetInterface(&T::IID, ga.void_ptr()).succeeded() { 53 ga.refptr() 54 } else { 55 None 56 } 57 } 58 } 59 } 60