Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::io::{Read, Write};
- const LH_SZ_LEN_ALL: u16 = 0b0000_0011;
- const LH_SZ_LEN_8: u16 = 0b0000_0001;
- const LH_SZ_LEN_16: u16 = 0b0000_0010;
- const LH_SZ_LEN_32: u16 = 0b0000_0011;
- #[derive(Debug, Fail)]
- pub enum CodecError {
- #[fail(display = "Too less bytes in the header !")]
- MissingHeaderBytes,
- #[fail(display = "Wrong header !")]
- WrongHeader,
- #[fail(display = "Invalide size len (from header) !")]
- WrongSizeLen,
- }
- #[derive(Debug, Clone, Copy)]
- pub enum PacketSizeEncoding {
- B8,
- B16,
- B32,
- None,
- }
- impl From<HiHeader> for PacketSizeEncoding {
- fn from(head: HiHeader) -> Self {
- match head.0 & LH_SZ_LEN_ALL {
- LH_SZ_LEN_8 => PacketSizeEncoding::B8,
- LH_SZ_LEN_16 => PacketSizeEncoding::B16,
- LH_SZ_LEN_32 => PacketSizeEncoding::B32,
- _ => PacketSizeEncoding::None
- }
- }
- }
- #[derive(Debug, Clone, Copy)]
- pub struct PacketId(u16);
- impl From<HiHeader> for PacketId {
- fn from(head: HiHeader) -> Self {
- PacketId(head.0 >> 2)
- }
- }
- #[derive(Debug, Clone, Copy)]
- pub struct HiHeader(u16);
- impl HiHeader {
- fn header_total(&self, side: PacketSide) -> usize {
- let a = match PacketSizeEncoding::from(*self) {
- PacketSizeEncoding::B8 => 1,
- PacketSizeEncoding::B16 => 2,
- PacketSizeEncoding::B32 => 4,
- _ => 0,
- };
- let b = match side {
- Client => 6, // hi header and packet counter
- Server => 2, // hi header only
- };
- a + b
- }
- }
- #[derive(Debug)]
- pub struct PacketHeader {
- hi: HiHeader,
- size: usize,
- }
- impl PacketHeader {
- fn from_bytes(td: &[u8], side: PacketSide) -> Result<PacketHeader, CodecError> {
- if td.len() < 2 {
- return Err(CodecError::MissingHeaderBytes)
- }
- let hi = HiHeader(u16::from_be_bytes([td[0], td[1]]));
- let htotal = hi.header_total(side);
- if td.len() < htotal {
- return Err(CodecError::WrongHeader)
- }
- let size = match PacketSizeEncoding::from(hi) {
- PacketSizeEncoding::B8 => usize::from(td[htotal]),
- PacketSizeEncoding::B16 => usize::from(u16::from_be_bytes([ td[htotal], td[htotal + 1] ])),
- PacketSizeEncoding::B32 => u32::from_be_bytes([ td[htotal], td[htotal + 1], td[htotal + 2], td[htotal + 3] ]) as usize,
- PacketSizeEncoding::None => return Err(CodecError::WrongSizeLen),
- };
- Ok(PacketHeader {
- hi,
- size,
- })
- }
- }
- #[derive(Debug, Clone, Copy)]
- pub enum PacketSide {
- Client,
- Server,
- }
- pub struct DofusCodec {
- buffer: Vec<u8>,
- side: PacketSide,
- }
- impl DofusCodec {
- pub fn new(side: PacketSide) -> Self {
- DofusCodec{buffer: Vec::new(), side}
- }
- }
- impl Write for DofusCodec {
- fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
- let header = PacketHeader::from_bytes(buf, self.side).map(|e| {
- println!("{:?} -> id: {}, len: {}", self.side, PacketId::from(e.hi).0, e.size);
- e
- });
- Ok(buf.len())
- }
- fn flush(&mut self) -> std::io::Result<()> {
- Ok(())
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement