@@ -47,29 +47,36 @@ macro_rules! encode_tlv {
47
47
} }
48
48
}
49
49
50
- macro_rules! encode_varint_length_prefixed_tlv {
51
- ( $stream : expr , { $( ( $type: expr, $field: expr) ) ,* } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* } ) => { {
52
- use util:: ser:: { BigSize , LengthCalculatingWriter } ;
50
+ macro_rules! get_varint_length_prefixed_tlv_length {
51
+ ( { $( ( $type: expr, $field: expr) ) ,* } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $ ( , ) * } ) => { {
52
+ use util:: ser:: LengthCalculatingWriter ;
53
53
#[ allow( unused_mut) ]
54
54
let mut len = LengthCalculatingWriter ( 0 ) ;
55
55
{
56
56
$(
57
- BigSize ( $type) . write( & mut len) ? ;
57
+ BigSize ( $type) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
58
58
let field_len = $field. serialized_length( ) ;
59
- BigSize ( field_len as u64 ) . write( & mut len) ? ;
59
+ BigSize ( field_len as u64 ) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
60
60
len. 0 += field_len;
61
61
) *
62
62
$(
63
63
if let Some ( ref field) = $optional_field {
64
- BigSize ( $optional_type) . write( & mut len) ? ;
64
+ BigSize ( $optional_type) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
65
65
let field_len = field. serialized_length( ) ;
66
- BigSize ( field_len as u64 ) . write( & mut len) ? ;
66
+ BigSize ( field_len as u64 ) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
67
67
len. 0 += field_len;
68
68
}
69
69
) *
70
70
}
71
+ len. 0
72
+ } }
73
+ }
71
74
72
- BigSize ( len. 0 as u64 ) . write( $stream) ?;
75
+ macro_rules! encode_varint_length_prefixed_tlv {
76
+ ( $stream: expr, { $( ( $type: expr, $field: expr) ) ,* } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* } ) => { {
77
+ use util:: ser:: BigSize ;
78
+ let len = get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } ) ;
79
+ BigSize ( len as u64 ) . write( $stream) ?;
73
80
encode_tlv!( $stream, { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } ) ;
74
81
} }
75
82
}
@@ -167,13 +174,28 @@ macro_rules! impl_writeable {
167
174
if $len != 0 {
168
175
use util:: ser:: LengthCalculatingWriter ;
169
176
let mut len_calc = LengthCalculatingWriter ( 0 ) ;
170
- $( self . $field. write( & mut len_calc) ? ; ) *
177
+ $( self . $field. write( & mut len_calc) . expect ( "No in-memory data may fail to serialize" ) ; ) *
171
178
assert_eq!( len_calc. 0 , $len) ;
172
179
}
173
180
}
174
181
$( self . $field. write( w) ?; ) *
175
182
Ok ( ( ) )
176
183
}
184
+
185
+ #[ inline]
186
+ fn serialized_length( & self ) -> usize {
187
+ if $len == 0 || cfg!( any( test, feature = "fuzztarget" ) ) {
188
+ let mut len_calc = 0 ;
189
+ $( len_calc += self . $field. serialized_length( ) ; ) *
190
+ if $len != 0 {
191
+ // In tests, assert that the hard-coded length matches the actual one
192
+ assert_eq!( len_calc, $len) ;
193
+ } else {
194
+ return len_calc;
195
+ }
196
+ }
197
+ $len
198
+ }
177
199
}
178
200
179
201
impl :: util:: ser:: Readable for $st {
@@ -186,7 +208,7 @@ macro_rules! impl_writeable {
186
208
}
187
209
}
188
210
macro_rules! impl_writeable_len_match {
189
- ( $struct: ident, $cmp: tt, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
211
+ ( $struct: ident, $cmp: tt, ( $calc_len : expr ) , { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
190
212
impl Writeable for $struct {
191
213
fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , :: std:: io:: Error > {
192
214
let len = match * self {
@@ -198,12 +220,29 @@ macro_rules! impl_writeable_len_match {
198
220
// In tests, assert that the hard-coded length matches the actual one
199
221
use util:: ser:: LengthCalculatingWriter ;
200
222
let mut len_calc = LengthCalculatingWriter ( 0 ) ;
201
- $( self . $field. write( & mut len_calc) ? ; ) *
223
+ $( self . $field. write( & mut len_calc) . expect ( "No in-memory data may fail to serialize" ) ; ) *
202
224
assert!( len_calc. 0 $cmp len) ;
203
225
}
204
226
$( self . $field. write( w) ?; ) *
205
227
Ok ( ( ) )
206
228
}
229
+
230
+ #[ inline]
231
+ fn serialized_length( & self ) -> usize {
232
+ if $calc_len || cfg!( any( test, feature = "fuzztarget" ) ) {
233
+ let mut len_calc = 0 ;
234
+ $( len_calc += self . $field. serialized_length( ) ; ) *
235
+ if !$calc_len {
236
+ assert_eq!( len_calc, match * self {
237
+ $( $match => $length, ) *
238
+ } ) ;
239
+ }
240
+ return len_calc
241
+ }
242
+ match * self {
243
+ $( $match => $length, ) *
244
+ }
245
+ }
207
246
}
208
247
209
248
impl :: util:: ser:: Readable for $struct {
@@ -214,8 +253,11 @@ macro_rules! impl_writeable_len_match {
214
253
}
215
254
}
216
255
} ;
256
+ ( $struct: ident, $cmp: tt, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
257
+ impl_writeable_len_match!( $struct, $cmp, ( true ) , { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
258
+ } ;
217
259
( $struct: ident, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
218
- impl_writeable_len_match!( $struct, ==, { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
260
+ impl_writeable_len_match!( $struct, ==, ( false ) , { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
219
261
}
220
262
}
221
263
@@ -319,6 +361,14 @@ macro_rules! _write_tlv_fields {
319
361
write_tlv_fields!( $stream, { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* , $( ( $optional_type_2, $optional_field_2) ) ,* } ) ;
320
362
}
321
363
}
364
+ macro_rules! _get_tlv_len {
365
+ ( { $( ( $type: expr, $field: expr) ) ,* $( , ) * } , { } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $( , ) * } ) => {
366
+ get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } )
367
+ } ;
368
+ ( { $( ( $type: expr, $field: expr) ) ,* $( , ) * } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $( , ) * } , { $( ( $optional_type_2: expr, $optional_field_2: expr) ) ,* $( , ) * } ) => {
369
+ get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* , $( ( $optional_type_2, $optional_field_2) ) ,* } )
370
+ }
371
+ }
322
372
macro_rules! _read_tlv_fields {
323
373
( $stream: expr, { $( ( $reqtype: expr, $reqfield: ident) ) ,* $( , ) * } , { } , { $( ( $type: expr, $field: ident) ) ,* $( , ) * } ) => {
324
374
read_tlv_fields!( $stream, { $( ( $reqtype, $reqfield) ) ,* } , { $( ( $type, $field) ) ,* } ) ;
@@ -346,6 +396,21 @@ macro_rules! impl_writeable_tlv_based {
346
396
} ) ;
347
397
Ok ( ( ) )
348
398
}
399
+
400
+ #[ inline]
401
+ fn serialized_length( & self ) -> usize {
402
+ let len = _get_tlv_len!( {
403
+ $( ( $reqtype, self . $reqfield) ) ,*
404
+ } , {
405
+ $( ( $type, self . $field) ) ,*
406
+ } , {
407
+ $( ( $vectype, Some ( :: util:: ser:: VecWriteWrapper ( & self . $vecfield) ) ) ) ,*
408
+ } ) ;
409
+ use util:: ser:: { BigSize , LengthCalculatingWriter } ;
410
+ let mut len_calc = LengthCalculatingWriter ( 0 ) ;
411
+ BigSize ( len as u64 ) . write( & mut len_calc) . expect( "No in-memory data may fail to serialize" ) ;
412
+ len + len_calc. 0
413
+ }
349
414
}
350
415
351
416
impl :: util:: ser:: Readable for $st {
0 commit comments