@@ -57,7 +57,9 @@ impl<T, C: Container> Message<T, C> {
57
57
}
58
58
59
59
// Instructions for serialization of `Message`.
60
- // Intended to swap out the constraint on `C` for `C: Bytesable`.
60
+ //
61
+ // Serialization of each field is meant to be `u64` aligned, so that each has the ability
62
+ // to be decoded using safe transmutation, e.g. `bytemuck`.
61
63
impl < T , C > crate :: communication:: Bytesable for Message < T , C >
62
64
where
63
65
T : Serialize + for < ' a > Deserialize < ' a > ,
@@ -69,24 +71,28 @@ where
69
71
let from: usize = slice. read_u64 :: < byteorder:: LittleEndian > ( ) . unwrap ( ) . try_into ( ) . unwrap ( ) ;
70
72
let seq: usize = slice. read_u64 :: < byteorder:: LittleEndian > ( ) . unwrap ( ) . try_into ( ) . unwrap ( ) ;
71
73
let time: T = :: bincode:: deserialize_from ( & mut slice) . expect ( "bincode::deserialize() failed" ) ;
72
- let bytes_read = bytes. len ( ) - slice. len ( ) ;
74
+ let time_size = :: bincode:: serialized_size ( & time) . expect ( "bincode::serialized_size() failed" ) as usize ;
75
+ // We expect to find the `data` payload at `8 + 8 + round_up(time_size)`;
76
+ let bytes_read = 8 + 8 + ( ( time_size + 7 ) & !7 ) ;
73
77
bytes. extract_to ( bytes_read) ;
74
78
let data: C = ContainerBytes :: from_bytes ( bytes) ;
75
79
Self { time, data, from, seq }
76
80
}
77
81
78
82
fn length_in_bytes ( & self ) -> usize {
83
+ let time_size = :: bincode:: serialized_size ( & self . time ) . expect ( "bincode::serialized_size() failed" ) as usize ;
79
84
// 16 comes from the two `u64` fields: `from` and `seq`.
80
- 16 +
81
- :: bincode:: serialized_size ( & self . time ) . expect ( "bincode::serialized_size() failed" ) as usize +
82
- self . data . length_in_bytes ( )
85
+ 16 + ( ( time_size + 7 ) & !7 ) + self . data . length_in_bytes ( )
83
86
}
84
87
85
88
fn into_bytes < W : :: std:: io:: Write > ( & self , writer : & mut W ) {
86
89
use byteorder:: WriteBytesExt ;
87
90
writer. write_u64 :: < byteorder:: LittleEndian > ( self . from . try_into ( ) . unwrap ( ) ) . unwrap ( ) ;
88
91
writer. write_u64 :: < byteorder:: LittleEndian > ( self . seq . try_into ( ) . unwrap ( ) ) . unwrap ( ) ;
89
92
:: bincode:: serialize_into ( & mut * writer, & self . time ) . expect ( "bincode::serialize_into() failed" ) ;
93
+ let time_size = :: bincode:: serialized_size ( & self . time ) . expect ( "bincode::serialized_size() failed" ) as usize ;
94
+ let time_slop = ( ( time_size + 7 ) & !7 ) - time_size;
95
+ writer. write ( & [ 0u8 ; 8 ] [ ..time_slop] ) . unwrap ( ) ;
90
96
self . data . into_bytes ( & mut * writer) ;
91
97
}
92
98
}
@@ -106,6 +112,8 @@ pub trait ContainerBytes {
106
112
107
113
mod implementations {
108
114
115
+ use std:: io:: Write ;
116
+
109
117
use serde:: { Serialize , Deserialize } ;
110
118
use crate :: dataflow:: channels:: ContainerBytes ;
111
119
@@ -115,11 +123,16 @@ mod implementations {
115
123
}
116
124
117
125
fn length_in_bytes ( & self ) -> usize {
118
- :: bincode:: serialized_size ( & self ) . expect ( "bincode::serialized_size() failed" ) as usize
126
+ let length = :: bincode:: serialized_size ( & self ) . expect ( "bincode::serialized_size() failed" ) as usize ;
127
+ ( length + 7 ) & !7
119
128
}
120
129
121
- fn into_bytes < W : :: std:: io:: Write > ( & self , writer : & mut W ) {
122
- :: bincode:: serialize_into ( writer, & self ) . expect ( "bincode::serialize_into() failed" ) ;
130
+ fn into_bytes < W : Write > ( & self , writer : & mut W ) {
131
+ let mut counter = WriteCounter :: new ( writer) ;
132
+ :: bincode:: serialize_into ( & mut counter, & self ) . expect ( "bincode::serialize_into() failed" ) ;
133
+ let written = counter. count ;
134
+ let written_slop = ( ( written + 7 ) & !7 ) - written;
135
+ counter. write ( & [ 0u8 ; 8 ] [ ..written_slop] ) . unwrap ( ) ;
123
136
}
124
137
}
125
138
@@ -130,11 +143,60 @@ mod implementations {
130
143
}
131
144
132
145
fn length_in_bytes ( & self ) -> usize {
133
- :: bincode:: serialized_size ( & self ) . expect ( "bincode::serialized_size() failed" ) as usize
146
+ let length = :: bincode:: serialized_size ( & self ) . expect ( "bincode::serialized_size() failed" ) as usize ;
147
+ ( length + 7 ) & !7
148
+ }
149
+
150
+ fn into_bytes < W : Write > ( & self , writer : & mut W ) {
151
+ let mut counter = WriteCounter :: new ( writer) ;
152
+ :: bincode:: serialize_into ( & mut counter, & self ) . expect ( "bincode::serialize_into() failed" ) ;
153
+ let written = counter. count ;
154
+ let written_slop = ( ( written + 7 ) & !7 ) - written;
155
+ counter. write ( & [ 0u8 ; 8 ] [ ..written_slop] ) . unwrap ( ) ;
156
+ }
157
+ }
158
+
159
+ use write_counter:: WriteCounter ;
160
+ /// A `Write` wrapper that counts the bytes written.
161
+ mod write_counter {
162
+
163
+ use :: std:: io:: { Write , IoSlice , Result } ;
164
+ use std:: fmt:: Arguments ;
165
+
166
+ /// A write wrapper that tracks the bytes written.
167
+ pub struct WriteCounter < W > {
168
+ inner : W ,
169
+ pub count : usize ,
170
+ }
171
+
172
+ impl < W > WriteCounter < W > {
173
+ /// Creates a new counter wrapper from a writer.
174
+ pub fn new ( inner : W ) -> Self {
175
+ Self { inner, count : 0 }
176
+ }
134
177
}
135
178
136
- fn into_bytes < W : :: std:: io:: Write > ( & self , writer : & mut W ) {
137
- :: bincode:: serialize_into ( writer, & self ) . expect ( "bincode::serialize_into() failed" ) ;
179
+ impl < W : Write > Write for WriteCounter < W > {
180
+ fn write ( & mut self , buf : & [ u8 ] ) -> Result < usize > {
181
+ let written = self . inner . write ( buf) ?;
182
+ self . count += written;
183
+ Ok ( written)
184
+ }
185
+ fn flush ( & mut self ) -> Result < ( ) > {
186
+ self . inner . flush ( )
187
+ }
188
+ fn write_vectored ( & mut self , bufs : & [ IoSlice < ' _ > ] ) -> Result < usize > {
189
+ let written = self . inner . write_vectored ( bufs) ?;
190
+ self . count += written;
191
+ Ok ( written)
192
+ }
193
+ fn write_all ( & mut self , buf : & [ u8 ] ) -> Result < ( ) > {
194
+ self . count += buf. len ( ) ;
195
+ self . inner . write_all ( buf)
196
+ }
197
+ fn write_fmt ( & mut self , _fmt : Arguments < ' _ > ) -> Result < ( ) > {
198
+ unimplemented ! ( )
199
+ }
138
200
}
139
201
}
140
202
}
0 commit comments