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,
}
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)))
}
}