Skip to content

Commit 6a3878e

Browse files
committed
Borrow the vector of references instead of returning its ownership every time.
1 parent 1508675 commit 6a3878e

File tree

1 file changed

+27
-28
lines changed

1 file changed

+27
-28
lines changed

src/marshal.rs

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -105,52 +105,49 @@ fn read_unicode_string<R: io::Read>(r: &mut R, size: usize) -> Result<String, Un
105105
}
106106
}
107107

108-
fn read_objects<R: io::Read>(r: &mut R, references: Vec<Object>, size: usize) -> Result<(Vec<Object>, Vec<Object>), UnmarshalError> {
108+
fn read_objects<R: io::Read>(r: &mut R, references: &mut Vec<Object>, size: usize) -> Result<Vec<Object>, UnmarshalError> {
109109
let mut vector = Vec::<Object>::new();
110-
let mut references2 = references;
111110
vector.reserve(size);
112111
for _ in 0..size {
113-
let (object, r) = try!(read_object(r, references2));
114-
references2 = r;
112+
let object = try!(read_object(r, references));
115113
vector.push(object);
116114
};
117-
Ok((vector, references2))
115+
Ok(vector)
118116
}
119117

120118
macro_rules! build_container {
121-
( $reader:expr, $references:expr, $container:expr, $size:expr, $flag:expr) => {{
122-
let mut references = $references;
119+
( $reader:expr, $references:ident, $container:expr, $size:expr, $flag:expr) => {{
123120
if $flag {
124-
let index = references.len() as u32; // TODO: overflow check
125-
references.push(Object::Hole);
126-
let (objects, mut references) = try!(read_objects($reader, references, $size));
127-
references[index as usize] = $container(objects); // TODO: overflow check
128-
(false, Object::Ref(index), references)
121+
let index = $references.len() as u32; // TODO: overflow check
122+
$references.push(Object::Hole);
123+
let objects = try!(read_objects($reader, $references, $size));
124+
$references[index as usize] = $container(objects); // TODO: overflow check
125+
(false, Object::Ref(index))
129126
}
130127
else {
131-
let (objects, mut references) = try!(read_objects($reader, references, $size));
132-
(false, $container(objects), references)
128+
let objects = try!(read_objects($reader, $references, $size));
129+
(false, $container(objects))
133130
}
134131
}}
135132
}
136133

137-
pub fn read_object<R: io::Read>(r: &mut R, mut references: Vec<Object>) -> Result<(Object, Vec<Object>), UnmarshalError> {
134+
pub fn read_object<R: io::Read>(r: &mut R, references: &mut Vec<Object>) -> Result<Object, UnmarshalError> {
138135
let byte = read_byte!(r);
139136
let flag = if (byte & 0b10000000) == 0 { false } else { true };
140137
let opcode = byte & 0b01111111;
141-
let (add_ref, object, mut references) = match opcode as char {
138+
let (add_ref, object) = match opcode as char {
142139
'0' => return Err(UnmarshalError::UnexpectedCode("NULL object in marshal data for object".to_string())),
143-
'N' => (false, Object::None, references),
144-
'F' => (false, Object::False, references),
145-
'T' => (false, Object::True, references),
146-
'i' => (true, Object::Int(try!(read_long(r))), references),
140+
'N' => (false, Object::None),
141+
'F' => (false, Object::False),
142+
'T' => (false, Object::True),
143+
'i' => (true, Object::Int(try!(read_long(r)))),
147144
'z' | 'Z' => { // “short ascii”, “short ascii interned”
148145
let size = read_byte!(r) as usize;
149-
(true, Object::String(try!(read_ascii_string(r, size))), references)
146+
(true, Object::String(try!(read_ascii_string(r, size))))
150147
},
151148
'u' => { // “unicode”
152149
let size = try!(read_long(r)) as usize; // TODO: overflow check if usize is smaller than u32
153-
(true, Object::String(try!(read_unicode_string(r, size))), references)
150+
(true, Object::String(try!(read_unicode_string(r, size))))
154151
}
155152
's' => { // “string”, but actually bytes
156153
let size = try!(read_long(r)) as usize; // TODO: overflow check if usize is smaller than u32
@@ -160,7 +157,7 @@ pub fn read_object<R: io::Read>(r: &mut R, mut references: Vec<Object>) -> Resul
160157
Err(err) => return Err(UnmarshalError::Io(err)),
161158
Ok(()) => ()
162159
};
163-
(true, Object::Bytes(buf), references)
160+
(true, Object::Bytes(buf))
164161
},
165162
')' => { // “small tuple”
166163
let size = read_byte!(r) as usize;
@@ -184,29 +181,31 @@ pub fn read_object<R: io::Read>(r: &mut R, mut references: Vec<Object>) -> Resul
184181
}
185182
'r' => {
186183
let index = try!(read_long(r));
187-
(false, Object::Ref(index), references)
184+
(false, Object::Ref(index))
188185
},
189186

190187
_ => panic!(format!("Unsupported opcode: {}", opcode as char)),
191188
};
192189
if flag && add_ref {
193190
let index = references.len() as u32; // TODO: overflow check
194191
references.push(object);
195-
Ok((Object::Ref(index), references))
192+
Ok(Object::Ref(index))
196193
} else {
197-
Ok((object, references))
194+
Ok(object)
198195
}
199196
}
200197

201198
macro_rules! assert_unmarshal {
202199
( $expected_obj:expr, $bytecode:expr) => {{
203200
let mut reader: &[u8] = $bytecode;
204-
let (obj, _refs) = read_object(&mut reader, Vec::new()).unwrap();
201+
let mut refs = Vec::new();
202+
let obj = read_object(&mut reader, &mut refs).unwrap();
205203
assert_eq!($expected_obj, obj);
206204
}};
207205
( $expected_obj:expr, $expected_refs:expr, $bytecode:expr) => {{
208206
let mut reader: &[u8] = $bytecode;
209-
let (obj, refs) = read_object(&mut reader, Vec::new()).unwrap();
207+
let mut refs = Vec::new();
208+
let obj = read_object(&mut reader, &mut refs).unwrap();
210209
assert_eq!($expected_obj, obj);
211210
assert_eq!($expected_refs, refs);
212211
}};

0 commit comments

Comments
 (0)