summaryrefslogtreecommitdiffstats
path: root/third_party/rust/cubeb-coreaudio/src/backend/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/cubeb-coreaudio/src/backend/utils.rs')
-rw-r--r--third_party/rust/cubeb-coreaudio/src/backend/utils.rs107
1 files changed, 107 insertions, 0 deletions
diff --git a/third_party/rust/cubeb-coreaudio/src/backend/utils.rs b/third_party/rust/cubeb-coreaudio/src/backend/utils.rs
new file mode 100644
index 0000000000..246e337ef5
--- /dev/null
+++ b/third_party/rust/cubeb-coreaudio/src/backend/utils.rs
@@ -0,0 +1,107 @@
+// Copyright © 2018 Mozilla Foundation
+//
+// This program is made available under an ISC-style license. See the
+// accompanying file LICENSE for details.
+use cubeb_backend::SampleFormat as fmt;
+use std::mem;
+
+pub fn allocate_array_by_size<T: Clone + Default>(size: usize) -> Vec<T> {
+ assert_eq!(size % mem::size_of::<T>(), 0);
+ let elements = size / mem::size_of::<T>();
+ allocate_array::<T>(elements)
+}
+
+pub fn allocate_array<T: Clone + Default>(elements: usize) -> Vec<T> {
+ vec![T::default(); elements]
+}
+
+pub fn forget_vec<T>(v: Vec<T>) -> (*mut T, usize) {
+ // Drop any excess capacity by into_boxed_slice.
+ let mut slice = v.into_boxed_slice();
+ let ptr_and_len = (slice.as_mut_ptr(), slice.len());
+ mem::forget(slice); // Leak the memory to the external code.
+ ptr_and_len
+}
+
+#[inline]
+pub fn retake_forgotten_vec<T>(ptr: *mut T, len: usize) -> Vec<T> {
+ unsafe { Vec::from_raw_parts(ptr, len, len) }
+}
+
+pub fn cubeb_sample_size(format: fmt) -> usize {
+ match format {
+ fmt::S16LE | fmt::S16BE | fmt::S16NE => mem::size_of::<i16>(),
+ fmt::Float32LE | fmt::Float32BE | fmt::Float32NE => mem::size_of::<f32>(),
+ }
+}
+
+pub struct Finalizer<F: FnOnce()>(Option<F>);
+
+impl<F: FnOnce()> Finalizer<F> {
+ pub fn dismiss(&mut self) {
+ let _ = self.0.take();
+ assert!(self.0.is_none());
+ }
+}
+
+impl<F: FnOnce()> Drop for Finalizer<F> {
+ fn drop(&mut self) {
+ if let Some(f) = self.0.take() {
+ f();
+ }
+ }
+}
+
+pub fn finally<F: FnOnce()>(f: F) -> Finalizer<F> {
+ Finalizer(Some(f))
+}
+
+#[test]
+fn test_forget_vec_and_retake_it() {
+ let expected: Vec<u32> = (10..20).collect();
+ let leaked = expected.clone();
+ let (ptr, len) = forget_vec(leaked);
+ let retaken = retake_forgotten_vec(ptr, len);
+ for (idx, data) in retaken.iter().enumerate() {
+ assert_eq!(*data, expected[idx]);
+ }
+}
+
+#[test]
+fn test_cubeb_sample_size() {
+ let pairs = [
+ (fmt::S16LE, mem::size_of::<i16>()),
+ (fmt::S16BE, mem::size_of::<i16>()),
+ (fmt::S16NE, mem::size_of::<i16>()),
+ (fmt::Float32LE, mem::size_of::<f32>()),
+ (fmt::Float32BE, mem::size_of::<f32>()),
+ (fmt::Float32NE, mem::size_of::<f32>()),
+ ];
+
+ for pair in pairs.iter() {
+ let (fotmat, size) = pair;
+ assert_eq!(cubeb_sample_size(*fotmat), *size);
+ }
+}
+
+#[test]
+fn test_finally() {
+ let mut x = 0;
+
+ {
+ let y = &mut x;
+ let _finally = finally(|| {
+ *y = 100;
+ });
+ }
+ assert_eq!(x, 100);
+
+ {
+ let y = &mut x;
+ let mut finally = finally(|| {
+ *y = 200;
+ });
+ finally.dismiss();
+ }
+ assert_eq!(x, 100);
+}