@@ -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,29 @@ 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) ;
179
+ assert_eq!( self . serialized_length( ) , $len) ;
172
180
}
173
181
}
174
182
$( self . $field. write( w) ?; ) *
175
183
Ok ( ( ) )
176
184
}
185
+
186
+ #[ inline]
187
+ fn serialized_length( & self ) -> usize {
188
+ if $len == 0 || cfg!( any( test, feature = "fuzztarget" ) ) {
189
+ let mut len_calc = 0 ;
190
+ $( len_calc += self . $field. serialized_length( ) ; ) *
191
+ if $len != 0 {
192
+ // In tests, assert that the hard-coded length matches the actual one
193
+ assert_eq!( len_calc, $len) ;
194
+ } else {
195
+ return len_calc;
196
+ }
197
+ }
198
+ $len
199
+ }
177
200
}
178
201
179
202
impl :: util:: ser:: Readable for $st {
@@ -186,7 +209,7 @@ macro_rules! impl_writeable {
186
209
}
187
210
}
188
211
macro_rules! impl_writeable_len_match {
189
- ( $struct: ident, $cmp: tt, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
212
+ ( $struct: ident, $cmp: tt, ( $calc_len : expr ) , { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
190
213
impl Writeable for $struct {
191
214
fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , :: std:: io:: Error > {
192
215
let len = match * self {
@@ -198,12 +221,30 @@ macro_rules! impl_writeable_len_match {
198
221
// In tests, assert that the hard-coded length matches the actual one
199
222
use util:: ser:: LengthCalculatingWriter ;
200
223
let mut len_calc = LengthCalculatingWriter ( 0 ) ;
201
- $( self . $field. write( & mut len_calc) ? ; ) *
224
+ $( self . $field. write( & mut len_calc) . expect ( "No in-memory data may fail to serialize" ) ; ) *
202
225
assert!( len_calc. 0 $cmp len) ;
226
+ assert_eq!( len_calc. 0 , self . serialized_length( ) ) ;
203
227
}
204
228
$( self . $field. write( w) ?; ) *
205
229
Ok ( ( ) )
206
230
}
231
+
232
+ #[ inline]
233
+ fn serialized_length( & self ) -> usize {
234
+ if $calc_len || cfg!( any( test, feature = "fuzztarget" ) ) {
235
+ let mut len_calc = 0 ;
236
+ $( len_calc += self . $field. serialized_length( ) ; ) *
237
+ if !$calc_len {
238
+ assert_eq!( len_calc, match * self {
239
+ $( $match => $length, ) *
240
+ } ) ;
241
+ }
242
+ return len_calc
243
+ }
244
+ match * self {
245
+ $( $match => $length, ) *
246
+ }
247
+ }
207
248
}
208
249
209
250
impl :: util:: ser:: Readable for $struct {
@@ -214,8 +255,11 @@ macro_rules! impl_writeable_len_match {
214
255
}
215
256
}
216
257
} ;
258
+ ( $struct: ident, $cmp: tt, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
259
+ impl_writeable_len_match!( $struct, $cmp, ( true ) , { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
260
+ } ;
217
261
( $struct: ident, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
218
- impl_writeable_len_match!( $struct, ==, { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
262
+ impl_writeable_len_match!( $struct, ==, ( false ) , { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
219
263
}
220
264
}
221
265
@@ -319,6 +363,14 @@ macro_rules! _write_tlv_fields {
319
363
write_tlv_fields!( $stream, { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* , $( ( $optional_type_2, $optional_field_2) ) ,* } ) ;
320
364
}
321
365
}
366
+ macro_rules! _get_tlv_len {
367
+ ( { $( ( $type: expr, $field: expr) ) ,* $( , ) * } , { } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $( , ) * } ) => {
368
+ get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } )
369
+ } ;
370
+ ( { $( ( $type: expr, $field: expr) ) ,* $( , ) * } , { $( ( $optional_type: expr, $optional_field: expr) ) ,* $( , ) * } , { $( ( $optional_type_2: expr, $optional_field_2: expr) ) ,* $( , ) * } ) => {
371
+ get_varint_length_prefixed_tlv_length!( { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* , $( ( $optional_type_2, $optional_field_2) ) ,* } )
372
+ }
373
+ }
322
374
macro_rules! _read_tlv_fields {
323
375
( $stream: expr, { $( ( $reqtype: expr, $reqfield: ident) ) ,* $( , ) * } , { } , { $( ( $type: expr, $field: ident) ) ,* $( , ) * } ) => {
324
376
read_tlv_fields!( $stream, { $( ( $reqtype, $reqfield) ) ,* } , { $( ( $type, $field) ) ,* } ) ;
@@ -346,6 +398,21 @@ macro_rules! impl_writeable_tlv_based {
346
398
} ) ;
347
399
Ok ( ( ) )
348
400
}
401
+
402
+ #[ inline]
403
+ fn serialized_length( & self ) -> usize {
404
+ let len = _get_tlv_len!( {
405
+ $( ( $reqtype, self . $reqfield) ) ,*
406
+ } , {
407
+ $( ( $type, self . $field) ) ,*
408
+ } , {
409
+ $( ( $vectype, Some ( :: util:: ser:: VecWriteWrapper ( & self . $vecfield) ) ) ) ,*
410
+ } ) ;
411
+ use util:: ser:: { BigSize , LengthCalculatingWriter } ;
412
+ let mut len_calc = LengthCalculatingWriter ( 0 ) ;
413
+ BigSize ( len as u64 ) . write( & mut len_calc) . expect( "No in-memory data may fail to serialize" ) ;
414
+ len + len_calc. 0
415
+ }
349
416
}
350
417
351
418
impl :: util:: ser:: Readable for $st {
0 commit comments