@@ -105,52 +105,49 @@ fn read_unicode_string<R: io::Read>(r: &mut R, size: usize) -> Result<String, Un
105
105
}
106
106
}
107
107
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 > {
109
109
let mut vector = Vec :: < Object > :: new ( ) ;
110
- let mut references2 = references;
111
110
vector. reserve ( size) ;
112
111
for _ in 0 ..size {
113
- let ( object, r) = try!( read_object ( r, references2) ) ;
114
- references2 = r;
112
+ let object = try!( read_object ( r, references) ) ;
115
113
vector. push ( object) ;
116
114
} ;
117
- Ok ( ( vector, references2 ) )
115
+ Ok ( vector)
118
116
}
119
117
120
118
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) => { {
123
120
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) )
129
126
}
130
127
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) )
133
130
}
134
131
} }
135
132
}
136
133
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 > {
138
135
let byte = read_byte ! ( r) ;
139
136
let flag = if ( byte & 0b10000000 ) == 0 { false } else { true } ;
140
137
let opcode = byte & 0b01111111 ;
141
- let ( add_ref, object, mut references ) = match opcode as char {
138
+ let ( add_ref, object) = match opcode as char {
142
139
'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) ) ) ) ,
147
144
'z' | 'Z' => { // “short ascii”, “short ascii interned”
148
145
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) ) ) )
150
147
} ,
151
148
'u' => { // “unicode”
152
149
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) ) ) )
154
151
}
155
152
's' => { // “string”, but actually bytes
156
153
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
160
157
Err ( err) => return Err ( UnmarshalError :: Io ( err) ) ,
161
158
Ok ( ( ) ) => ( )
162
159
} ;
163
- ( true , Object :: Bytes ( buf) , references )
160
+ ( true , Object :: Bytes ( buf) )
164
161
} ,
165
162
')' => { // “small tuple”
166
163
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
184
181
}
185
182
'r' => {
186
183
let index = try!( read_long ( r) ) ;
187
- ( false , Object :: Ref ( index) , references )
184
+ ( false , Object :: Ref ( index) )
188
185
} ,
189
186
190
187
_ => panic ! ( format!( "Unsupported opcode: {}" , opcode as char ) ) ,
191
188
} ;
192
189
if flag && add_ref {
193
190
let index = references. len ( ) as u32 ; // TODO: overflow check
194
191
references. push ( object) ;
195
- Ok ( ( Object :: Ref ( index) , references ) )
192
+ Ok ( Object :: Ref ( index) )
196
193
} else {
197
- Ok ( ( object, references ) )
194
+ Ok ( object)
198
195
}
199
196
}
200
197
201
198
macro_rules! assert_unmarshal {
202
199
( $expected_obj: expr, $bytecode: expr) => { {
203
200
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( ) ;
205
203
assert_eq!( $expected_obj, obj) ;
206
204
} } ;
207
205
( $expected_obj: expr, $expected_refs: expr, $bytecode: expr) => { {
208
206
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( ) ;
210
209
assert_eq!( $expected_obj, obj) ;
211
210
assert_eq!( $expected_refs, refs) ;
212
211
} } ;
0 commit comments