zlib-compressed data compiles
authorBen Pfaff <blp@cs.stanford.edu>
Sat, 29 Jul 2023 03:12:48 +0000 (20:12 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Sat, 29 Jul 2023 03:12:48 +0000 (20:12 -0700)
rust/src/lib.rs

index 963e4ef44850db5c57614c5ef20e82e51ea08b87..3932dcf5b24995767c8a82ace93508815a58fe76 100644 (file)
@@ -273,7 +273,7 @@ impl<R: Read + Seek + 'static> State for Headers<R> {
                         var_types: self.var_types,
                         codes: VecDeque::new(),
                     }),
-                    Some(Compression::ZLib) => Box::new(ZlibData {
+                    Some(Compression::ZLib) => Box::new(CompressedData {
                         reader: ZlibDecodeMultiple::new(self.reader),
                         endian: self.endian,
                         var_types: self.var_types,
@@ -323,116 +323,75 @@ impl<R: Read + Seek + 'static> State for Data<R> {
 }
 
 struct CompressedData<R: Read + Seek> {
-    reader: BufReader<R>,
+    reader: R,
     endian: Endian,
     var_types: Vec<VarType>,
     codes: VecDeque<u8>,
 }
 
-fn read_compressed_data<R>(
-    reader: &mut R,
-    endian: Endian,
-    var_types: &Vec<VarType>,
-    codes: &mut VecDeque<u8>,
-) -> Result<Option<Record>, Error>
-where
-    R: Read + Seek,
-{
-    let case_start = reader.stream_position()?;
-    let mut values = Vec::with_capacity(var_types.len());
-    let bias = 100.0; // XXX
-    for (i, &var_type) in var_types.iter().enumerate() {
-        let value = loop {
-            let Some(code) = codes.pop_front() else {
-                let Some(new_codes): Option<[u8; 8]> = try_read_bytes(reader)? else {
-                    if i == 0 {
-                        return Ok(None);
-                    } else {
-                        let offset = reader.stream_position()?;
-                        return Err(Error::EofInCompressedCase {
-                            offset,
-                            case_ofs: offset - case_start,
-                        });
-                    }
+impl<R: Read + Seek + 'static> State for CompressedData<R> {
+    fn read(mut self: Box<Self>) -> Result<Option<(Record, Box<dyn State>)>, Error> {
+        let case_start = self.reader.stream_position()?;
+        let mut values = Vec::with_capacity(self.var_types.len());
+        let bias = 100.0; // XXX
+        for (i, &var_type) in self.var_types.iter().enumerate() {
+            let value = loop {
+                let Some(code) = self.codes.pop_front() else {
+                    let Some(new_codes): Option<[u8; 8]> = try_read_bytes(&mut self.reader)? else {
+                        if i == 0 {
+                            return Ok(None);
+                        } else {
+                            let offset = self.reader.stream_position()?;
+                            return Err(Error::EofInCompressedCase {
+                                offset,
+                                case_ofs: offset - case_start,
+                            });
+                        }
+                    };
+                    self.codes.extend(new_codes.into_iter());
+                    continue;
                 };
-                codes.extend(new_codes.into_iter());
-                continue;
-            };
-            match code {
-                0 => (),
-                1..=251 => match var_type {
-                    VarType::Number => break Value::Number(Some(code as f64 - bias)),
-                    VarType::String => break Value::String(endian.to_bytes(code as f64 - bias)),
-                },
-                252 => {
-                    if i == 0 {
-                        return Ok(None);
-                    } else {
-                        let offset = reader.stream_position()?;
-                        return Err(Error::PartialCompressedCase {
-                            offset,
-                            case_ofs: offset - case_start,
-                        });
+                match code {
+                    0 => (),
+                    1..=251 => match var_type {
+                        VarType::Number => break Value::Number(Some(code as f64 - bias)),
+                        VarType::String => break Value::String(self.endian.to_bytes(code as f64 - bias)),
+                    },
+                    252 => {
+                        if i == 0 {
+                            return Ok(None);
+                        } else {
+                            let offset = self.reader.stream_position()?;
+                            return Err(Error::PartialCompressedCase {
+                                offset,
+                                case_ofs: offset - case_start,
+                            });
+                        }
                     }
+                    253 => break Value::from_raw(var_type, read_bytes(&mut self.reader)?, self.endian),
+                    254 => match var_type {
+                        VarType::String => break Value::String(*b"        "), // XXX EBCDIC
+                        VarType::Number => {
+                            return Err(Error::CompressedStringExpected {
+                                offset: case_start,
+                                case_ofs: self.reader.stream_position()? - case_start,
+                            })
+                        }
+                    },
+                    255 => match var_type {
+                        VarType::Number => break Value::Number(None),
+                        VarType::String => {
+                            return Err(Error::CompressedNumberExpected {
+                                offset: case_start,
+                                case_ofs: self.reader.stream_position()? - case_start,
+                            })
+                        }
+                    },
                 }
-                253 => break Value::from_raw(var_type, read_bytes(reader)?, endian),
-                254 => match var_type {
-                    VarType::String => break Value::String(*b"        "), // XXX EBCDIC
-                    VarType::Number => {
-                        return Err(Error::CompressedStringExpected {
-                            offset: case_start,
-                            case_ofs: reader.stream_position()? - case_start,
-                        })
-                    }
-                },
-                255 => match var_type {
-                    VarType::Number => break Value::Number(None),
-                    VarType::String => {
-                        return Err(Error::CompressedNumberExpected {
-                            offset: case_start,
-                            case_ofs: reader.stream_position()? - case_start,
-                        })
-                    }
-                },
-            }
-        };
-        values.push(value);
-    }
-    Ok(Some(Record::Case(values)))
-}
-
-impl<R: Read + Seek + 'static> State for CompressedData<R> {
-    fn read(mut self: Box<Self>) -> Result<Option<(Record, Box<dyn State>)>, Error> {
-        match read_compressed_data(
-            &mut self.reader,
-            self.endian,
-            &self.var_types,
-            &mut self.codes,
-        )? {
-            None => Ok(None),
-            Some(record) => Ok(Some((record, self))),
-        }
-    }
-}
-
-struct ZlibData<R: Read + Seek> {
-    reader: ZlibDecodeMultiple<R>,
-    endian: Endian,
-    var_types: Vec<VarType>,
-    codes: VecDeque<u8>,
-}
-
-impl<R: Read + Seek + 'static> State for ZlibData<R> {
-    fn read(mut self: Box<Self>) -> Result<Option<(Record, Box<dyn State>)>, Error> {
-        match read_compressed_data(
-            &mut self.reader,
-            self.endian,
-            &self.var_types,
-            &mut self.codes,
-        )? {
-            None => Ok(None),
-            Some(record) => Ok(Some((record, self))),
+            };
+            values.push(value);
         }
+        Ok(Some((Record::Case(values), self)))
     }
 }