1 use { 2 super::{amf0_markers, errors::Amf0WriteErrorValue, Amf0ValueType, Amf0WriteError}, 3 byteorder::BigEndian, 4 bytes::BytesMut, 5 bytesio::bytes_writer::BytesWriter, 6 indexmap::IndexMap, 7 }; 8 9 #[derive(Default)] 10 pub struct Amf0Writer { 11 writer: BytesWriter, 12 } 13 14 impl Amf0Writer { new() -> Self15 pub fn new() -> Self { 16 Self { 17 writer: BytesWriter::new(), 18 } 19 } write_anys(&mut self, values: &Vec<Amf0ValueType>) -> Result<(), Amf0WriteError>20 pub fn write_anys(&mut self, values: &Vec<Amf0ValueType>) -> Result<(), Amf0WriteError> { 21 for val in values { 22 self.write_any(val)?; 23 } 24 25 Ok(()) 26 } write_any(&mut self, value: &Amf0ValueType) -> Result<(), Amf0WriteError>27 pub fn write_any(&mut self, value: &Amf0ValueType) -> Result<(), Amf0WriteError> { 28 match *value { 29 Amf0ValueType::Boolean(ref val) => self.write_bool(val), 30 Amf0ValueType::Null => self.write_null(), 31 Amf0ValueType::Number(ref val) => self.write_number(val), 32 Amf0ValueType::UTF8String(ref val) => self.write_string(val), 33 Amf0ValueType::Object(ref val) => self.write_object(val), 34 Amf0ValueType::EcmaArray(ref val) => self.write_eacm_array(val), 35 _ => Ok(()), 36 } 37 } 38 write_number(&mut self, value: &f64) -> Result<(), Amf0WriteError>39 pub fn write_number(&mut self, value: &f64) -> Result<(), Amf0WriteError> { 40 self.writer.write_u8(amf0_markers::NUMBER)?; 41 self.writer.write_f64::<BigEndian>(*value)?; 42 Ok(()) 43 } 44 write_bool(&mut self, value: &bool) -> Result<(), Amf0WriteError>45 pub fn write_bool(&mut self, value: &bool) -> Result<(), Amf0WriteError> { 46 self.writer.write_u8(amf0_markers::BOOLEAN)?; 47 self.writer.write_u8(*value as u8)?; 48 Ok(()) 49 } 50 write_string(&mut self, value: &String) -> Result<(), Amf0WriteError>51 pub fn write_string(&mut self, value: &String) -> Result<(), Amf0WriteError> { 52 if value.len() > (u16::max_value() as usize) { 53 return Err(Amf0WriteError { 54 value: Amf0WriteErrorValue::NormalStringTooLong, 55 }); 56 } 57 58 self.writer.write_u8(amf0_markers::STRING)?; 59 self.writer.write_u16::<BigEndian>(value.len() as u16)?; 60 self.writer.write(value.as_bytes())?; 61 62 Ok(()) 63 } 64 write_null(&mut self) -> Result<(), Amf0WriteError>65 pub fn write_null(&mut self) -> Result<(), Amf0WriteError> { 66 self.writer.write_u8(amf0_markers::NULL)?; 67 Ok(()) 68 } 69 write_object_eof(&mut self) -> Result<(), Amf0WriteError>70 pub fn write_object_eof(&mut self) -> Result<(), Amf0WriteError> { 71 self.writer 72 .write_u24::<BigEndian>(amf0_markers::OBJECT_END as u32)?; 73 Ok(()) 74 } 75 write_object( &mut self, properties: &IndexMap<String, Amf0ValueType>, ) -> Result<(), Amf0WriteError>76 pub fn write_object( 77 &mut self, 78 properties: &IndexMap<String, Amf0ValueType>, 79 ) -> Result<(), Amf0WriteError> { 80 self.writer.write_u8(amf0_markers::OBJECT)?; 81 82 for (key, value) in properties { 83 self.writer.write_u16::<BigEndian>(key.len() as u16)?; 84 self.writer.write(key.as_bytes())?; 85 self.write_any(value)?; 86 } 87 88 self.write_object_eof()?; 89 Ok(()) 90 } 91 write_eacm_array( &mut self, properties: &IndexMap<String, Amf0ValueType>, ) -> Result<(), Amf0WriteError>92 pub fn write_eacm_array( 93 &mut self, 94 properties: &IndexMap<String, Amf0ValueType>, 95 ) -> Result<(), Amf0WriteError> { 96 self.writer.write_u8(amf0_markers::ECMA_ARRAY)?; 97 self.writer 98 .write_u32::<BigEndian>(properties.len() as u32)?; 99 100 for (key, value) in properties { 101 self.writer.write_u16::<BigEndian>(key.len() as u16)?; 102 self.writer.write(key.as_bytes())?; 103 self.write_any(value)?; 104 } 105 106 self.write_object_eof()?; 107 Ok(()) 108 } 109 110 // pub async fn flush(&mut self) -> Result<(), Amf0WriteError> { 111 // self.writer.flush()?; 112 // } 113 extract_current_bytes(&mut self) -> BytesMut114 pub fn extract_current_bytes(&mut self) -> BytesMut { 115 self.writer.extract_current_bytes() 116 } 117 get_current_bytes(&mut self) -> BytesMut118 pub fn get_current_bytes(&mut self) -> BytesMut { 119 self.writer.get_current_bytes() 120 } 121 len(&self) -> usize122 pub fn len(&self) -> usize { 123 self.writer.len() 124 } is_empty(&self) -> bool125 pub fn is_empty(&self) -> bool { 126 self.len() == 0 127 } 128 } 129