1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use {
    self::{deserializer::SequenceDeserializer, errors::Result},
    byteorder::{BigEndian, ReadBytesExt},
    serde::{de::Visitor, Deserialize},
    std::io::{Cursor, Read},
};

pub use self::errors::{CompatDeserializationError, DeserializationError};

/// Deserializer for the XDR format.
///
/// Structure that holds a mutable borrow of the reader it deserializes data
/// from. It has an implementation of `serde::Deserializer` so that it can
/// deserialize data from its XDR representation.
pub struct Deserializer<'r, R>
where
    R: ReadBytesExt + 'r,
{
    reader: &'r mut R,
}

impl<'r, R> Deserializer<'r, R>
where
    R: ReadBytesExt + 'r,
{
    /// Create a new instance that deserializes data from the given generic
    /// reader.
    pub fn new(reader: &'r mut R) -> Self {
        Deserializer { reader }
    }

    fn deserialize_integer(&mut self, bits: u8) -> Result<i32> {
        let value = self.reader.read_i32::<BigEndian>().map_err(|error| {
            DeserializationError::io_error(
                format!("signed {}-bit integer", bits),
                error,
            )
        })?;

        let most_significant_bit: u32 = 1 << (bits - 1);
        let max_value = (most_significant_bit - 1) as i32;
        let min_value = -max_value - 1;

        if value >= min_value && value <= max_value {
            Ok(value)
        } else {
            Err(DeserializationError::InvalidInteger { bits, value }.into())
        }
    }

    fn deserialize_unsigned_integer(&mut self, bits: u8) -> Result<u32> {
        let value = self.reader.read_u32::<BigEndian>().map_err(|error| {
            DeserializationError::io_error(
                format!("unsigned {}-bit integer", bits),
                error,
            )
        })?;

        let most_significant_bit: u64 = 1 << bits;
        let max_value = (most_significant_bit - 1) as u32;

        ensure!(
            value <= max_value,
            DeserializationError::InvalidUnsignedInteger { bits, value }
        );

        Ok(value)
    }

    fn deserialize_sequence<'de, V, S>(
        &mut self,
        visitor: V,
        type_name: S,
        length: u32,
    ) -> Result<V::Value>
    where
        V: Visitor<'de>,
        S: AsRef<str>,
    {
        let type_name = type_name.as_ref();
        let deserializer = SequenceDeserializer::new(length, &type_name, self);

        Ok(visitor.visit_seq(deserializer)?)
    }

    fn deserialize_opaque(&mut self, type_name: &str) -> Result<Vec<u8>> {
        let length = self.reader.read_u32::<BigEndian>().map_err(|error| {
            DeserializationError::io_error(type_name, error)
        })?;

        let padding_size = 4 - (length + 3) % 4 - 1;
        let buffer_length = length + padding_size;

        let mut buffer = Vec::with_capacity(buffer_length as usize);

        buffer.resize(buffer_length as usize, 0);
        self.reader.read_exact(&mut buffer).map_err(|error| {
            DeserializationError::io_error(type_name, error)
        })?;
        buffer.truncate(length as usize);

        Ok(buffer)
    }
}

/// Deserializes data from a generic reader.
///
/// Deserializes data of a given type `T` from a generic instance that
/// implements `Read`.
///
/// The lifetimes of the deserialized data `'de` and of the reader `'r` are
/// different because the deserializer currently is not zero-copy, which means
/// the returned data owns everything it deserialized.
pub fn from_reader<'de, 'r, R, T>(reader: &'r mut R) -> Result<T>
where
    R: Read,
    T: Deserialize<'de>,
{
    let mut deserializer = Deserializer::new(reader);

    Ok(T::deserialize(&mut deserializer)?)
}

/// Deserializes data from a slice of bytes.
///
/// Deserializes data of a given type `T` from a generic instance that can be
/// accessed as a reference to a slice of bytes.
///
/// The deserializer is currently zero-copy, which means that the returned data
/// owns everything it deserialized.
pub fn from_bytes<'de, B, T>(bytes: B) -> Result<T>
where
    B: AsRef<[u8]>,
    T: Deserialize<'de>,
{
    let mut reader = Cursor::new(bytes);

    from_reader(&mut reader)
}

mod deserializer;
mod errors;