// Take a look at the license at the top of the repository in the LICENSE file. use glib::prelude::*; use glib::translate::*; use glib::subclass::prelude::*; use crate::URIHandler; use crate::URIType; pub trait URIHandlerImpl: super::element::ElementImpl { const URI_TYPE: URIType; fn get_protocols() -> &'static [&'static str]; fn get_uri(&self, element: &Self::Type) -> Option; fn set_uri(&self, element: &Self::Type, uri: &str) -> Result<(), glib::Error>; } unsafe impl IsImplementable for URIHandler { unsafe extern "C" fn interface_init( iface: glib::ffi::gpointer, _iface_data: glib::ffi::gpointer, ) { let uri_handler_iface = &mut *(iface as *mut ffi::GstURIHandlerInterface); // Store the protocols in the interface data for later use let mut data = T::type_data(); let protocols = T::get_protocols(); let protocols: *mut *const libc::c_char = protocols.to_glib_full(); let data = data.as_mut(); if data.interface_data.is_null() { data.interface_data = Box::into_raw(Box::new(Vec::new())); } (*(data.interface_data as *mut Vec<(glib::ffi::GType, glib::ffi::gpointer)>)) .push((URIHandler::static_type().to_glib(), protocols as *mut _)); uri_handler_iface.get_type = Some(uri_handler_get_type::); uri_handler_iface.get_protocols = Some(uri_handler_get_protocols::); uri_handler_iface.get_uri = Some(uri_handler_get_uri::); uri_handler_iface.set_uri = Some(uri_handler_set_uri::); } } unsafe extern "C" fn uri_handler_get_type( _type_: glib::ffi::GType, ) -> ffi::GstURIType { ::URI_TYPE.to_glib() } unsafe extern "C" fn uri_handler_get_protocols( _type_: glib::ffi::GType, ) -> *const *const libc::c_char { let data = ::type_data(); data.as_ref() .get_interface_data(URIHandler::static_type().to_glib()) as *const _ } unsafe extern "C" fn uri_handler_get_uri( uri_handler: *mut ffi::GstURIHandler, ) -> *mut libc::c_char { let instance = &*(uri_handler as *mut T::Instance); let imp = instance.get_impl(); imp.get_uri(&from_glib_borrow::<_, URIHandler>(uri_handler).unsafe_cast_ref()) .to_glib_full() } unsafe extern "C" fn uri_handler_set_uri( uri_handler: *mut ffi::GstURIHandler, uri: *const libc::c_char, err: *mut *mut glib::ffi::GError, ) -> glib::ffi::gboolean { let instance = &*(uri_handler as *mut T::Instance); let imp = instance.get_impl(); match imp.set_uri( &from_glib_borrow::<_, URIHandler>(uri_handler).unsafe_cast_ref(), glib::GString::from_glib_borrow(uri).as_str(), ) { Ok(()) => true.to_glib(), Err(error) => { *err = error.to_glib_full() as *mut _; false.to_glib() } } }