@@ -6,6 +6,7 @@ use std::fmt;
6
6
use std:: ops:: Deref ;
7
7
8
8
use PacketList ;
9
+ use AlignmentMarker ;
9
10
10
11
pub type Timestamp = u64 ;
11
12
@@ -14,11 +15,14 @@ const MAX_PACKET_DATA_LENGTH: usize = 0xffffusize;
14
15
/// A collection of simultaneous MIDI events.
15
16
/// See [MIDIPacket](https://developer.apple.com/reference/coremidi/midipacket).
16
17
///
18
+ #[ repr( C ) ]
17
19
pub struct Packet {
18
- // NOTE: At runtime this type must only be used behind references
19
- // that point to valid instances of MIDIPacket.
20
+ // NOTE: At runtime this type must only be used behind immutable references
21
+ // that point to valid instances of MIDIPacket (mutable references would allow mem::swap).
22
+ // This type must NOT implement `Copy`!
23
+ // On ARM, this must be 4-byte aligned.
20
24
inner : PacketInner ,
21
- _do_not_construct : [ u32 ; 0 ] // u32 also guarantees at least 4-byte alignment
25
+ _do_not_construct : AlignmentMarker
22
26
}
23
27
24
28
#[ repr( packed) ]
@@ -56,17 +60,10 @@ impl Packet {
56
60
/// 90 40 7f
57
61
/// ```
58
62
pub fn data ( & self ) -> & [ u8 ] {
59
- let packet = self . packet ( ) ;
60
- let data_ptr = packet. inner . data . as_ptr ( ) ;
61
- let data_len = packet. inner . length as usize ;
63
+ let data_ptr = self . inner . data . as_ptr ( ) ;
64
+ let data_len = self . inner . length as usize ;
62
65
unsafe { :: std:: slice:: from_raw_parts ( data_ptr, data_len) }
63
66
}
64
-
65
- #[ inline]
66
- // TODO: this is wrong, a &MIDIPacket must not exist if the length is smaller than 256 bytes
67
- fn packet ( & self ) -> & Packet {
68
- self
69
- }
70
67
}
71
68
72
69
impl fmt:: Debug for Packet {
@@ -103,24 +100,18 @@ impl PacketList {
103
100
/// Get the number of packets in the list.
104
101
///
105
102
pub fn length ( & self ) -> usize {
106
- self . packet_list ( ) . numPackets as usize
103
+ self . inner . num_packets as usize
107
104
}
108
105
109
106
/// Get an iterator for the packets in the list.
110
107
///
111
108
pub fn iter < ' a > ( & ' a self ) -> PacketListIterator < ' a > {
112
109
PacketListIterator {
113
110
count : self . length ( ) ,
114
- packet_ptr : & self . packet_list ( ) . packet [ 0 ] ,
111
+ packet_ptr : self . inner . data . as_ptr ( ) ,
115
112
_phantom : :: std:: marker:: PhantomData :: default ( ) ,
116
113
}
117
114
}
118
-
119
- #[ inline]
120
- // TODO: This must be removed
121
- fn packet_list ( & self ) -> & MIDIPacketList {
122
- unsafe { & * ( self . as_ptr ( ) as * const MIDIPacketList ) }
123
- }
124
115
}
125
116
126
117
impl fmt:: Debug for PacketList {
@@ -140,7 +131,7 @@ impl fmt::Debug for PacketList {
140
131
141
132
impl fmt:: Display for PacketList {
142
133
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
143
- let result = write ! ( f, "PacketList(len={})" , self . packet_list ( ) . numPackets ) ;
134
+ let result = write ! ( f, "PacketList(len={})" , self . inner . num_packets ) ;
144
135
self . iter ( ) . fold ( result, |prev_result, packet| {
145
136
match prev_result {
146
137
Err ( err) => Err ( err) ,
@@ -274,9 +265,27 @@ impl Deref for PacketBuffer {
274
265
275
266
#[ cfg( test) ]
276
267
mod tests {
268
+ use std:: mem;
277
269
use coremidi_sys:: { MIDITimeStamp , MIDIPacketList } ;
278
270
use PacketList ;
279
271
use PacketBuffer ;
272
+ use Packet ;
273
+ use super :: { PACKET_HEADER_SIZE , PACKET_LIST_HEADER_SIZE } ;
274
+
275
+ #[ test]
276
+ pub fn packet_struct_layout ( ) {
277
+ let expected_align = if cfg ! ( any( target_arch = "arm" , target_arch = "aarch64" ) ) { 4 } else { 1 } ;
278
+ assert_eq ! ( expected_align, mem:: align_of:: <Packet >( ) ) ;
279
+ assert_eq ! ( expected_align, mem:: align_of:: <PacketList >( ) ) ;
280
+
281
+ let dummy_packet: Packet = unsafe { mem:: zeroed ( ) } ;
282
+ let ptr = & dummy_packet as * const _ as * const u8 ;
283
+ assert_eq ! ( PACKET_HEADER_SIZE , dummy_packet. inner. data. as_ptr( ) as usize - ptr as usize ) ;
284
+
285
+ let dummy_packet_list: PacketList = unsafe { mem:: zeroed ( ) } ;
286
+ let ptr = & dummy_packet_list as * const _ as * const u8 ;
287
+ assert_eq ! ( PACKET_LIST_HEADER_SIZE , dummy_packet_list. inner. data. as_ptr( ) as usize - ptr as usize ) ;
288
+ }
280
289
281
290
#[ test]
282
291
pub fn packet_buffer_new ( ) {
0 commit comments