use std::io::Read;
use crate::{
error::MuninError,
nvl_table::NameValueListTable,
primitives::{read_7bit_count, read_7bit_int, read_bool, read_dotnet_string},
string_table::StringTable,
};
pub fn read_dedup_string(
reader: &mut impl Read,
strings: &StringTable,
) -> Result<Option<String>, MuninError> {
let index = read_7bit_int(reader)?;
Ok(strings.get(index)?.map(|s| s.to_string()))
}
pub fn read_optional_string(
reader: &mut impl Read,
strings: &StringTable,
file_format_version: i32,
) -> Result<Option<String>, MuninError> {
if file_format_version < 10 {
if read_bool(reader)? {
Ok(Some(read_dotnet_string(reader)?))
} else {
Ok(None)
}
} else {
read_dedup_string(reader, strings)
}
}
pub fn read_string_dictionary(
reader: &mut impl Read,
strings: &StringTable,
nvl_table: &NameValueListTable,
file_format_version: i32,
) -> Result<Option<Vec<(String, String)>>, MuninError> {
if file_format_version < 10 {
read_legacy_string_dictionary(reader)
} else {
let index = read_7bit_int(reader)?;
if index == 0 {
return Ok(None);
}
nvl_table.resolve(index, strings)
}
}
fn read_legacy_string_dictionary(
reader: &mut impl Read,
) -> Result<Option<Vec<(String, String)>>, MuninError> {
let count = read_7bit_count(reader, "legacy string-dictionary count")?;
if count == 0 {
return Ok(None);
}
let mut result = Vec::with_capacity(count);
for _ in 0..count {
let key = read_dotnet_string(reader)?;
let value = read_dotnet_string(reader)?;
result.push((key, value));
}
Ok(Some(result))
}
#[cfg(test)]
mod tests;