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