use crate::error::{Result, SpssError};
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct LongStringMissingEntry {
pub var_name: String,
pub n_values: u8,
pub values: Vec<Vec<u8>>,
}
pub fn parse_long_string_missing(data: &[u8]) -> Result<Vec<LongStringMissingEntry>> {
let mut result = Vec::new();
let mut pos = 0;
while pos + 4 <= data.len() {
let name_len = read_i32_le(data, pos)? as usize;
pos += 4;
if pos + name_len > data.len() {
break;
}
let var_name = String::from_utf8_lossy(&data[pos..pos + name_len])
.trim()
.to_string();
pos += name_len;
if pos >= data.len() {
break;
}
let n_values = data[pos];
pos += 1;
if pos + 4 > data.len() {
break;
}
let value_len = read_i32_le(data, pos)? as usize;
pos += 4;
let mut values = Vec::with_capacity(n_values as usize);
for _ in 0..n_values {
if pos + value_len > data.len() {
break;
}
values.push(data[pos..pos + value_len].to_vec());
pos += value_len;
}
result.push(LongStringMissingEntry {
var_name,
n_values,
values,
});
}
Ok(result)
}
fn read_i32_le(data: &[u8], pos: usize) -> Result<i32> {
if pos + 4 > data.len() {
return Err(SpssError::TruncatedFile {
expected: pos + 4,
actual: data.len(),
});
}
let bytes: [u8; 4] = data[pos..pos + 4].try_into().unwrap();
Ok(i32::from_le_bytes(bytes))
}