Add file names and line numbers to error messages.
[pspp] / rust / src / lib.rs
index 504d5eb3a645af70428fe144f5bb24567239a13a..8bf72fe02c064c8dcb5f30ff44c8cd6208ec4ba2 100644 (file)
@@ -1,4 +1,3 @@
-#![allow(unused_variables)]
 use endian::{Endian, Parse, ToBytes};
 use flate2::read::ZlibDecoder;
 use num::Integer;
@@ -11,6 +10,7 @@ use std::{
 use thiserror::Error;
 
 pub mod endian;
+pub mod sack;
 
 #[derive(Error, Debug)]
 pub enum Error {
@@ -220,6 +220,7 @@ impl VarType {
 }
 
 trait State {
+    #[allow(clippy::type_complexity)]
     fn read(self: Box<Self>) -> Result<Option<(Record, Box<dyn State>)>, Error>;
 }
 
@@ -270,13 +271,7 @@ impl<R: Read + Seek + 'static> State for Headers<R> {
                 let next_state: Box<dyn State> = match self.0.compression {
                     None => Box::new(Data(self.0)),
                     Some(Compression::Simple) => Box::new(CompressedData::new(self.0)),
-                    Some(Compression::ZLib) => Box::new(CompressedData::new(CommonState {
-                        reader: ZlibDecodeMultiple::new(self.0.reader),
-                        endian: self.0.endian,
-                        bias: self.0.bias,
-                        compression: self.0.compression,
-                        var_types: self.0.var_types
-                    })),
+                    Some(Compression::ZLib) => Box::new(ZlibHeader(self.0)),
                 };
                 return Ok(Some((Record::EndOfHeaders, next_state)));
             }
@@ -291,6 +286,34 @@ impl<R: Read + Seek + 'static> State for Headers<R> {
     }
 }
 
+struct ZlibHeader<R: Read + Seek>(CommonState<R>);
+
+impl<R: Read + Seek + 'static> State for ZlibHeader<R> {
+    fn read(mut self: Box<Self>) -> Result<Option<(Record, Box<dyn State>)>, Error> {
+        let zheader = read_zheader(&mut self.0.reader, self.0.endian)?;
+        Ok(Some((Record::ZHeader(zheader), self)))
+    }
+}
+
+struct ZlibTrailer<R: Read + Seek>(CommonState<R>, ZHeader);
+
+impl<R: Read + Seek + 'static> State for ZlibTrailer<R> {
+    fn read(mut self: Box<Self>) -> Result<Option<(Record, Box<dyn State>)>, Error> {
+        let retval = read_ztrailer(&mut self.0.reader, self.0.endian, self.1.ztrailer_offset, self.1.ztrailer_len)?;
+        let next_state = Box::new(CompressedData::new(CommonState {
+            reader: ZlibDecodeMultiple::new(self.0.reader),
+            endian: self.0.endian,
+            bias: self.0.bias,
+            compression: self.0.compression,
+            var_types: self.0.var_types
+        }));
+        match retval {
+            None => next_state.read(),
+            Some(ztrailer) => Ok(Some((Record::ZTrailer(ztrailer), next_state)))
+        }        
+    }
+}
+
 struct Data<R: Read + Seek>(CommonState<R>);
 
 impl<R: Read + Seek + 'static> State for Data<R> {
@@ -441,7 +464,7 @@ where
     R: Read + Seek,
 {
     fn seek(&mut self, pos: SeekFrom) -> Result<u64, IoError> {
-        unimplemented!();
+        self.reader.as_mut().unwrap().get_mut().seek(pos)
     }
 }
 
@@ -482,10 +505,10 @@ impl Iterator for Reader {
         match self.state.take()?.read() {
             Ok(Some((record, next_state))) => {
                 self.state = Some(next_state);
-                return Some(Ok(record));
+                Some(Ok(record))
             }
-            Ok(None) => return None,
-            Err(error) => return Some(Err(error)),
+            Ok(None) => None,
+            Err(error) => Some(Err(error)),
         }
     }
 }