rakata_formats/ssf/
writer.rs

1//! SSF binary writer.
2
3use std::io::{Cursor, Write};
4
5use crate::binary::{checked_to_usize, write_u32};
6
7use super::{Ssf, SsfBinaryError, FILE_HEADER_SIZE, SSF_MAGIC, SSF_VERSION_V11};
8
9/// Writes an SSF file to a writer.
10pub fn write_ssf<W: Write>(writer: &mut W, ssf: &Ssf) -> Result<(), SsfBinaryError> {
11    let sound_table_offset = checked_to_usize(ssf.sound_table_offset, "sound_table_offset")?;
12    if sound_table_offset < FILE_HEADER_SIZE {
13        return Err(SsfBinaryError::InvalidHeader(
14            "sound table offset overlaps SSF header".into(),
15        ));
16    }
17
18    writer.write_all(&SSF_MAGIC)?;
19    writer.write_all(&SSF_VERSION_V11)?;
20    write_u32(writer, ssf.sound_table_offset)?;
21
22    if sound_table_offset > FILE_HEADER_SIZE {
23        writer.write_all(&vec![0_u8; sound_table_offset - FILE_HEADER_SIZE])?;
24    }
25
26    for strref in &ssf.sounds {
27        writer.write_all(&strref.raw().to_le_bytes())?;
28    }
29
30    for strref in &ssf.reserved_entries {
31        writer.write_all(&strref.raw().to_le_bytes())?;
32    }
33
34    Ok(())
35}
36
37/// Serializes an SSF file into bytes.
38pub fn write_ssf_to_vec(ssf: &Ssf) -> Result<Vec<u8>, SsfBinaryError> {
39    let mut cursor = Cursor::new(Vec::new());
40    write_ssf(&mut cursor, ssf)?;
41    Ok(cursor.into_inner())
42}