ruby_marshal/
load.rs

1use crate::ArrayValue;
2use crate::Error;
3use crate::FixnumValue;
4use crate::HashValue;
5use crate::ObjectValue;
6use crate::StringValue;
7use crate::SymbolValue;
8use crate::TypedValueHandle;
9use crate::UserDefinedValue;
10use crate::Value;
11use crate::ValueArena;
12use crate::ValueHandle;
13use crate::MAJOR_VERSION;
14use crate::MINOR_VERSION;
15use crate::VALUE_KIND_ARRAY;
16use crate::VALUE_KIND_FALSE;
17use crate::VALUE_KIND_FIXNUM;
18use crate::VALUE_KIND_HASH;
19use crate::VALUE_KIND_HASH_DEFAULT;
20use crate::VALUE_KIND_INSTANCE_VARIABLES;
21use crate::VALUE_KIND_NIL;
22use crate::VALUE_KIND_OBJECT;
23use crate::VALUE_KIND_OBJECT_LINK;
24use crate::VALUE_KIND_STRING;
25use crate::VALUE_KIND_SYMBOL;
26use crate::VALUE_KIND_SYMBOL_LINK;
27use crate::VALUE_KIND_TRUE;
28use crate::VALUE_KIND_USER_DEFINED;
29use std::io::Read;
30
31#[derive(Debug)]
32struct Loader<R> {
33    reader: R,
34
35    arena: ValueArena,
36
37    symbol_links: Vec<TypedValueHandle<SymbolValue>>,
38    object_links: Vec<ValueHandle>,
39}
40
41impl<R> Loader<R> {
42    /// Make a new [`Loader`] around a reader.
43    fn new(reader: R) -> Self {
44        let arena = ValueArena::new();
45
46        Self {
47            reader,
48            arena,
49            symbol_links: Vec::new(),
50            object_links: Vec::new(),
51        }
52    }
53}
54
55impl<R> Loader<R>
56where
57    R: Read,
58{
59    /// Read a byte
60    fn read_byte(&mut self) -> Result<u8, Error> {
61        let mut byte = 0;
62        self.reader.read_exact(std::slice::from_mut(&mut byte))?;
63        Ok(byte)
64    }
65
66    /// Read a byte string.
67    ///
68    /// A byte string is a fixnum length, then that number of bytes.
69    fn read_byte_string(&mut self) -> Result<Vec<u8>, Error> {
70        let len = self.read_fixnum_value()?;
71        let len = usize::try_from(len).map_err(|error| Error::FixnumInvalidUSize { error })?;
72
73        let mut value = vec![0; len];
74        self.reader.read_exact(&mut value)?;
75
76        Ok(value)
77    }
78
79    /// Read and validate the header.
80    fn read_header(&mut self) -> Result<(), Error> {
81        let major_version = self.read_byte()?;
82        let minor_version = self.read_byte()?;
83
84        if major_version != MAJOR_VERSION || minor_version > MINOR_VERSION {
85            return Err(Error::InvalidVersion {
86                major: major_version,
87                minor: minor_version,
88            });
89        }
90
91        Ok(())
92    }
93
94    /// Read a fixnum value
95    fn read_fixnum_value(&mut self) -> Result<i32, Error> {
96        let len = self.read_byte()?;
97        if len == 0 {
98            return Ok(0);
99        }
100        let positive = (len as i8) > 0;
101        let byte = len;
102
103        if positive {
104            if byte > 4 {
105                return Ok(i32::from(byte) - 5);
106            }
107
108            if usize::from(byte) > std::mem::size_of::<i32>() {
109                return Err(Error::InvalidFixnumSize { size: byte });
110            }
111
112            let mut n: i32 = 0;
113            for i in 0..byte {
114                let byte = self.read_byte()?;
115                n |= i32::from(byte) << (i * 8);
116            }
117
118            Ok(n)
119        } else {
120            if (byte as i8) < -4 {
121                return Ok(i32::from(byte as i8) + 5);
122            }
123
124            let byte = -(byte as i8) as u8;
125            if usize::from(byte) > std::mem::size_of::<i32>() {
126                return Err(Error::InvalidFixnumSize { size: byte });
127            }
128
129            let mut n: i32 = -1;
130            for i in 0..byte {
131                n &= !(0xFF_i32 << (i * 8));
132                n |= i32::from(self.read_byte()?) << (i * 8);
133            }
134
135            Ok(n)
136        }
137    }
138
139    /// Read a fixnum.
140    fn read_fixnum(&mut self) -> Result<TypedValueHandle<FixnumValue>, Error> {
141        let value = self.read_fixnum_value()?;
142        Ok(self.arena.create_fixnum(value))
143    }
144
145    /// Read a symbol.
146    fn read_symbol(&mut self) -> Result<TypedValueHandle<SymbolValue>, Error> {
147        let symbol = self.read_byte_string()?;
148        let handle = self.arena.create_symbol(symbol);
149
150        self.symbol_links.push(handle);
151
152        Ok(handle)
153    }
154
155    /// Read a symbol link.
156    fn read_symbol_link(&mut self) -> Result<TypedValueHandle<SymbolValue>, Error> {
157        let index = self.read_fixnum_value()?;
158        let index = usize::try_from(index).map_err(|error| Error::FixnumInvalidUSize { error })?;
159
160        let value = self
161            .symbol_links
162            .get(index)
163            .ok_or(Error::MissingSymbolLink { index })?;
164
165        Ok(*value)
166    }
167
168    /// Read an object link
169    fn read_object_link(&mut self) -> Result<ValueHandle, Error> {
170        let index = self.read_fixnum_value()?;
171        let index = usize::try_from(index).map_err(|error| Error::FixnumInvalidUSize { error })?;
172
173        let value = self
174            .object_links
175            .get(index)
176            .ok_or(Error::MissingObjectLink { index })?;
177
178        Ok(*value)
179    }
180
181    /// Read instance variables.
182    fn read_instance_variables(
183        &mut self,
184    ) -> Result<Vec<(TypedValueHandle<SymbolValue>, ValueHandle)>, Error> {
185        let num_pairs = self.read_fixnum_value()?;
186        let num_pairs =
187            usize::try_from(num_pairs).map_err(|error| Error::FixnumInvalidUSize { error })?;
188
189        // TODO: Consider making this a map.
190        let mut instance_variables = Vec::with_capacity(num_pairs);
191        for _ in 0..num_pairs {
192            let symbol = self.read_value_symbol_like()?;
193            let value = self.read_value()?;
194
195            instance_variables.push((symbol, value));
196        }
197
198        Ok(instance_variables)
199    }
200
201    /// Read an array
202    fn read_array(&mut self) -> Result<TypedValueHandle<ArrayValue>, Error> {
203        let handle = self.arena.create_nil().into_raw();
204        self.object_links.push(handle);
205
206        let len = self.read_fixnum_value()?;
207        let len = usize::try_from(len).map_err(|error| Error::FixnumInvalidUSize { error })?;
208        let mut array_value = Vec::with_capacity(len);
209
210        for _ in 0..len {
211            let value = self.read_value()?;
212            array_value.push(value);
213        }
214
215        *self.arena.get_mut(handle).unwrap() = ArrayValue::new(array_value).into();
216
217        Ok(TypedValueHandle::new_unchecked(handle))
218    }
219
220    /// Read a hash.
221    fn read_hash(&mut self, has_default_value: bool) -> Result<TypedValueHandle<HashValue>, Error> {
222        let handle = self.arena.create_nil().into_raw();
223        self.object_links.push(handle);
224
225        let num_pairs = self.read_fixnum_value()?;
226        let num_pairs =
227            usize::try_from(num_pairs).map_err(|error| Error::FixnumInvalidUSize { error })?;
228
229        // TODO: Consider making this a map.
230        let mut pairs = Vec::with_capacity(num_pairs);
231        for _ in 0..num_pairs {
232            let key = self.read_value()?;
233            let value = self.read_value()?;
234
235            pairs.push((key, value));
236        }
237
238        let default_value = if has_default_value {
239            Some(self.read_value()?)
240        } else {
241            None
242        };
243
244        *self.arena.get_mut(handle).unwrap() = HashValue::new(pairs, default_value).into();
245
246        Ok(TypedValueHandle::new_unchecked(handle))
247    }
248
249    /// Read an object
250    fn read_object(&mut self) -> Result<TypedValueHandle<ObjectValue>, Error> {
251        let handle = self.arena.create_nil().into_raw();
252        self.object_links.push(handle);
253
254        let name = self.read_value_symbol_like()?;
255        let instance_variables = self.read_instance_variables()?;
256
257        *self.arena.get_mut(handle).unwrap() = ObjectValue::new(name, instance_variables).into();
258
259        Ok(TypedValueHandle::new_unchecked(handle))
260    }
261
262    /// Read a string
263    fn read_string(&mut self) -> Result<TypedValueHandle<StringValue>, Error> {
264        let data = self.read_byte_string()?;
265
266        let handle = self.arena.create_string(data);
267        self.object_links.push(handle.into());
268
269        Ok(handle)
270    }
271
272    /// Read a user defined
273    fn read_user_defined(&mut self) -> Result<TypedValueHandle<UserDefinedValue>, Error> {
274        let name = self.read_value_symbol_like()?;
275        let value = self.read_byte_string()?;
276
277        let handle = self.arena.create_user_defined(name, value);
278        self.object_links.push(handle.into());
279
280        Ok(handle)
281    }
282
283    /// Read the next value, failing if it is not a symbol-like value.
284    fn read_value_symbol_like(&mut self) -> Result<TypedValueHandle<SymbolValue>, Error> {
285        let kind = self.read_byte()?;
286        match kind {
287            VALUE_KIND_SYMBOL => self.read_symbol(),
288            VALUE_KIND_SYMBOL_LINK => self.read_symbol_link(),
289            _ => Err(Error::UnexpectedValueKind {
290                expected: VALUE_KIND_SYMBOL,
291                actual: kind,
292            }),
293        }
294    }
295
296    /// Read the next value.
297    fn read_value(&mut self) -> Result<ValueHandle, Error> {
298        let kind = self.read_byte()?;
299        match kind {
300            VALUE_KIND_NIL => Ok(self.arena.create_nil().into()),
301            VALUE_KIND_TRUE => Ok(self.arena.create_bool(true).into()),
302            VALUE_KIND_FALSE => Ok(self.arena.create_bool(false).into()),
303            VALUE_KIND_FIXNUM => Ok(self.read_fixnum()?.into()),
304            VALUE_KIND_SYMBOL => Ok(self.read_symbol()?.into()),
305            VALUE_KIND_SYMBOL_LINK => Ok(self.read_symbol_link()?.into()),
306            VALUE_KIND_OBJECT_LINK => Ok(self.read_object_link()?),
307            VALUE_KIND_INSTANCE_VARIABLES => {
308                let value = self.read_value()?;
309
310                let instance_variables = self.read_instance_variables()?;
311
312                match self
313                    .arena
314                    .get_mut(value)
315                    .ok_or(Error::InvalidValueHandle { handle: value })?
316                {
317                    Value::String(value) => {
318                        value.set_instance_variables(Some(instance_variables));
319                    }
320                    Value::UserDefined(value) => {
321                        value.set_instance_variables(Some(instance_variables));
322                    }
323                    _ => return Err(Error::NotAnObject),
324                }
325
326                Ok(value)
327            }
328            VALUE_KIND_ARRAY => Ok(self.read_array()?.into()),
329            VALUE_KIND_HASH => Ok(self.read_hash(false)?.into()),
330            VALUE_KIND_HASH_DEFAULT => Ok(self.read_hash(true)?.into()),
331            VALUE_KIND_OBJECT => Ok(self.read_object()?.into()),
332            VALUE_KIND_STRING => Ok(self.read_string()?.into()),
333            VALUE_KIND_USER_DEFINED => Ok(self.read_user_defined()?.into()),
334            _ => Err(Error::InvalidValueKind { kind }),
335        }
336    }
337
338    /// Load from the reader and get the value.
339    fn load(mut self) -> Result<ValueArena, Error> {
340        self.read_header()?;
341        let root = self.read_value()?;
342        let _old_root = self.arena.replace_root(root);
343
344        // TODO: Delete old root.
345
346        Ok(self.arena)
347    }
348}
349
350/// Load from a reader.
351pub fn load<R>(reader: R) -> Result<ValueArena, Error>
352where
353    R: Read,
354{
355    let loader = Loader::new(reader);
356    let value_arena = loader.load()?;
357
358    Ok(value_arena)
359}