Skip to main content

cubeb_core/
device_collection.rs

1// Copyright © 2017-2018 Mozilla Foundation
2//
3// This program is made available under an ISC-style license.  See the
4// accompanying file LICENSE for details.
5
6use ffi;
7use ffi_types;
8use std::{ops, slice};
9use {ContextRef, DeviceInfo};
10
11/// A collection of `DeviceInfo` used by libcubeb
12type CType = ffi::cubeb_device_collection;
13
14#[derive(Debug)]
15pub struct DeviceCollection<'ctx>(CType, &'ctx ContextRef);
16
17impl DeviceCollection<'_> {
18    pub(crate) fn init_with_ctx(ctx: &ContextRef, coll: CType) -> DeviceCollection<'_> {
19        DeviceCollection(coll, ctx)
20    }
21
22    pub fn as_ptr(&self) -> *mut CType {
23        &self.0 as *const CType as *mut CType
24    }
25}
26
27impl Drop for DeviceCollection<'_> {
28    fn drop(&mut self) {
29        unsafe {
30            let _ = call!(ffi::cubeb_device_collection_destroy(
31                self.1.as_ptr(),
32                &mut self.0
33            ));
34        }
35    }
36}
37
38impl ::std::ops::Deref for DeviceCollection<'_> {
39    type Target = DeviceCollectionRef;
40
41    #[inline]
42    fn deref(&self) -> &DeviceCollectionRef {
43        let ptr = &self.0 as *const CType as *mut CType;
44        unsafe { DeviceCollectionRef::from_ptr(ptr) }
45    }
46}
47
48impl ::std::convert::AsRef<DeviceCollectionRef> for DeviceCollection<'_> {
49    #[inline]
50    fn as_ref(&self) -> &DeviceCollectionRef {
51        self
52    }
53}
54
55#[repr(transparent)]
56pub struct DeviceCollectionRef(ffi_types::Opaque<CType>);
57
58impl DeviceCollectionRef {
59    /// # Safety
60    ///
61    /// This function is unsafe because it dereferences the given `ptr` pointer.
62    /// The caller should ensure that pointer is valid.
63    #[inline]
64    pub unsafe fn from_ptr<'a>(ptr: *mut CType) -> &'a Self {
65        &*(ptr as *mut _)
66    }
67
68    /// # Safety
69    ///
70    /// This function is unsafe because it dereferences the given `ptr` pointer.
71    /// The caller should ensure that pointer is valid.
72    #[inline]
73    pub unsafe fn from_ptr_mut<'a>(ptr: *mut CType) -> &'a mut Self {
74        &mut *(ptr as *mut _)
75    }
76
77    #[inline]
78    pub fn as_ptr(&self) -> *mut CType {
79        self.0.get().cast()
80    }
81}
82
83impl ::std::fmt::Debug for DeviceCollectionRef {
84    fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
85        let ptr = self.0.get() as usize;
86        f.debug_tuple(stringify!(DeviceCollectionRef))
87            .field(&ptr)
88            .finish()
89    }
90}
91
92impl ops::Deref for DeviceCollectionRef {
93    type Target = [DeviceInfo];
94    fn deref(&self) -> &[DeviceInfo] {
95        unsafe {
96            let coll: &ffi::cubeb_device_collection = &*self.as_ptr();
97            slice::from_raw_parts(coll.device as *const DeviceInfo, coll.count)
98        }
99    }
100}