flash_lso/
write.rs

1//! Handles writing of LSO files
2use std::io::Write;
3
4use cookie_factory::bytes::be_u32;
5use cookie_factory::combinator::cond;
6use cookie_factory::combinator::slice;
7use cookie_factory::gen;
8use cookie_factory::sequence::tuple;
9use cookie_factory::SerializeFn;
10
11use crate::amf3::write::AMF3Encoder;
12use crate::nom_utils::write_string;
13use crate::types::{AMFVersion, Header, Lso};
14use crate::{FORMAT_VERSION_AMF0, FORMAT_VERSION_AMF3, HEADER_SIGNATURE, HEADER_VERSION, PADDING};
15
16/// Handles writing a given LSO
17#[derive(Default)]
18pub struct Writer {
19    /// The encoder used for writing Value::AMF3() wrapped types
20    pub amf3_encoder: AMF3Encoder,
21}
22
23impl Writer {
24    /// Write a given LSO
25    pub fn write_full<'a, 'b: 'a, W: Write + 'a>(
26        &'a mut self,
27        lso: &'b Lso,
28    ) -> impl SerializeFn<W> + 'a {
29        let amf0 = cond(
30            lso.header.format_version == AMFVersion::AMF0,
31            crate::amf0::write::write_body(&lso.body),
32        );
33        let amf3 = cond(
34            lso.header.format_version == AMFVersion::AMF3,
35            self.amf3_encoder.write_body(&lso.body),
36        );
37
38        tuple((write_header(&lso.header), amf0, amf3))
39    }
40}
41
42fn write_header<'a, 'b: 'a, W: Write + 'a>(header: &'b Header) -> impl SerializeFn<W> + 'a {
43    tuple((
44        slice(HEADER_VERSION),
45        be_u32(header.length),
46        slice(HEADER_SIGNATURE),
47        write_string(&header.name),
48        slice(PADDING),
49        slice(PADDING),
50        slice(PADDING),
51        cond(
52            header.format_version == AMFVersion::AMF0,
53            slice(&[FORMAT_VERSION_AMF0]),
54        ),
55        cond(
56            header.format_version == AMFVersion::AMF3,
57            slice(&[FORMAT_VERSION_AMF3]),
58        ),
59    ))
60}
61
62/// Write a LSO to a vec of bytes
63pub fn write_to_bytes(lso: &Lso) -> Vec<u8> {
64    let v = vec![];
65
66    let mut s = Writer::default();
67    let serialise = s.write_full(lso);
68    let (buffer, _size) = gen(serialise, v).unwrap();
69    buffer
70}