use crate::Result;
use crate::blocks::common::{BlockHeader, BlockParse, read_string_block};
use crate::blocks::conversion::base::ConversionBlock;
use crate::types::DecodedValue;
use alloc::format;
use alloc::vec::Vec;
pub fn apply_bitfield_text(
block: &ConversionBlock,
value: DecodedValue,
file_data: &[u8],
) -> Result<DecodedValue> {
let raw = match value {
DecodedValue::UnsignedInteger(u) => u,
DecodedValue::SignedInteger(i) => i as u64,
_ => return Ok(value),
};
let mut parts = Vec::new();
let masks = &block.values;
let links = &block.refs;
for (i, &link_addr) in links.iter().enumerate() {
if i >= masks.len() {
break;
}
let mask = masks[i].to_bits();
let masked = raw & mask;
if link_addr == 0 {
continue;
}
#[cfg(feature = "std")]
if let Some(resolved_conversion) = block.get_resolved_conversion(i) {
let decoded_masked =
resolved_conversion.apply_decoded(DecodedValue::UnsignedInteger(masked), &[])?;
if let DecodedValue::String(s) = decoded_masked {
let part = if let Some(name) = resolved_conversion.name_addr {
if let Some(name_text) = read_string_block(file_data, name)? {
format!("{} = {}", name_text, s)
} else {
s
}
} else {
s
};
parts.push(part);
}
continue;
}
let off = link_addr as usize;
if off + 24 > file_data.len() {
if let Some(default_conversion) = block.get_default_conversion() {
let decoded_masked =
default_conversion.apply_decoded(DecodedValue::UnsignedInteger(masked), &[])?;
if let DecodedValue::String(s) = decoded_masked {
parts.push(s);
}
}
continue;
}
let hdr = BlockHeader::from_bytes(&file_data[off..off + 24])?;
if &hdr.id != "##CC" {
continue;
}
let mut nested = ConversionBlock::from_bytes(&file_data[off..])?;
let _ = nested.resolve_formula(file_data);
let decoded_masked =
nested.apply_decoded(DecodedValue::UnsignedInteger(masked), file_data)?;
if let DecodedValue::String(s) = decoded_masked {
let part = if let Some(name_ptr) = nested.name_addr {
if let Some(name) = read_string_block(file_data, name_ptr)? {
format!("{} = {}", name, s)
} else {
s.clone()
}
} else {
s.clone()
};
parts.push(part);
}
}
let out = parts.join("|");
Ok(DecodedValue::String(out))
}