+ Ok(Some(Record::Case(values)))
+ }
+ ReaderState::CompressedData(endian, ref mut codes) => {
+ let case_start = self.r.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) = codes.pop_front() else {
+ let Some(new_codes): Option<[u8; 8]> = try_read_bytes(&mut self.r)? else {
+ if i == 0 {
+ return Ok(None);
+ } else {
+ let offset = self.r.stream_position()?;
+ return Err(Error::EofInCompressedCase { offset, case_ofs: offset - case_start});
+ }
+ };
+ 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 = self.r.stream_position()?;
+ return Err(Error::PartialCompressedCase {
+ offset,
+ case_ofs: offset - case_start,
+ });
+ }
+ }
+ 253 => break Value::from_raw(
+ var_type,
+ read_bytes(&mut self.r)?,
+ 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.r.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.r.stream_position()? - case_start,})
+ }
+ }
+ }
+ };
+ values.push(value);
+ }
+ Ok(Some(Record::Case(values)))