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]
17pub unsafe fn MIDIPacketNext(pkt: *const MIDIPacket) -> *const MIDIPacket {
18 let ptr = ptr::addr_of!((*pkt).data) as *const u8;
22 let ptr_length = ptr::addr_of!((*pkt).length) as *const u16;
23 if cfg!(any(target_arch = "arm", target_arch = "aarch64")) {
24 let offset = ptr_length.read() as isize;
28 ((ptr.offset(offset + 3) as usize) & !(3usize)) as *const MIDIPacket
29 } else {
30 let offset = ptr_length.read_unaligned() as isize;
34 ptr.offset(offset) as *const MIDIPacket
35 }
36}
37
38#[inline]
39pub unsafe fn MIDIEventPacketNext(pkt: *const MIDIEventPacket) -> *const MIDIEventPacket {
40 let ptr = ptr::addr_of!((*pkt).words) as *const u8;
44 let offset = (((*pkt).wordCount as usize) * mem::size_of::<u32>()) as isize;
45 ptr.offset(offset) as *const MIDIEventPacket
46}
47
48#[allow(dead_code)]
49mod static_test {
50 unsafe fn assert_sizes() {
53 use super::{MIDIPacket, MIDIPacketList};
54 use std::mem::{transmute, zeroed};
55
56 let p: MIDIPacket = zeroed();
57 transmute::<_, [u8; 268]>(p);
58
59 let p: MIDIPacketList = zeroed();
60 transmute::<_, [u8; 272]>(p);
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn midi_packet_next() {
70 const BUFFER_SIZE: usize = 65536;
71 let buffer: &mut [u8] = &mut [0; BUFFER_SIZE];
72 let pkt_list_ptr = buffer.as_mut_ptr() as *mut MIDIPacketList;
73
74 let packets = vec![
75 (1, vec![0x90, 0x40, 0x7f]), (2, vec![0x90, 0x41, 0x7f]),
77 ];
78
79 unsafe {
80 let mut pkt_ptr = MIDIPacketListInit(pkt_list_ptr);
81 for pkt in &packets {
82 pkt_ptr = MIDIPacketListAdd(
83 pkt_list_ptr,
84 BUFFER_SIZE as ByteCount,
85 pkt_ptr,
86 pkt.0,
87 pkt.1.len() as ByteCount,
88 pkt.1.as_ptr(),
89 );
90 assert!(!pkt_ptr.is_null());
91 }
92 }
93
94 unsafe {
95 let first_packet = &(*pkt_list_ptr).packet as *const MIDIPacket; let len = (*first_packet).length as usize;
97 assert_eq!(
98 &(*first_packet).data[0..len],
99 &[0x90, 0x40, 0x7f]
100 );
101
102 let second_packet = MIDIPacketNext(first_packet);
103 let ptr_length = ptr::addr_of!((*second_packet).length) as *const u16;
104 let len = ptr_length.read_unaligned() as usize;
105 assert_eq!(
106 &(*second_packet).data[0..len],
107 &[0x90, 0x41, 0x7f]
108 );
109 }
110 }
111
112 #[test]
113 fn midi_event_packet_next() {
114 const BUFFER_SIZE: usize = 65536;
115 let buffer: &mut [u8] = &mut [0; BUFFER_SIZE];
116 let pkt_list_ptr = buffer.as_mut_ptr() as *mut MIDIEventList;
117
118 let packets = vec![
119 (1, vec![10u32, 20]), (2, vec![30u32, 40, 50]),
121 ];
122
123 unsafe {
124 let mut pkt_ptr = MIDIEventListInit(pkt_list_ptr, kMIDIProtocol_2_0 as MIDIProtocolID);
125 for pkt in &packets {
126 pkt_ptr = MIDIEventListAdd(
127 pkt_list_ptr,
128 BUFFER_SIZE as ByteCount,
129 pkt_ptr,
130 pkt.0,
131 pkt.1.len() as ByteCount,
132 pkt.1.as_ptr(),
133 );
134 assert!(!pkt_ptr.is_null());
135 }
136 }
137
138 unsafe {
139 let first_packet = &(*pkt_list_ptr).packet as *const MIDIEventPacket; let len = (*first_packet).wordCount as usize;
141 assert_eq!(
142 &(*first_packet).words[0..len],
143 &[10, 20]
144 );
145
146 let second_packet = MIDIEventPacketNext(first_packet);
147 let len = (*second_packet).wordCount as usize;
148 assert_eq!(
149 &(*second_packet).words[0..len],
150 &[30, 40, 50]
151 );
152 }
153 }
154}