1
- use std :: convert :: { TryInto } ;
1
+ use integer_encoding :: VarInt ;
2
2
3
- pub type Padding = u32 ;
4
- pub const PADDING : usize = std:: mem:: size_of :: < Padding > ( ) ;
3
+ /// This is the max required bytes to encode a u64 using the varint encoding scheme.
4
+ /// It is size 10=ceil(64/7)
5
+ pub const MAX_ENCODED_SIZE : usize = 10 ;
5
6
6
7
/// Encode a message, returning the bytes that must be sent before the message.
7
- pub fn encode_size ( message : & [ u8 ] ) -> [ u8 ; PADDING ] {
8
- ( message. len ( ) as Padding ) . to_le_bytes ( )
8
+ /// A buffer is used to avoid heap allocation.
9
+ pub fn encode_size < ' a > ( message : & [ u8 ] , buf : & ' a mut [ u8 ; MAX_ENCODED_SIZE ] ) -> & ' a [ u8 ] {
10
+ let varint_size = message. len ( ) . encode_var ( buf) ;
11
+ & buf[ ..varint_size]
9
12
}
10
13
11
14
/// Decodes an encoded value in a buffer.
12
- /// The function returns the message size or none if the buffer is less than [`PADDING`].
13
- pub fn decode_size ( data : & [ u8 ] ) -> Option < usize > {
14
- if data. len ( ) < PADDING {
15
- return None
16
- }
17
- data[ ..PADDING ] . try_into ( ) . map ( |encoded| Padding :: from_le_bytes ( encoded) as usize ) . ok ( )
15
+ /// The function returns the message size and the consumed bytes or none if the buffer is too small.
16
+ pub fn decode_size ( data : & [ u8 ] ) -> Option < ( usize , usize ) > {
17
+ usize:: decode_var ( data)
18
18
}
19
19
20
20
/// Used to decoded one message from several/partial data chunks
@@ -34,8 +34,8 @@ impl Decoder {
34
34
fn try_decode ( & mut self , data : & [ u8 ] , mut decoded_callback : impl FnMut ( & [ u8 ] ) ) {
35
35
let mut next_data = data;
36
36
loop {
37
- if let Some ( expected_size) = decode_size ( & next_data) {
38
- let remaining = & next_data[ PADDING ..] ;
37
+ if let Some ( ( expected_size, used_bytes ) ) = decode_size ( & next_data) {
38
+ let remaining = & next_data[ used_bytes ..] ;
39
39
if remaining. len ( ) >= expected_size {
40
40
let ( decoded, not_decoded) = remaining. split_at ( expected_size) ;
41
41
decoded_callback ( decoded) ;
@@ -55,25 +55,25 @@ impl Decoder {
55
55
56
56
fn store_and_decoded_data < ' a > ( & mut self , data : & ' a [ u8 ] ) -> Option < ( & [ u8 ] , & ' a [ u8 ] ) > {
57
57
// Process frame header
58
- let ( expected_size, data) = match decode_size ( & self . stored ) {
59
- Some ( size ) => ( size , data) ,
58
+ let ( ( expected_size, used_bytes ) , data) = match decode_size ( & self . stored ) {
59
+ Some ( size_info ) => ( size_info , data) ,
60
60
None => {
61
- let remaining = PADDING - self . stored . len ( ) ;
62
- if data. len ( ) >= remaining {
63
- // Now, we can now the size
64
- self . stored . extend_from_slice ( & data [ ..remaining ] ) ;
65
- ( decode_size ( & self . stored ) . unwrap ( ) , & data [ remaining.. ] )
66
- }
67
- else {
68
- // We need more data to know the size
69
- self . stored . extend_from_slice ( data) ;
61
+ // we append at most the potential data needed to decode the size
62
+ let max_remaining = ( MAX_ENCODED_SIZE - self . stored . len ( ) ) . min ( data. len ( ) ) ;
63
+ self . stored . extend_from_slice ( & data [ ..max_remaining ] ) ;
64
+
65
+ if let Some ( x ) = decode_size ( & self . stored ) {
66
+ // Now we know the size
67
+ ( x , & data [ max_remaining.. ] )
68
+ } else {
69
+ // We still don't know the size (data was too small)
70
70
return None
71
71
}
72
72
}
73
73
} ;
74
74
75
75
// At this point we know at least the expected size of the frame.
76
- let remaining = expected_size - ( self . stored . len ( ) - PADDING ) ;
76
+ let remaining = expected_size - ( self . stored . len ( ) - used_bytes ) ;
77
77
if data. len ( ) < remaining {
78
78
// We need more data to decoder
79
79
self . stored . extend_from_slice ( data) ;
@@ -83,7 +83,7 @@ impl Decoder {
83
83
// We can complete a message here
84
84
let ( to_store, remaining) = data. split_at ( remaining) ;
85
85
self . stored . extend_from_slice ( to_store) ;
86
- Some ( ( & self . stored [ PADDING ..] , remaining) )
86
+ Some ( ( & self . stored [ used_bytes ..] , remaining) )
87
87
}
88
88
}
89
89
@@ -118,14 +118,15 @@ mod tests {
118
118
use super :: * ;
119
119
120
120
const MESSAGE_SIZE : usize = 20 ; // only works if (X + PADDING ) % 6 == 0
121
- const ENCODED_MESSAGE_SIZE : usize = PADDING + MESSAGE_SIZE ;
121
+ const ENCODED_MESSAGE_SIZE : usize = 1 + MESSAGE_SIZE ; // 1 = log_2(20)/7
122
122
const MESSAGE : [ u8 ; MESSAGE_SIZE ] = [ 42 ; MESSAGE_SIZE ] ;
123
123
const MESSAGE_A : [ u8 ; MESSAGE_SIZE ] = [ 'A' as u8 ; MESSAGE_SIZE ] ;
124
124
const MESSAGE_B : [ u8 ; MESSAGE_SIZE ] = [ 'B' as u8 ; MESSAGE_SIZE ] ;
125
125
const MESSAGE_C : [ u8 ; MESSAGE_SIZE ] = [ 'C' as u8 ; MESSAGE_SIZE ] ;
126
126
127
127
fn encode_message ( buffer : & mut Vec < u8 > , message : & [ u8 ] ) {
128
- buffer. extend_from_slice ( & encode_size ( message) ) ;
128
+ let mut buf = [ 0 ; MAX_ENCODED_SIZE ] ;
129
+ buffer. extend_from_slice ( & * encode_size ( message, & mut buf) ) ;
129
130
buffer. extend_from_slice ( message) ;
130
131
}
131
132
@@ -135,9 +136,22 @@ mod tests {
135
136
encode_message ( & mut buffer, & MESSAGE ) ;
136
137
137
138
assert_eq ! ( ENCODED_MESSAGE_SIZE , buffer. len( ) ) ;
138
- let expected_size = decode_size ( & buffer) . unwrap ( ) ;
139
+ let ( expected_size, used_bytes ) = decode_size ( & buffer) . unwrap ( ) ;
139
140
assert_eq ! ( MESSAGE_SIZE , expected_size) ;
140
- assert_eq ! ( & MESSAGE , & buffer[ PADDING ..] ) ;
141
+ assert_eq ! ( used_bytes, 1 ) ;
142
+ assert_eq ! ( & MESSAGE , & buffer[ used_bytes..] ) ;
143
+ }
144
+
145
+ #[ test]
146
+ fn encode_one_big_message ( ) {
147
+ let mut buffer = Vec :: new ( ) ;
148
+ encode_message ( & mut buffer, & vec ! [ 0 ; 1000 ] ) ;
149
+
150
+ assert_eq ! ( 1002 , buffer. len( ) ) ;
151
+ let ( expected_size, used_bytes) = decode_size ( & buffer) . unwrap ( ) ;
152
+ assert_eq ! ( 1000 , expected_size) ;
153
+ assert_eq ! ( used_bytes, 2 ) ;
154
+ assert_eq ! ( & vec![ 0 ; 1000 ] , & buffer[ used_bytes..] ) ;
141
155
}
142
156
143
157
#[ test]
@@ -307,60 +321,72 @@ mod tests {
307
321
}
308
322
309
323
#[ test]
310
- // [ 3B ][ remaining ]
324
+ // [ 1B ][ remaining ]
311
325
// [ message ]
312
326
fn decode_message_after_non_enough_padding ( ) {
327
+ let msg = [ 0 ; 1000 ] ;
313
328
let mut buffer = Vec :: new ( ) ;
314
- encode_message ( & mut buffer, & MESSAGE ) ;
329
+ encode_message ( & mut buffer, & msg ) ;
315
330
316
- let ( start_3b , remaining) = buffer. split_at ( 3 ) ;
331
+ let ( start_1b , remaining) = buffer. split_at ( 2 ) ;
317
332
318
333
let mut decoder = Decoder :: default ( ) ;
319
334
320
335
let mut times_called = 0 ;
321
- decoder. decode ( & start_3b , |_decoded| {
336
+ decoder. decode ( & start_1b , |_decoded| {
322
337
// Should not be called
323
338
times_called += 1 ;
324
339
} ) ;
325
340
326
341
assert_eq ! ( 0 , times_called) ;
327
- assert_eq ! ( 3 , decoder. stored. len( ) ) ;
342
+ assert_eq ! ( 2 , decoder. stored. len( ) ) ;
328
343
329
344
decoder. decode ( & remaining, |decoded| {
330
345
times_called += 1 ;
331
- assert_eq ! ( MESSAGE , decoded) ;
346
+ assert_eq ! ( msg , decoded) ;
332
347
} ) ;
333
348
334
349
assert_eq ! ( 1 , times_called) ;
335
350
assert_eq ! ( 0 , decoder. stored. len( ) ) ;
336
351
}
337
352
338
353
#[ test]
339
- // [ 3B ][ 1B ]
340
- // [ message ]
341
- fn decode_message_no_size_after_non_enough_padding ( ) {
354
+ // [ 1B ][ 1B ][ remaining ]
355
+ // [ message ]
356
+ fn decode_message_var_size_in_two_data ( ) {
357
+ let msg = [ 0 ; 1000 ] ;
342
358
let mut buffer = Vec :: new ( ) ;
343
- encode_message ( & mut buffer, & [ ] ) ;
359
+ encode_message ( & mut buffer, & msg ) ;
344
360
345
- let ( start_3b , remaining) = buffer. split_at ( 3 ) ;
361
+ let ( start_1b , remaining) = buffer. split_at ( 1 ) ;
346
362
347
363
let mut decoder = Decoder :: default ( ) ;
348
364
349
365
let mut times_called = 0 ;
350
- decoder. decode ( & start_3b , |_decoded| {
366
+ decoder. decode ( & start_1b , |_decoded| {
351
367
// Should not be called
352
368
times_called += 1 ;
353
369
} ) ;
354
370
355
371
assert_eq ! ( 0 , times_called) ;
356
- assert_eq ! ( 3 , decoder. stored. len( ) ) ;
372
+ assert_eq ! ( 1 , decoder. stored. len( ) ) ;
373
+
374
+ let ( next_1b, remaining) = remaining. split_at ( 1 ) ;
357
375
358
376
let mut times_called = 0 ;
359
- decoder. decode ( & remaining , |_decoded| {
377
+ decoder. decode ( & next_1b , |_decoded| {
360
378
// Should not be called
361
379
times_called += 1 ;
362
380
} ) ;
363
381
382
+ assert_eq ! ( 0 , times_called) ;
383
+ assert_eq ! ( 2 , decoder. stored. len( ) ) ;
384
+
385
+ decoder. decode ( & remaining, |decoded| {
386
+ times_called += 1 ;
387
+ assert_eq ! ( msg, decoded) ;
388
+ } ) ;
389
+
364
390
assert_eq ! ( 1 , times_called) ;
365
391
assert_eq ! ( 0 , decoder. stored. len( ) ) ;
366
392
}
0 commit comments