33//! Abomonation takes typed elements and simply writes their contents as binary.
44//! It then gives the element the opportunity to serialize more data, which is
55//! useful for types with owned memory such as `String` and `Vec`.
6- //! The result is effectively a copy of reachable memory, where pointers are zero-ed out and vector
7- //! capacities are set to the vector length.
6+ //! The result is effectively a copy of reachable memory.
87//! Deserialization results in a shared reference to the type, pointing at the binary data itself.
98//!
109//! Abomonation does several unsafe things, and should ideally be used only through the methods
1110//! `encode` and `decode` on types implementing the `Abomonation` trait. Implementing the
12- //! `Abomonation` trait is highly discouraged, unless you use the `unsafe_abomonate!` macro, which
13- //! is only mostly discouraged.
11+ //! `Abomonation` trait is highly discouraged; instead, you can use the [`abomonation_derive` crate](https://crates.io/crates/abomonation_derive).
1412//!
15- //! **Very important**: Abomonation reproduces the memory as laid out by the serializer, which can
13+ //! **Very important**: Abomonation reproduces the memory as laid out by the serializer, which will
1614//! reveal architectural variations. Data encoded on a 32bit big-endian machine will not decode
1715//! properly on a 64bit little-endian machine. Moreover, it could result in undefined behavior if
1816//! the deserialization results in invalid typed data. Please do not do this.
@@ -46,10 +44,11 @@ pub mod abomonated;
4644
4745/// Encodes a typed reference into a binary buffer.
4846///
49- /// `encode` will transmute `typed` to binary and write its contents to `bytes`. It then offers the
50- /// element the opportunity to serialize more data. Having done that,
51- /// it offers the element the opportunity to "tidy up", in which the element can erasing things
52- /// like local memory addresses that it would be impolite to share.
47+ /// # Safety
48+ ///
49+ /// This method is unsafe because it is unsafe to transmute typed allocations to binary.
50+ /// Furthermore, Rust currently indicates that it is undefined behavior to observe padding
51+ /// bytes, which will happen when we `memmcpy` structs which contain padding bytes.
5352///
5453/// # Examples
5554/// ```
@@ -85,13 +84,21 @@ pub unsafe fn encode<T: Abomonation, W: Write>(typed: &T, write: &mut W) -> IORe
8584/// The return value is either a pair of the typed reference `&T` and the remaining `&mut [u8]`
8685/// binary data, or `None` if decoding failed due to lack of data.
8786///
88- /// #Safety
87+ /// # Safety
8988///
90- /// `decode` is unsafe due to a number of unchecked invariants. Decoding arbitrary `&[u8]` data can
91- /// result in invalid utf8 strings, enums with invalid discriminants, etc. `decode` does presently
89+ /// The `decode` method is unsafe due to a number of unchecked invariants.
90+ ///
91+ /// Decoding arbitrary `&[u8]` data can
92+ /// result in invalid utf8 strings, enums with invalid discriminants, etc. `decode` *does*
9293/// perform bounds checks, as part of determining if enough data are present to completely decode,
93- /// and while it should only write to its `&mut [u8]` argument, invalid utf8 and enums are undefined
94- /// behavior. Please do not decode data that was not encoded by the corresponding implementation.
94+ /// and while it should only write within the bounds of its `&mut [u8]` argument, the use of invalid
95+ /// utf8 and enums are undefined behavior.
96+ ///
97+ /// Please do not decode data that was not encoded by the corresponding implementation.
98+ ///
99+ /// In addition, `decode` does not ensure that the bytes representing types will be correctly aligned.
100+ /// On several platforms unaligned reads are undefined behavior, but on several other platforms they
101+ /// are only a performance penalty.
95102///
96103/// # Examples
97104/// ```
@@ -127,6 +134,10 @@ pub unsafe fn decode<T: Abomonation>(bytes: &mut [u8]) -> Option<(&T, &mut [u8])
127134}
128135
129136/// Reports the number of bytes required to encode `self`.
137+ ///
138+ /// # Safety
139+ ///
140+ /// The `measure` method is safe. It neither produces nor consults serialized representations.
130141#[ inline]
131142pub fn measure < T : Abomonation > ( typed : & T ) -> usize {
132143 mem:: size_of :: < T > ( ) + typed. extent ( )
@@ -137,7 +148,7 @@ pub fn measure<T: Abomonation>(typed: &T) -> usize {
137148/// The default implementations for Abomonation's methods are all empty. Many types have no owned
138149/// data to transcribe. Some do, however, and need to carefully implement these unsafe methods.
139150///
140- /// #Safety
151+ /// # Safety
141152///
142153/// Abomonation has no safe methods. Please do not call them. They should be called only by
143154/// `encode` and `decode`, each of which impose restrictions on ownership and lifetime of the data
@@ -490,7 +501,7 @@ impl<T: Abomonation> Abomonation for Box<T> {
490501 }
491502}
492503
493- // currently enables UB , by exposing padding bytes
504+ // This method currently enables undefined behavior , by exposing padding bytes.
494505#[ inline] unsafe fn typed_to_bytes < T > ( slice : & [ T ] ) -> & [ u8 ] {
495506 std:: slice:: from_raw_parts ( slice. as_ptr ( ) as * const u8 , slice. len ( ) * mem:: size_of :: < T > ( ) )
496507}
0 commit comments