23
23
//! [standard stream framing](https://capnproto.org/encoding.html#serialization-over-a-stream),
24
24
//! where each message is preceded by a segment table indicating the size of its segments.
25
25
26
+ mod no_alloc_slice_segments;
27
+ pub use no_alloc_slice_segments:: NoAllocSliceSegments ;
28
+
26
29
use alloc:: string:: ToString ;
27
30
use alloc:: vec:: Vec ;
28
31
use core:: convert:: TryInto ;
@@ -33,6 +36,7 @@ use crate::message;
33
36
use crate :: private:: units:: BYTES_PER_WORD ;
34
37
use crate :: { Error , Result } ;
35
38
39
+ pub const SEGMENTS_COUNT_LIMIT : usize = 512 ;
36
40
37
41
/// Segments read from a single flat slice of words.
38
42
pub struct SliceSegments < ' a > {
@@ -88,6 +92,22 @@ pub fn read_message_from_flat_slice<'a>(slice: &mut &'a [u8],
88
92
}
89
93
}
90
94
95
+ /// Reads a serialized message (including a segment table) from a flat slice of bytes, without copying.
96
+ /// The slice is allowed to extend beyond the end of the message. On success, updates `slice` to point
97
+ /// to the remaining bytes beyond the end of the message.
98
+ ///
99
+ /// Unlike read_message_from_flat_slice_no_alloc it does not do heap allocation (except for error message)
100
+ ///
101
+ /// ALIGNMENT: If the "unaligned" feature is enabled, then there are no alignment requirements on `slice`.
102
+ /// Otherwise, `slice` must be 8-byte aligned (attempts to read the message will trigger errors).
103
+ pub fn read_message_from_flat_slice_no_alloc < ' a > ( slice : & mut & ' a [ u8 ] ,
104
+ options : message:: ReaderOptions )
105
+ -> Result < message:: Reader < NoAllocSliceSegments < ' a > > > {
106
+ let segments = NoAllocSliceSegments :: try_new ( slice, options) ?;
107
+
108
+ Ok ( message:: Reader :: new ( segments, options) )
109
+ }
110
+
91
111
/// Segments read from a buffer, useful for when you have the message in a buffer and don't want the extra
92
112
/// copy of `read_message`.
93
113
pub struct BufferSegments < T > {
@@ -291,7 +311,7 @@ fn read_segment_table<R>(read: &mut R,
291
311
292
312
let segment_count = u32:: from_le_bytes ( buf[ 0 ..4 ] . try_into ( ) . unwrap ( ) ) . wrapping_add ( 1 ) as usize ;
293
313
294
- if segment_count >= 512 {
314
+ if segment_count >= SEGMENTS_COUNT_LIMIT {
295
315
return Err ( Error :: failed ( format ! ( "Too many segments: {}" , segment_count) ) )
296
316
} else if segment_count == 0 {
297
317
return Err ( Error :: failed ( format ! ( "Too few segments: {}" , segment_count) ) )
0 commit comments