xref: /xiu/protocol/rtmp/src/amf0/amf0_writer.rs (revision 7adc8486)
1 use super::amf0_markers;
2 use super::errors::Amf0WriteErrorValue;
3 use super::Amf0ValueType;
4 use super::Amf0WriteError;
5 use byteorder::BigEndian;
6 use bytes::BytesMut;
7 use netio::bytes_writer::BytesWriter;
8 use std::collections::HashMap;
9 
10 pub struct Amf0Writer {
11     writer: BytesWriter,
12 }
13 
14 impl Amf0Writer {
15     pub fn new(writer: BytesWriter) -> Self {
16         Self { writer: writer }
17     }
18     pub fn write_anys(&mut self, values: &Vec<Amf0ValueType>) -> Result<(), Amf0WriteError> {
19         for val in values {
20             self.write_any(val)?;
21         }
22 
23         Ok(())
24     }
25     pub fn write_any(&mut self, value: &Amf0ValueType) -> Result<(), Amf0WriteError> {
26         match *value {
27             Amf0ValueType::Boolean(ref val) => self.write_bool(&val),
28             Amf0ValueType::Null => self.write_null(),
29             Amf0ValueType::Number(ref val) => self.write_number(&val),
30             Amf0ValueType::UTF8String(ref val) => self.write_string(&val),
31             Amf0ValueType::Object(ref val) => self.write_object(&val),
32             _ => Ok(()),
33         }
34     }
35 
36     pub fn write_number(&mut self, value: &f64) -> Result<(), Amf0WriteError> {
37         self.writer.write_u8(amf0_markers::NUMBER)?;
38         self.writer.write_f64::<BigEndian>(value.clone())?;
39         Ok(())
40     }
41 
42     pub fn write_bool(&mut self, value: &bool) -> Result<(), Amf0WriteError> {
43         self.writer.write_u8(amf0_markers::BOOLEAN)?;
44         self.writer.write_u8(value.clone() as u8)?;
45         Ok(())
46     }
47 
48     pub fn write_string(&mut self, value: &String) -> Result<(), Amf0WriteError> {
49         if value.len() > (u16::max_value() as usize) {
50             return Err(Amf0WriteError {
51                 value: Amf0WriteErrorValue::NormalStringTooLong,
52             });
53         }
54 
55         self.writer.write_u8(amf0_markers::STRING)?;
56         self.writer.write_u16::<BigEndian>(value.len() as u16)?;
57         self.writer.write(value.as_bytes())?;
58 
59         Ok(())
60     }
61 
62     pub fn write_null(&mut self) -> Result<(), Amf0WriteError> {
63         self.writer.write_u8(amf0_markers::NULL)?;
64         Ok(())
65     }
66 
67     pub fn write_object_eof(&mut self) -> Result<(), Amf0WriteError> {
68         self.writer
69             .write_u24::<BigEndian>(amf0_markers::OBJECT_END as u32)?;
70         Ok(())
71     }
72 
73     pub fn write_object(
74         &mut self,
75         properties: &HashMap<String, Amf0ValueType>,
76     ) -> Result<(), Amf0WriteError> {
77         self.writer.write_u8(amf0_markers::OBJECT)?;
78 
79         for (key, value) in properties {
80             self.writer.write_u16::<BigEndian>(key.len() as u16)?;
81             self.writer.write(key.as_bytes())?;
82             self.write_any(value)?;
83         }
84 
85         self.write_object_eof()?;
86         Ok(())
87     }
88 
89     // pub async fn flush(&mut self) -> Result<(), Amf0WriteError> {
90     //     self.writer.flush()?;
91     // }
92 
93     pub fn extract_current_bytes(&mut self) -> BytesMut {
94         self.writer.extract_current_bytes()
95     }
96 }
97