1#![cfg(any(target_os = "macos", target_os = "ios"))]
2
3#![allow(non_snake_case, non_upper_case_globals, non_camel_case_types)]
4
5extern crate core_foundation_sys;
6
7use core_foundation_sys::string::*;
8use core_foundation_sys::data::*;
9use core_foundation_sys::dictionary::*;
10use core_foundation_sys::propertylist::*;
11
12use std::{ptr, mem};
13
14include!("generated.rs");
15
16#[inline]
17#[must_use]
18pub unsafe fn MIDIPacketNext(pkt: *const MIDIPacket) -> *const MIDIPacket {
19 let ptr = ptr::addr_of!((*pkt).data).cast::<u8>();
23 let ptr_length = ptr::addr_of!((*pkt).length).cast::<u16>();
24 if cfg!(any(target_arch = "arm", target_arch = "aarch64")) {
25 let offset = ptr_length.read() as isize;
29 ((ptr.offset(offset + 3) as usize) & !(3usize)) as *const MIDIPacket
30 } else {
31 let offset = ptr_length.read_unaligned() as isize;
35 ptr.offset(offset).cast::<MIDIPacket>()
36 }
37}
38
39#[inline]
40#[must_use]
41pub unsafe fn MIDIEventPacketNext(pkt: *const MIDIEventPacket) -> *const MIDIEventPacket {
42 let ptr = ptr::addr_of!((*pkt).words).cast::<u8>();
46 let offset = (((*pkt).wordCount as usize) * mem::size_of::<u32>()) as isize;
47 ptr.offset(offset).cast::<MIDIEventPacket>()
48}
49
50#[allow(dead_code)]
51mod static_test {
52 unsafe fn assert_sizes() {
55 use super::{MIDIPacket, MIDIPacketList};
56 use std::mem::{transmute, zeroed};
57
58 let p: MIDIPacket = zeroed();
59 transmute::<MIDIPacket, [u8; 268]>(p);
60
61 let p: MIDIPacketList = zeroed();
62 transmute::<MIDIPacketList, [u8; 272]>(p);
63 }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69
70 #[test]
71 fn midi_packet_next() {
72 const BUFFER_SIZE: usize = 65536;
73 let buffer: &mut [u8] = &mut [0; BUFFER_SIZE];
74 let pkt_list_ptr = buffer.as_mut_ptr().cast::<MIDIPacketList>();
75
76 let packets = vec![
77 (1, vec![0x90, 0x40, 0x7f]), (2, vec![0x90, 0x41, 0x7f]),
79 ];
80
81 unsafe {
82 let mut pkt_ptr = MIDIPacketListInit(pkt_list_ptr);
83 for pkt in &packets {
84 pkt_ptr = MIDIPacketListAdd(
85 pkt_list_ptr,
86 BUFFER_SIZE as ByteCount,
87 pkt_ptr,
88 pkt.0,
89 pkt.1.len() as ByteCount,
90 pkt.1.as_ptr(),
91 );
92 assert!(!pkt_ptr.is_null());
93 }
94 }
95
96 unsafe {
97 let first_packet = &(*pkt_list_ptr).packet as *const MIDIPacket; let len = (*first_packet).length as usize;
99 assert_eq!(
100 std::slice::from_raw_parts((*first_packet).data.as_ptr(), len),
101 &[0x90, 0x40, 0x7f]
102 );
103
104 let second_packet = MIDIPacketNext(first_packet);
105 let ptr_length = ptr::addr_of!((*second_packet).length).cast::<u16>();
106 let len = ptr_length.read_unaligned() as usize;
107 assert_eq!(
108 std::slice::from_raw_parts((*second_packet).data.as_ptr(), len),
109 &[0x90, 0x41, 0x7f]
110 );
111 }
112 }
113
114 #[test]
115 fn midi_event_packet_next() {
116 const BUFFER_SIZE: usize = 65536;
117 let buffer: &mut [u8] = &mut [0; BUFFER_SIZE];
118 let pkt_list_ptr = buffer.as_mut_ptr().cast::<MIDIEventList>();
119
120 let packets = vec![
121 (1, vec![10u32, 20]), (2, vec![30u32, 40, 50]),
123 ];
124
125 unsafe {
126 let mut pkt_ptr = MIDIEventListInit(pkt_list_ptr, kMIDIProtocol_2_0 as MIDIProtocolID);
127 for pkt in &packets {
128 pkt_ptr = MIDIEventListAdd(
129 pkt_list_ptr,
130 BUFFER_SIZE as ByteCount,
131 pkt_ptr,
132 pkt.0,
133 pkt.1.len() as ByteCount,
134 pkt.1.as_ptr(),
135 );
136 assert!(!pkt_ptr.is_null());
137 }
138 }
139
140 unsafe {
141 let first_packet = &(*pkt_list_ptr).packet as *const MIDIEventPacket; let len = (*first_packet).wordCount as usize;
143 assert_eq!(
144 std::slice::from_raw_parts((*first_packet).words.as_ptr(), len),
145 &[10, 20]
146 );
147
148 let second_packet = MIDIEventPacketNext(first_packet);
149 let len = (*second_packet).wordCount as usize;
150 assert_eq!(
151 std::slice::from_raw_parts((*second_packet).words.as_ptr(), len),
152 &[30, 40, 50]
153 );
154 }
155 }
156}