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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
//! # This module contains Read/Write adapters for sd0 reading and writing
//!
//!
use std::io::{Read, BufReader, Error as IoError, Result as IoResult, ErrorKind};
use libflate::deflate::Decoder as ZlibDecoder;
use std::convert::{TryFrom, From};
use std::num::TryFromIntError;
use std::fmt::{Display, Formatter, Result as FmtResult};
use std::error::Error;
use assembly_core::borrow::Oom;

/// # Error type for segmented streams
#[derive(Debug)]
pub enum SegmentedError {
    MagicMismatch([u8;5]),
    Read(IoError),
    TryFromInt(TryFromIntError),
    #[cfg(debug_assertions)]
    NotImplemented,
    ZlibMissing,
}

/// Result with segmented error
pub type SegmentedResult<T> = Result<T, SegmentedError>;

impl Error for SegmentedError {}

impl Display for SegmentedError {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        match self {
            SegmentedError::MagicMismatch(arr) => write!(f, "Magic is wrong: {:?}", arr),
            SegmentedError::Read(io) => io.fmt(f),
            SegmentedError::TryFromInt(tfi) => tfi.fmt(f),
            #[cfg(debug_assertions)]
            SegmentedError::NotImplemented => write!(f, "Not implemented!"),
            SegmentedError::ZlibMissing => write!(f, "ZLIB Decoder is None!"),
        }
    }
}

impl From<TryFromIntError> for SegmentedError {
    fn from(e: TryFromIntError) -> SegmentedError {
        SegmentedError::TryFromInt(e)
    }
}


/// # `Read`-Stream wrapper for sd0
///
/// This structure wraps an inner stream, which it treats as an sd0 stream.
/// Initially, the stream does not contain anything, when you call `next_chunk`
/// on an empty stream, the struct can be read again.
pub struct SegmentedChunkStream<'a, T> {
    inner: Oom<'a, T>,
    chunk_remain: usize,
}

pub type ChunkStreamReader<'a, T> = BufReader<SegmentedChunkStream<'a, T>>;
pub type DecoderType<'a,T> = ZlibDecoder<ChunkStreamReader<'a, T>>;
type DecoderOptionType<'a,T> = Option<DecoderType<'a,T>>;
type DecoderOptionResult<'a,T> = SegmentedResult<DecoderOptionType<'a, T>>;


impl<'a, T> SegmentedChunkStream<'a, T>
where T: Read {
    /// Create a new empty chunk stream reader from some reference or object
    pub fn new<'b, I: Into<Oom<'b, T>>>(some: I) -> SegmentedChunkStream<'b, T> {
        SegmentedChunkStream{inner: some.into(), chunk_remain: 0}
    }

    /// Create a new empty chunk stream reader from some reference or object,
    /// initialized to the first chunk
    pub fn init<'b, I: Into<Oom<'b, T>>>(some: I) -> DecoderOptionResult<'b, T> {
        SegmentedChunkStream::new(some).next_chunk()
    }

    /// Load the next chunk
    pub fn next_chunk(mut self) -> DecoderOptionResult<'a, T> {
        let mut chunk_size_bytes: [u8; 4] = [0; 4];
        match self.inner.as_mut().read_exact(&mut chunk_size_bytes) {
            Ok(()) => {
                let size = u32::from_le_bytes(chunk_size_bytes);
                //println!("CHNK: {}", size);
                self.chunk_remain = usize::try_from(size)?;
                let buf_read = BufReader::new(self);
                Ok(Some(ZlibDecoder::new(buf_read)))
            },
            Err(_) => {
                Ok(None)
            }
        }
    }
}

impl<'a, T> Read for SegmentedChunkStream<'a, T>
where T: Read {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
        let buf_len = buf.len();
        //println!("BUF: {}", buf_len);
        //println!("REM: {}", self.chunk_remain);
        match if self.chunk_remain == 0 {
            Ok(0)
        } else if buf_len > self.chunk_remain {
            let max = self.chunk_remain;
            //println!("MAX: {}", max);
            self.chunk_remain = 0;
            self.inner.as_mut().read(&mut buf[..max])
        } else {
            self.chunk_remain -= buf_len;
            self.inner.as_mut().read(buf)
        } {
            Ok(n) => {
                //println!("RES: {}", n);
                Ok(n)
            },
            Err(e) => {
                //println!("ERR: {:?}", e);
                Err(e)
            },
        }
    }
}

/// # A `sd0` streamed file
pub struct SegmentedStream<'a, T> {
    /// The currently active decoder
    decoder: Option<DecoderType<'a,T>>,
}

impl<'a, T> SegmentedStream<'a, T>
where T: Read {
    fn check_magic<'b>(inner: &'b mut T) -> SegmentedResult<()> {
        let mut magic: [u8;5] = [0;5];
        inner.read_exact(&mut magic).map_err(SegmentedError::Read)?;
        if magic == ['s' as u8, 'd' as u8, '0' as u8, 0x01, 0xff] {
            Ok(())
        } else {
            Err(SegmentedError::MagicMismatch(magic))
        }
    }

    /// Create a new stream from a reference to a `Read` object
    pub fn new(inner: &'a mut T) -> SegmentedResult<Self> {
        SegmentedStream::check_magic(inner)?;
        let cs = SegmentedChunkStream::init(inner)?;
        Ok(SegmentedStream{decoder: cs})
    }

    /// Create a new stream from a `Read` object
    pub fn try_from(mut inner: T) -> SegmentedResult<Self> {
        SegmentedStream::check_magic(&mut inner)?;
        let cs = SegmentedChunkStream::init(inner)?;
        Ok(SegmentedStream{decoder: cs})
    }

    /// Internal function to swap out the decoder
    fn next_or_done(&mut self, buf: &mut[u8]) -> IoResult<usize> {
        match std::mem::replace(&mut self.decoder, None) {
            Some(decoder) => match decoder.into_inner().into_inner().next_chunk() {
                Ok(Some(mut decoder)) => {
                    let next_read_len = decoder.read(buf)?;
                    // Store the new decoder
                    std::mem::replace(&mut self.decoder, Some(decoder));
                    // Returned `next_read_len` bytes from the next chunk
                    Ok(next_read_len)
                },
                // There is no upcoming chunk
                Ok(None) => Ok(0),
                // Some error occured
                Err(e) => Err(IoError::new(ErrorKind::Other, e)),
            },
            // This should never ever happen, as we have recently read from the decode
            None => panic!("The sd0 zlib decoder is gone!"),
        }
    }
}

impl<'a, T> Read for SegmentedStream<'a, T>
where T: Read {
    fn read(&mut self, buf: &mut[u8]) -> IoResult<usize> {
        match &mut self.decoder {
            Some(decoder) => {
                let read_len = decoder.read(buf)?;
                // Successfully ead read_len of buf.len() bytes
                if read_len == 0 {
                    // The decode stream is complete, decoder.total_out() bytes were read
                    self.next_or_done(buf)
                } else {
                    // We have read some bytes, though there may be more
                    Ok(read_len)
                }
            },
            None => Ok(0),
        }
    }
}