@@ -280,6 +280,37 @@ impl ReadVolatile for &[u8] {
280
280
}
281
281
}
282
282
283
+ // WriteVolatile implementation for Vec<u8> is based upon the Write impl for Vec, which
284
+ // defers to Vec::append_elements, after which the below functionality is modelled.
285
+ impl WriteVolatile for Vec < u8 > {
286
+ fn write_volatile < B : BitmapSlice > (
287
+ & mut self ,
288
+ buf : & VolatileSlice < B > ,
289
+ ) -> Result < usize , VolatileMemoryError > {
290
+ let count = buf. len ( ) ;
291
+ self . reserve ( count) ;
292
+ let len = self . len ( ) ;
293
+
294
+ // SAFETY: Calling Vec::reserve() above guarantees the the backing storage of the Vec has
295
+ // length at least `len + count`. This means that self.as_mut_ptr().add(len) remains within
296
+ // the same allocated object, the offset does not exceed isize (as otherwise reserve would
297
+ // have panicked), and does not rely on address space wrapping around.
298
+ // In particular, the entire `count` bytes after `self.as_mut_ptr().add(count)` is
299
+ // contiguously allocated and valid for writes.
300
+ // Lastly, `copy_to_volatile_slice` correctly initialized `copied_len` additional bytes
301
+ // in the Vec's backing storage, and we assert this to be equal to `count`. Additionally,
302
+ // `len + count` is at most the reserved capacity of the vector. Thus the call to `set_len`
303
+ // is safe.
304
+ unsafe {
305
+ let copied_len = copy_from_volatile_slice ( self . as_mut_ptr ( ) . add ( len) , buf, count) ;
306
+
307
+ assert_eq ! ( copied_len, count) ;
308
+ self . set_len ( len + count) ;
309
+ }
310
+ Ok ( count)
311
+ }
312
+ }
313
+
283
314
// ReadVolatile and WriteVolatile implementations for Cursor<T> is modelled after the standard
284
315
// library's implementation (modulo having to inline `Cursor::remaining_slice`, as that's nightly only)
285
316
impl < T > ReadVolatile for Cursor < T >
@@ -561,4 +592,19 @@ mod tests {
561
592
) ;
562
593
assert_eq ! ( cursor. get_ref( ) , & [ 1 , 2 , 3 , 4 , 1 , 2 , 3 ] ) ;
563
594
}
595
+
596
+ #[ test]
597
+ fn test_write_volatile_for_vec ( ) {
598
+ let mut write_buffer = Vec :: new ( ) ;
599
+ let mut input = [ 1 , 2 , 3 , 4 ] ;
600
+
601
+ assert_eq ! (
602
+ write_buffer
603
+ . write_volatile( & VolatileSlice :: from( input. as_mut_slice( ) ) )
604
+ . unwrap( ) ,
605
+ 4
606
+ ) ;
607
+
608
+ assert_eq ! ( & write_buffer, & input) ;
609
+ }
564
610
}
0 commit comments