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::{nsIComponentManager, nsIComponentRegistrar, nsIServiceManager};
6 use crate::{GetterAddrefs, RefPtr, XpCom};
7 use std::ffi::CStr;
8 use std::ptr;
9 
10 /// Get a reference to the global `nsIComponentManager`.
11 ///
12 /// Can return `None` during shutdown.
13 #[inline]
component_manager() -> Option<RefPtr<nsIComponentManager>>14 pub fn component_manager() -> Option<RefPtr<nsIComponentManager>> {
15     unsafe { RefPtr::from_raw(Gecko_GetComponentManager()) }
16 }
17 
18 /// Get a reference to the global `nsIServiceManager`.
19 ///
20 /// Can return `None` during shutdown.
21 #[inline]
service_manager() -> Option<RefPtr<nsIServiceManager>>22 pub fn service_manager() -> Option<RefPtr<nsIServiceManager>> {
23     unsafe { RefPtr::from_raw(Gecko_GetServiceManager()) }
24 }
25 
26 /// Get a reference to the global `nsIComponentRegistrar`
27 ///
28 /// Can return `None` during shutdown.
29 #[inline]
component_registrar() -> Option<RefPtr<nsIComponentRegistrar>>30 pub fn component_registrar() -> Option<RefPtr<nsIComponentRegistrar>> {
31     unsafe { RefPtr::from_raw(Gecko_GetComponentRegistrar()) }
32 }
33 
34 /// Helper for calling `nsIComponentManager::CreateInstanceByContractID` on the
35 /// global `nsIComponentRegistrar`.
36 ///
37 /// This method is similar to `do_CreateInstance` in C++.
38 #[inline]
create_instance<T: XpCom>(id: &CStr) -> Option<RefPtr<T>>39 pub fn create_instance<T: XpCom>(id: &CStr) -> Option<RefPtr<T>> {
40     unsafe {
41         let mut ga = GetterAddrefs::<T>::new();
42         if component_manager()?
43             .CreateInstanceByContractID(id.as_ptr(), ptr::null(), &T::IID, ga.void_ptr())
44             .succeeded()
45         {
46             ga.refptr()
47         } else {
48             None
49         }
50     }
51 }
52 
53 /// Helper for calling `nsIServiceManager::GetServiceByContractID` on the global
54 /// `nsIServiceManager`.
55 ///
56 /// This method is similar to `do_GetService` in C++.
57 #[inline]
get_service<T: XpCom>(id: &CStr) -> Option<RefPtr<T>>58 pub fn get_service<T: XpCom>(id: &CStr) -> Option<RefPtr<T>> {
59     unsafe {
60         let mut ga = GetterAddrefs::<T>::new();
61         if service_manager()?
62             .GetServiceByContractID(id.as_ptr(), &T::IID, ga.void_ptr())
63             .succeeded()
64         {
65             ga.refptr()
66         } else {
67             None
68         }
69     }
70 }
71 
72 extern "C" {
Gecko_GetComponentManager() -> *const nsIComponentManager73     fn Gecko_GetComponentManager() -> *const nsIComponentManager;
Gecko_GetServiceManager() -> *const nsIServiceManager74     fn Gecko_GetServiceManager() -> *const nsIServiceManager;
Gecko_GetComponentRegistrar() -> *const nsIComponentRegistrar75     fn Gecko_GetComponentRegistrar() -> *const nsIComponentRegistrar;
76 }
77