@@ -4,6 +4,10 @@ use std::io::Write as _;
4
4
5
5
use re_log_types:: LogMsg ;
6
6
7
+ use crate :: { Compression , EncodingOptions } ;
8
+
9
+ // ----------------------------------------------------------------------------
10
+
7
11
/// On failure to encode or serialize a [`LogMsg`].
8
12
#[ derive( thiserror:: Error , Debug ) ]
9
13
pub enum EncodeError {
@@ -26,11 +30,12 @@ pub enum EncodeError {
26
30
// ----------------------------------------------------------------------------
27
31
28
32
pub fn encode_to_bytes < ' a > (
33
+ options : EncodingOptions ,
29
34
msgs : impl IntoIterator < Item = & ' a LogMsg > ,
30
35
) -> Result < Vec < u8 > , EncodeError > {
31
36
let mut bytes: Vec < u8 > = vec ! [ ] ;
32
37
{
33
- let mut encoder = Encoder :: new ( std:: io:: Cursor :: new ( & mut bytes) ) ?;
38
+ let mut encoder = Encoder :: new ( options , std:: io:: Cursor :: new ( & mut bytes) ) ?;
34
39
for msg in msgs {
35
40
encoder. append ( msg) ?;
36
41
}
@@ -41,14 +46,42 @@ pub fn encode_to_bytes<'a>(
41
46
42
47
// ----------------------------------------------------------------------------
43
48
44
- /// Encode a stream of [`LogMsg`] into an `.rrd` file.
45
- pub struct Encoder < W : std:: io:: Write > {
46
- /// Set to None when finished.
49
+ struct Lz4Compressor < W : std:: io:: Write > {
50
+ /// `None` if finished.
47
51
lz4_encoder : Option < lz4_flex:: frame:: FrameEncoder < W > > ,
48
- buffer : Vec < u8 > ,
49
52
}
50
53
51
- impl < W : std:: io:: Write > Drop for Encoder < W > {
54
+ impl < W : std:: io:: Write > Lz4Compressor < W > {
55
+ pub fn new ( write : W ) -> Self {
56
+ Self {
57
+ lz4_encoder : Some ( lz4_flex:: frame:: FrameEncoder :: new ( write) ) ,
58
+ }
59
+ }
60
+
61
+ pub fn write ( & mut self , bytes : & [ u8 ] ) -> Result < ( ) , EncodeError > {
62
+ if let Some ( lz4_encoder) = & mut self . lz4_encoder {
63
+ lz4_encoder
64
+ . write_all ( bytes)
65
+ . map_err ( EncodeError :: Lz4Write ) ?;
66
+
67
+ Ok ( ( ) )
68
+ } else {
69
+ Err ( EncodeError :: AlreadyFinished )
70
+ }
71
+ }
72
+
73
+ pub fn finish ( & mut self ) -> Result < ( ) , EncodeError > {
74
+ if let Some ( lz4_encoder) = self . lz4_encoder . take ( ) {
75
+ lz4_encoder. finish ( ) . map_err ( EncodeError :: Lz4Finish ) ?;
76
+ Ok ( ( ) )
77
+ } else {
78
+ re_log:: warn!( "Encoder::finish called twice" ) ;
79
+ Ok ( ( ) )
80
+ }
81
+ }
82
+ }
83
+
84
+ impl < W : std:: io:: Write > Drop for Lz4Compressor < W > {
52
85
fn drop ( & mut self ) {
53
86
if self . lz4_encoder . is_some ( ) {
54
87
re_log:: warn!( "Encoder dropped without calling finish()!" ) ;
@@ -59,73 +92,107 @@ impl<W: std::io::Write> Drop for Encoder<W> {
59
92
}
60
93
}
61
94
95
+ #[ allow( clippy:: large_enum_variant) ]
96
+ enum Compressor < W : std:: io:: Write > {
97
+ Off ( W ) ,
98
+ Lz4 ( Lz4Compressor < W > ) ,
99
+ }
100
+
101
+ impl < W : std:: io:: Write > Compressor < W > {
102
+ pub fn new ( compression : Compression , write : W ) -> Self {
103
+ match compression {
104
+ Compression :: Off => Self :: Off ( write) ,
105
+ Compression :: LZ4 => Self :: Lz4 ( Lz4Compressor :: new ( write) ) ,
106
+ }
107
+ }
108
+
109
+ pub fn write ( & mut self , bytes : & [ u8 ] ) -> Result < ( ) , EncodeError > {
110
+ let len = ( bytes. len ( ) as u64 ) . to_le_bytes ( ) ;
111
+
112
+ match self {
113
+ Compressor :: Off ( write) => {
114
+ write. write_all ( & len) . map_err ( EncodeError :: Write ) ?;
115
+ write. write_all ( bytes) . map_err ( EncodeError :: Write )
116
+ }
117
+ Compressor :: Lz4 ( lz4) => {
118
+ lz4. write ( & len) ?;
119
+ lz4. write ( bytes)
120
+ }
121
+ }
122
+ }
123
+
124
+ pub fn finish ( & mut self ) -> Result < ( ) , EncodeError > {
125
+ match self {
126
+ Compressor :: Off ( _) => Ok ( ( ) ) ,
127
+ Compressor :: Lz4 ( lz4) => lz4. finish ( ) ,
128
+ }
129
+ }
130
+ }
131
+
132
+ // ----------------------------------------------------------------------------
133
+
134
+ /// Encode a stream of [`LogMsg`] into an `.rrd` file.
135
+ pub struct Encoder < W : std:: io:: Write > {
136
+ compressor : Compressor < W > ,
137
+ buffer : Vec < u8 > ,
138
+ }
139
+
62
140
impl < W : std:: io:: Write > Encoder < W > {
63
- pub fn new ( mut write : W ) -> Result < Self , EncodeError > {
141
+ pub fn new ( options : EncodingOptions , mut write : W ) -> Result < Self , EncodeError > {
64
142
let rerun_version = re_build_info:: CrateVersion :: parse ( env ! ( "CARGO_PKG_VERSION" ) ) ;
65
143
66
- write. write_all ( b"RRF0" ) . map_err ( EncodeError :: Write ) ?;
144
+ write
145
+ . write_all ( crate :: RRD_HEADER )
146
+ . map_err ( EncodeError :: Write ) ?;
67
147
write
68
148
. write_all ( & rerun_version. to_bytes ( ) )
69
149
. map_err ( EncodeError :: Write ) ?;
150
+ write
151
+ . write_all ( & options. to_bytes ( ) )
152
+ . map_err ( EncodeError :: Write ) ?;
70
153
71
- let lz4_encoder = lz4_flex:: frame:: FrameEncoder :: new ( write) ;
154
+ match options. serializer {
155
+ crate :: Serializer :: MsgPack => { }
156
+ }
72
157
73
158
Ok ( Self {
74
- lz4_encoder : Some ( lz4_encoder ) ,
159
+ compressor : Compressor :: new ( options . compression , write ) ,
75
160
buffer : vec ! [ ] ,
76
161
} )
77
162
}
78
163
79
164
pub fn append ( & mut self , message : & LogMsg ) -> Result < ( ) , EncodeError > {
80
- let Self {
81
- lz4_encoder,
82
- buffer,
83
- } = self ;
165
+ let Self { compressor, buffer } = self ;
84
166
85
- if let Some ( lz4_encoder) = lz4_encoder {
86
- buffer. clear ( ) ;
87
- rmp_serde:: encode:: write_named ( buffer, message) ?;
167
+ buffer. clear ( ) ;
168
+ rmp_serde:: encode:: write_named ( buffer, message) ?;
88
169
89
- lz4_encoder
90
- . write_all ( & ( buffer. len ( ) as u64 ) . to_le_bytes ( ) )
91
- . map_err ( EncodeError :: Lz4Write ) ?;
92
- lz4_encoder
93
- . write_all ( buffer)
94
- . map_err ( EncodeError :: Lz4Write ) ?;
95
-
96
- Ok ( ( ) )
97
- } else {
98
- Err ( EncodeError :: AlreadyFinished )
99
- }
170
+ compressor. write ( buffer)
100
171
}
101
172
102
173
pub fn finish ( & mut self ) -> Result < ( ) , EncodeError > {
103
- if let Some ( lz4_encoder) = self . lz4_encoder . take ( ) {
104
- lz4_encoder. finish ( ) . map_err ( EncodeError :: Lz4Finish ) ?;
105
- Ok ( ( ) )
106
- } else {
107
- re_log:: warn!( "Encoder::finish called twice" ) ;
108
- Ok ( ( ) )
109
- }
174
+ self . compressor . finish ( )
110
175
}
111
176
}
112
177
113
178
pub fn encode < ' a > (
179
+ options : EncodingOptions ,
114
180
messages : impl Iterator < Item = & ' a LogMsg > ,
115
181
write : & mut impl std:: io:: Write ,
116
182
) -> Result < ( ) , EncodeError > {
117
- let mut encoder = Encoder :: new ( write) ?;
183
+ let mut encoder = Encoder :: new ( options , write) ?;
118
184
for message in messages {
119
185
encoder. append ( message) ?;
120
186
}
121
187
encoder. finish ( )
122
188
}
123
189
124
190
pub fn encode_owned (
191
+ options : EncodingOptions ,
125
192
messages : impl Iterator < Item = LogMsg > ,
126
193
write : impl std:: io:: Write ,
127
194
) -> Result < ( ) , EncodeError > {
128
- let mut encoder = Encoder :: new ( write) ?;
195
+ let mut encoder = Encoder :: new ( options , write) ?;
129
196
for message in messages {
130
197
encoder. append ( & message) ?;
131
198
}
0 commit comments