Skip to content

Commit 723f687

Browse files
authored
add parameter to set upper limit on output from serialize function (#247)
1 parent e25f141 commit 723f687

File tree

1 file changed

+78
-4
lines changed

1 file changed

+78
-4
lines changed

src/serde/ser.rs

Lines changed: 78 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,43 @@
11
use std::io;
22
use std::io::Cursor;
3+
use std::io::ErrorKind;
4+
use std::io::Write;
35

46
use super::write_atom::write_atom;
57
use crate::allocator::{NodePtr, SExp};
68
use crate::node::Node;
79

810
const CONS_BOX_MARKER: u8 = 0xff;
911

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+
1041
/// serialize a node
1142
pub fn node_to_stream<W: io::Write>(node: &Node, f: &mut W) -> io::Result<()> {
1243
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<()> {
2960
Ok(())
3061
}
3162

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+
3271
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+
}
3474

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+
}
38112
}

0 commit comments

Comments
 (0)