1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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);
}
|