1
1
use std:: io;
2
2
use std:: io:: Cursor ;
3
+ use std:: io:: ErrorKind ;
4
+ use std:: io:: Write ;
3
5
4
6
use super :: write_atom:: write_atom;
5
7
use crate :: allocator:: { NodePtr , SExp } ;
6
8
use crate :: node:: Node ;
7
9
8
10
const CONS_BOX_MARKER : u8 = 0xff ;
9
11
12
+ pub struct LimitedWriter < W : io:: Write > {
13
+ inner : W ,
14
+ limit : usize ,
15
+ }
16
+
17
+ impl < W : io:: Write > LimitedWriter < W > {
18
+ pub fn new ( w : W , limit : usize ) -> LimitedWriter < W > {
19
+ LimitedWriter { inner : w, limit }
20
+ }
21
+
22
+ pub fn into_inner ( self ) -> W {
23
+ self . inner
24
+ }
25
+ }
26
+
27
+ impl < W : io:: Write > Write for LimitedWriter < W > {
28
+ fn write ( & mut self , buf : & [ u8 ] ) -> io:: Result < usize > {
29
+ if self . limit < buf. len ( ) {
30
+ return Err ( ErrorKind :: OutOfMemory . into ( ) ) ;
31
+ }
32
+ let written = self . inner . write ( buf) ?;
33
+ self . limit -= written;
34
+ Ok ( written)
35
+ }
36
+ fn flush ( & mut self ) -> io:: Result < ( ) > {
37
+ self . inner . flush ( )
38
+ }
39
+ }
40
+
10
41
/// serialize a node
11
42
pub fn node_to_stream < W : io:: Write > ( node : & Node , f : & mut W ) -> io:: Result < ( ) > {
12
43
let mut values: Vec < NodePtr > = vec ! [ node. node] ;
@@ -29,10 +60,53 @@ pub fn node_to_stream<W: io::Write>(node: &Node, f: &mut W) -> io::Result<()> {
29
60
Ok ( ( ) )
30
61
}
31
62
63
+ pub fn node_to_bytes_limit ( node : & Node , limit : usize ) -> io:: Result < Vec < u8 > > {
64
+ let buffer = Cursor :: new ( Vec :: new ( ) ) ;
65
+ let mut writer = LimitedWriter :: new ( buffer, limit) ;
66
+ node_to_stream ( node, & mut writer) ?;
67
+ let vec = writer. into_inner ( ) . into_inner ( ) ;
68
+ Ok ( vec)
69
+ }
70
+
32
71
pub fn node_to_bytes ( node : & Node ) -> io:: Result < Vec < u8 > > {
33
- let mut buffer = Cursor :: new ( Vec :: new ( ) ) ;
72
+ node_to_bytes_limit ( node, 2000000 )
73
+ }
34
74
35
- node_to_stream ( node, & mut buffer) ?;
36
- let vec = buffer. into_inner ( ) ;
37
- Ok ( vec)
75
+ #[ cfg( test) ]
76
+ use crate :: allocator:: Allocator ;
77
+
78
+ #[ test]
79
+ fn test_serialize_limit ( ) {
80
+ let mut a = Allocator :: new ( ) ;
81
+
82
+ let leaf = a. new_atom ( & [ 1 , 2 , 3 , 4 , 5 ] ) . unwrap ( ) ;
83
+ let l1 = a. new_pair ( leaf, leaf) . unwrap ( ) ;
84
+ let l2 = a. new_pair ( l1, l1) . unwrap ( ) ;
85
+ let l3 = a. new_pair ( l2, l2) . unwrap ( ) ;
86
+
87
+ {
88
+ let buffer = Cursor :: new ( Vec :: new ( ) ) ;
89
+ let mut writer = LimitedWriter :: new ( buffer, 55 ) ;
90
+ node_to_stream ( & Node :: new ( & a, l3) , & mut writer) . unwrap ( ) ;
91
+ let vec = writer. into_inner ( ) . into_inner ( ) ;
92
+ assert_eq ! (
93
+ vec,
94
+ & [
95
+ 0xff , 0xff , 0xff , 133 , 1 , 2 , 3 , 4 , 5 , 133 , 1 , 2 , 3 , 4 , 5 , 0xff , 133 , 1 , 2 , 3 , 4 , 5 ,
96
+ 133 , 1 , 2 , 3 , 4 , 5 , 0xff , 0xff , 133 , 1 , 2 , 3 , 4 , 5 , 133 , 1 , 2 , 3 , 4 , 5 , 0xff , 133 ,
97
+ 1 , 2 , 3 , 4 , 5 , 133 , 1 , 2 , 3 , 4 , 5
98
+ ]
99
+ ) ;
100
+ }
101
+
102
+ {
103
+ let buffer = Cursor :: new ( Vec :: new ( ) ) ;
104
+ let mut writer = LimitedWriter :: new ( buffer, 54 ) ;
105
+ assert_eq ! (
106
+ node_to_stream( & Node :: new( & a, l3) , & mut writer)
107
+ . unwrap_err( )
108
+ . kind( ) ,
109
+ io:: ErrorKind :: OutOfMemory
110
+ ) ;
111
+ }
38
112
}
0 commit comments