1
1
#[ cfg( feature = "block" ) ]
2
2
use alloc:: vec:: Vec ;
3
- use core:: ops:: Range ;
3
+ use core:: ops:: { Deref , DerefMut , Range } ;
4
4
use core:: slice;
5
5
use core:: { ffi:: c_void, ptr:: NonNull } ;
6
6
@@ -43,19 +43,19 @@ pub unsafe trait INSData: INSObject {
43
43
44
44
#[ cfg( feature = "block" ) ]
45
45
fn from_vec ( bytes : Vec < u8 > ) -> Id < Self , Self :: Ownership > {
46
+ use core:: mem:: ManuallyDrop ;
47
+
46
48
use objc2_block:: { Block , ConcreteBlock } ;
47
49
48
50
let capacity = bytes. capacity ( ) ;
51
+
49
52
let dealloc = ConcreteBlock :: new ( move |bytes : * mut c_void , len : usize | unsafe {
50
53
// Recreate the Vec and let it drop
51
54
let _ = Vec :: from_raw_parts ( bytes as * mut u8 , len, capacity) ;
52
55
} ) ;
53
56
let dealloc = dealloc. copy ( ) ;
54
57
let dealloc: & Block < ( * mut c_void , usize ) , ( ) > = & dealloc;
55
58
56
- let mut bytes = bytes;
57
- let bytes_ptr = bytes. as_mut_ptr ( ) as * mut c_void ;
58
-
59
59
// GNUStep's NSData `initWithBytesNoCopy:length:deallocator:` has a
60
60
// bug; it forgets to assign the input buffer and length to the
61
61
// instance before it swizzles to NSDataWithDeallocatorBlock.
@@ -72,15 +72,17 @@ pub unsafe trait INSData: INSObject {
72
72
} ;
73
73
#[ cfg( not( gnustep) ) ]
74
74
let cls = Self :: class ( ) ;
75
+
76
+ let mut bytes = ManuallyDrop :: new ( bytes) ;
77
+
75
78
unsafe {
76
79
let obj: * mut Self = msg_send ! [ cls, alloc] ;
77
80
let obj: * mut Self = msg_send ! [
78
81
obj,
79
- initWithBytesNoCopy: bytes_ptr ,
82
+ initWithBytesNoCopy: bytes . as_mut_ptr ( ) as * mut c_void ,
80
83
length: bytes. len( ) ,
81
84
deallocator: dealloc,
82
85
] ;
83
- core:: mem:: forget ( bytes) ;
84
86
Id :: new ( NonNull :: new_unchecked ( obj) )
85
87
}
86
88
}
@@ -98,45 +100,45 @@ unsafe impl INSMutableCopying for NSData {
98
100
type Output = NSMutableData ;
99
101
}
100
102
103
+ impl Deref for NSData {
104
+ type Target = [ u8 ] ;
105
+
106
+ fn deref ( & self ) -> & [ u8 ] {
107
+ self . bytes ( )
108
+ }
109
+ }
110
+
101
111
pub unsafe trait INSMutableData : INSData {
102
112
fn bytes_mut ( & mut self ) -> & mut [ u8 ] {
103
113
let ptr: * mut c_void = unsafe { msg_send ! [ self , mutableBytes] } ;
104
114
// The bytes pointer may be null for length zero
105
- let ( ptr , len ) = if ptr. is_null ( ) {
106
- ( 0x1 as * mut u8 , 0 )
115
+ if ptr. is_null ( ) {
116
+ & mut [ ]
107
117
} else {
108
- ( ptr as * mut u8 , self . len ( ) )
109
- } ;
110
- unsafe { slice:: from_raw_parts_mut ( ptr, len) }
118
+ unsafe { slice:: from_raw_parts_mut ( ptr as * mut u8 , self . len ( ) ) }
119
+ }
111
120
}
112
121
122
+ /// Expands with zeroes, or truncates the buffer.
113
123
fn set_len ( & mut self , len : usize ) {
114
- unsafe {
115
- let _: ( ) = msg_send ! [ self , setLength: len] ;
116
- }
124
+ unsafe { msg_send ! [ self , setLength: len] }
117
125
}
118
126
119
127
fn append ( & mut self , bytes : & [ u8 ] ) {
120
128
let bytes_ptr = bytes. as_ptr ( ) as * const c_void ;
121
- unsafe {
122
- let _: ( ) = msg_send ! [
123
- self ,
124
- appendBytes: bytes_ptr,
125
- length: bytes. len( ) ,
126
- ] ;
127
- }
129
+ unsafe { msg_send ! [ self , appendBytes: bytes_ptr, length: bytes. len( ) ] }
128
130
}
129
131
130
132
fn replace_range ( & mut self , range : Range < usize > , bytes : & [ u8 ] ) {
131
133
let range = NSRange :: from ( range) ;
132
- let bytes_ptr = bytes. as_ptr ( ) as * const c_void ;
134
+ let ptr = bytes. as_ptr ( ) as * const c_void ;
133
135
unsafe {
134
- let _ : ( ) = msg_send ! [
136
+ msg_send ! [
135
137
self ,
136
- replaceBytesInRange: range,
137
- withBytes: bytes_ptr ,
138
- length: bytes. len( ) ,
139
- ] ;
138
+ replaceBytesInRange: range,
139
+ withBytes: ptr ,
140
+ length: bytes. len( ) ,
141
+ ]
140
142
}
141
143
}
142
144
@@ -160,6 +162,20 @@ unsafe impl INSMutableCopying for NSMutableData {
160
162
type Output = NSMutableData ;
161
163
}
162
164
165
+ impl Deref for NSMutableData {
166
+ type Target = [ u8 ] ;
167
+
168
+ fn deref ( & self ) -> & [ u8 ] {
169
+ self . bytes ( )
170
+ }
171
+ }
172
+
173
+ impl DerefMut for NSMutableData {
174
+ fn deref_mut ( & mut self ) -> & mut [ u8 ] {
175
+ self . bytes_mut ( )
176
+ }
177
+ }
178
+
163
179
#[ cfg( test) ]
164
180
mod tests {
165
181
use super :: { INSData , INSMutableData , NSData , NSMutableData } ;
@@ -171,8 +187,8 @@ mod tests {
171
187
fn test_bytes ( ) {
172
188
let bytes = [ 3 , 7 , 16 , 52 , 112 , 19 ] ;
173
189
let data = NSData :: with_bytes ( & bytes) ;
174
- assert ! ( data. len( ) == bytes. len( ) ) ;
175
- assert ! ( data. bytes( ) == bytes) ;
190
+ assert_eq ! ( data. len( ) , bytes. len( ) ) ;
191
+ assert_eq ! ( data. bytes( ) , bytes) ;
176
192
}
177
193
178
194
#[ test]
@@ -185,43 +201,43 @@ mod tests {
185
201
fn test_bytes_mut ( ) {
186
202
let mut data = NSMutableData :: with_bytes ( & [ 7 , 16 ] ) ;
187
203
data. bytes_mut ( ) [ 0 ] = 3 ;
188
- assert ! ( data. bytes( ) == [ 3 , 16 ] ) ;
204
+ assert_eq ! ( data. bytes( ) , [ 3 , 16 ] ) ;
189
205
}
190
206
191
207
#[ test]
192
208
fn test_set_len ( ) {
193
209
let mut data = NSMutableData :: with_bytes ( & [ 7 , 16 ] ) ;
194
210
data. set_len ( 4 ) ;
195
- assert ! ( data. len( ) == 4 ) ;
196
- assert ! ( data. bytes( ) == [ 7 , 16 , 0 , 0 ] ) ;
211
+ assert_eq ! ( data. len( ) , 4 ) ;
212
+ assert_eq ! ( data. bytes( ) , [ 7 , 16 , 0 , 0 ] ) ;
197
213
198
214
data. set_len ( 1 ) ;
199
- assert ! ( data. len( ) == 1 ) ;
200
- assert ! ( data. bytes( ) == [ 7 ] ) ;
215
+ assert_eq ! ( data. len( ) , 1 ) ;
216
+ assert_eq ! ( data. bytes( ) , [ 7 ] ) ;
201
217
}
202
218
203
219
#[ test]
204
220
fn test_append ( ) {
205
221
let mut data = NSMutableData :: with_bytes ( & [ 7 , 16 ] ) ;
206
222
data. append ( & [ 3 , 52 ] ) ;
207
- assert ! ( data. len( ) == 4 ) ;
208
- assert ! ( data. bytes( ) == [ 7 , 16 , 3 , 52 ] ) ;
223
+ assert_eq ! ( data. len( ) , 4 ) ;
224
+ assert_eq ! ( data. bytes( ) , [ 7 , 16 , 3 , 52 ] ) ;
209
225
}
210
226
211
227
#[ test]
212
228
fn test_replace ( ) {
213
229
let mut data = NSMutableData :: with_bytes ( & [ 7 , 16 ] ) ;
214
230
data. replace_range ( 0 ..0 , & [ 3 ] ) ;
215
- assert ! ( data. bytes( ) == [ 3 , 7 , 16 ] ) ;
231
+ assert_eq ! ( data. bytes( ) , [ 3 , 7 , 16 ] ) ;
216
232
217
233
data. replace_range ( 1 ..2 , & [ 52 , 13 ] ) ;
218
- assert ! ( data. bytes( ) == [ 3 , 52 , 13 , 16 ] ) ;
234
+ assert_eq ! ( data. bytes( ) , [ 3 , 52 , 13 , 16 ] ) ;
219
235
220
236
data. replace_range ( 2 ..4 , & [ 6 ] ) ;
221
- assert ! ( data. bytes( ) == [ 3 , 52 , 6 ] ) ;
237
+ assert_eq ! ( data. bytes( ) , [ 3 , 52 , 6 ] ) ;
222
238
223
239
data. set_bytes ( & [ 8 , 17 ] ) ;
224
- assert ! ( data. bytes( ) == [ 8 , 17 ] ) ;
240
+ assert_eq ! ( data. bytes( ) , [ 8 , 17 ] ) ;
225
241
}
226
242
227
243
#[ cfg( feature = "block" ) ]
0 commit comments