#![allow(dead_code)]
use super::record::Record;
use crate::error::Result;
use crate::model::{Paragraph, Table, TableCell, TableRow};
pub mod ctrl_id {
pub const SECD: u32 = u32::from_le_bytes(*b"secd");
pub const COLD: u32 = u32::from_le_bytes(*b"cold");
pub const TBL: u32 = u32::from_le_bytes(*b"tbl ");
pub const GSO: u32 = u32::from_le_bytes(*b"gso ");
pub const EQED: u32 = u32::from_le_bytes(*b"eqed");
pub const HEADER: u32 = u32::from_le_bytes(*b"head");
pub const FOOTER: u32 = u32::from_le_bytes(*b"foot");
pub const FN: u32 = u32::from_le_bytes(*b"fn ");
pub const EN: u32 = u32::from_le_bytes(*b"en ");
pub const ATNO: u32 = u32::from_le_bytes(*b"atno");
pub const NWNO: u32 = u32::from_le_bytes(*b"nwno");
pub const PGCT: u32 = u32::from_le_bytes(*b"pgct");
pub const TCMT: u32 = u32::from_le_bytes(*b"tcmt");
pub const FIELD: u32 = u32::from_le_bytes(*b"fld ");
}
pub struct ControlParser;
impl ControlParser {
pub fn parse_ctrl_type(record: &Record) -> Result<u32> {
if record.data().len() < 4 {
return Err(crate::error::Error::InvalidData(
"Control header too small".into(),
));
}
Ok(u32::from_le_bytes([
record.data()[0],
record.data()[1],
record.data()[2],
record.data()[3],
]))
}
pub fn parse_table(
_ctrl_header: &Record,
list_header: &Record,
_cell_records: &[Record],
) -> Result<Table> {
let data = list_header.data();
if data.len() < 30 {
return Err(crate::error::Error::InvalidData(
"ListHeader too small for table".into(),
));
}
let row_count = u16::from_le_bytes([data[0], data[1]]) as usize;
let col_count = u16::from_le_bytes([data[2], data[3]]) as usize;
let mut table = Table::new();
table.has_header = true;
for _ in 0..row_count {
let mut row = TableRow::new();
for _ in 0..col_count {
row.cells.push(TableCell::new());
}
table.rows.push(row);
}
Ok(table)
}
pub fn parse_equation(record: &Record) -> Result<String> {
let data = record.data();
if data.len() > 16 {
let script_data = &data[16..];
if let Ok(script) = decode_utf16le_string(script_data) {
return Ok(script);
}
}
Ok(String::new())
}
pub fn parse_image(record: &Record) -> Result<Option<String>> {
let _data = record.data();
Ok(None)
}
}
fn decode_utf16le_string(data: &[u8]) -> Result<String> {
let mut u16_values = Vec::new();
for chunk in data.chunks_exact(2) {
let value = u16::from_le_bytes([chunk[0], chunk[1]]);
if value == 0 {
break;
}
u16_values.push(value);
}
String::from_utf16(&u16_values).map_err(|e| crate::error::Error::Encoding(e.to_string()))
}
#[derive(Debug, Default)]
pub struct CellInfo {
pub row: usize,
pub col: usize,
pub rowspan: u32,
pub colspan: u32,
pub content: Vec<Paragraph>,
}