@@ -47,29 +47,36 @@ macro_rules! encode_tlv {
4747 } }
4848}
4949
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 ;
5353 #[ allow( unused_mut) ]
5454 let mut len = LengthCalculatingWriter ( 0 ) ;
5555 {
5656 $(
57- BigSize ( $type) . write( & mut len) ? ;
57+ BigSize ( $type) . write( & mut len) . expect ( "No in-memory data may fail to serialize" ) ;
5858 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" ) ;
6060 len. 0 += field_len;
6161 ) *
6262 $(
6363 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" ) ;
6565 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" ) ;
6767 len. 0 += field_len;
6868 }
6969 ) *
7070 }
71+ len. 0
72+ } }
73+ }
7174
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) ?;
7380 encode_tlv!( $stream, { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* } ) ;
7481 } }
7582}
@@ -167,13 +174,28 @@ macro_rules! impl_writeable {
167174 if $len != 0 {
168175 use util:: ser:: LengthCalculatingWriter ;
169176 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" ) ; ) *
171178 assert_eq!( len_calc. 0 , $len) ;
172179 }
173180 }
174181 $( self . $field. write( w) ?; ) *
175182 Ok ( ( ) )
176183 }
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+ }
177199 }
178200
179201 impl :: util:: ser:: Readable for $st {
@@ -186,7 +208,7 @@ macro_rules! impl_writeable {
186208 }
187209}
188210macro_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) ,* } ) => {
190212 impl Writeable for $struct {
191213 fn write<W : Writer >( & self , w: & mut W ) -> Result <( ) , :: std:: io:: Error > {
192214 let len = match * self {
@@ -198,12 +220,29 @@ macro_rules! impl_writeable_len_match {
198220 // In tests, assert that the hard-coded length matches the actual one
199221 use util:: ser:: LengthCalculatingWriter ;
200222 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" ) ; ) *
202224 assert!( len_calc. 0 $cmp len) ;
203225 }
204226 $( self . $field. write( w) ?; ) *
205227 Ok ( ( ) )
206228 }
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+ }
207246 }
208247
209248 impl :: util:: ser:: Readable for $struct {
@@ -214,8 +253,11 @@ macro_rules! impl_writeable_len_match {
214253 }
215254 }
216255 } ;
256+ ( $struct: ident, $cmp: tt, { $( { $match: pat, $length: expr} ) ,* } , { $( $field: ident) ,* } ) => {
257+ impl_writeable_len_match!( $struct, $cmp, ( true ) , { $( { $match, $length } ) ,* } , { $( $field) ,* } ) ;
258+ } ;
217259 ( $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) ,* } ) ;
219261 }
220262}
221263
@@ -319,6 +361,14 @@ macro_rules! _write_tlv_fields {
319361 write_tlv_fields!( $stream, { $( ( $type, $field) ) ,* } , { $( ( $optional_type, $optional_field) ) ,* , $( ( $optional_type_2, $optional_field_2) ) ,* } ) ;
320362 }
321363}
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+ }
322372macro_rules! _read_tlv_fields {
323373 ( $stream: expr, { $( ( $reqtype: expr, $reqfield: ident) ) ,* $( , ) * } , { } , { $( ( $type: expr, $field: ident) ) ,* $( , ) * } ) => {
324374 read_tlv_fields!( $stream, { $( ( $reqtype, $reqfield) ) ,* } , { $( ( $type, $field) ) ,* } ) ;
@@ -346,6 +396,21 @@ macro_rules! impl_writeable_tlv_based {
346396 } ) ;
347397 Ok ( ( ) )
348398 }
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+ }
349414 }
350415
351416 impl :: util:: ser:: Readable for $st {
0 commit comments