#![allow(clippy::cast_possible_truncation)]
use super::{ENTRY_SIZE, KEY_SIZE, LOCA_SIGNATURE, LocaResource};
use crate::error::Result;
use byteorder::{LittleEndian, WriteBytesExt};
use std::fs::File;
use std::io::{BufWriter, Write};
use std::path::Path;
const HEADER_SIZE: u32 = 12;
pub fn write_loca<P: AsRef<Path>>(path: P, resource: &LocaResource) -> Result<()> {
let file = File::create(path)?;
let mut writer = BufWriter::new(file);
let num_entries = resource.entries.len() as u32;
let texts_offset = HEADER_SIZE + (ENTRY_SIZE as u32) * num_entries;
writer.write_u32::<LittleEndian>(LOCA_SIGNATURE)?;
writer.write_u32::<LittleEndian>(num_entries)?;
writer.write_u32::<LittleEndian>(texts_offset)?;
let text_lengths: Vec<u32> = resource
.entries
.iter()
.map(|e| {
if e.text.is_empty() {
0
} else {
e.text.len() as u32 + 1 }
})
.collect();
for (entry, &length) in resource.entries.iter().zip(&text_lengths) {
let key_bytes = entry.key.as_bytes();
let mut key_buf = [0u8; KEY_SIZE];
let copy_len = key_bytes.len().min(KEY_SIZE);
key_buf[..copy_len].copy_from_slice(&key_bytes[..copy_len]);
writer.write_all(&key_buf)?;
writer.write_u16::<LittleEndian>(entry.version)?;
writer.write_u32::<LittleEndian>(length)?;
}
for entry in &resource.entries {
if !entry.text.is_empty() {
writer.write_all(entry.text.as_bytes())?;
writer.write_u8(0)?; }
}
writer.flush()?;
Ok(())
}