parse zlib header and trailer
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 29 Jul 2023 04:37:35 +0000 (21:37 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 29 Jul 2023 04:37:35 +0000 (21:37 -0700)
rust/src/lib.rs

index 504d5eb3a645af70428fe144f5bb24567239a13a..49bc74ef84e2430245b16d6b5cb9b8704d267755 100644 (file)
@@ -270,13 +270,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 +285,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> {