jt1078 0.1.0

jt1078协议库实现
Documentation
use jt_util::codec_trait::{CodecEof, CodecError};
use tokio_util::codec::Decoder;
// use tokio_util::codec::Encoder;

use bytes::{Buf, Bytes, BytesMut};
use std::{fmt, io, ops::Index, usize};

#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Jt1078Codec {
    /// 手机号长度(10Byte or 6Byte 为0时表示自动预测 自动预测时至少需要收1个完整包和下一个包的包头)
    sim_len: usize,
    /// 是否已找到头
    find_head: bool,
    /// 包大小(19协议,13协议)
    now_package_size: Option<usize>,
    /// 已结束
    pub eof: bool,
}
const HEAD1078: [u8; 4] = [0x30, 0x31, 0x63, 0x64];
impl Jt1078Codec {
    pub fn new() -> Self {
        Jt1078Codec {
            sim_len: 0,
            find_head: false,
            now_package_size: None,
            eof: false,
        }
    }

    /// 解码 ver 0=sim12 其他=sim20
    fn decode_xxxx(buf: &mut BytesMut, ver: usize) -> Result<Option<Bytes>, Jt1078CodecError> {
        let xxxx_index = match ver {
            0 => 15, //28,
            _ => 19,
        };
        let xxxx = buf.index(xxxx_index) & 0xF0 >> 4;
        let dlen_index = match xxxx {
            0 => xxxx_index + 13, //28,
            1 => xxxx_index + 13,
            2 => xxxx_index + 13,
            3 => xxxx_index + 9, //24,
            _ => xxxx_index + 1, // 16,
        };
        let dlen = match buf.chunk().get(dlen_index..dlen_index + 2) {
            Some(src) => unsafe {
                u16::from_be_bytes(*(src as *const _ as *const [_; 2])) as usize
            },
            None => {
                // 数据不够
                return Ok(None);
            }
        };
        let next_start = dlen_index + 2 + dlen;
        if buf.len() < next_start + 4 {
            // 数据不够
            return Ok(None);
        }
        if buf[next_start..next_start + 4].eq(&HEAD1078) {
            return Ok(Some(buf.split_to(next_start).freeze()));
        } else {
            return Err(Jt1078CodecError::No1078);
        }
    }
    // fn find_head_index(buf: &mut BytesMut) -> Option<usize> {
    //     // buf.starts_with(needle)
    //     let head_index = buf.iter().position(|b| {
    //         [0x30, 0x31, 0x63, 0x64]
    //             .iter()
    //             .any(|delimiter| *b == *delimiter)
    //     });
    //     head_index
    // }
}
impl Default for Jt1078Codec {
    fn default() -> Self {
        Self::new()
    }
}
impl CodecEof for Jt1078Codec {
    fn is_eof(&self) -> bool {
        self.eof
    }
}
impl Decoder for Jt1078Codec {
    type Item = Bytes;
    type Error = Jt1078CodecError;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Jt1078CodecError> {
        if buf.len() < self.sim_len + 12 {
            // 数据不够
            return Ok(None);
        }

        if !buf[..4].eq(&HEAD1078) {
            return Err(Jt1078CodecError::No1078);
        }

        // // 推进buf到找到包头位置
        // if !self.find_head {
        //     // 找包头
        //     match find_head_index(buf) {
        //         Some(offset) => {
        //             // 移除包头前无效数据
        //             buf.advance(offset);
        //             self.find_head = true;
        //         }
        //         None => {
        //             //留下3位,防止包头在最后几位 此处buf长度一定大于3
        //             buf.advance(buf.len() - 3);
        //             self.find_head = false;
        //             return Ok(None);
        //         }
        //     }
        // }
        if self.sim_len == 0 {
            //尝试2013
            let r13 = Self::decode_xxxx(buf, 0);
            if let Ok(Some(ret)) = r13 {
                self.sim_len = 6;
                return Ok(Some(ret));
            }
            //尝试2019
            let r19 = Self::decode_xxxx(buf, 0);
            if let Ok(Some(ret)) = r19 {
                self.sim_len = 10;
                return Ok(Some(ret));
            }
            if r13.is_err() && r19.is_err() {
                return Err(Jt1078CodecError::No1078);
            }
        } else if self.sim_len == 6 {
            return Self::decode_xxxx(buf, 0);
        } else if self.sim_len == 10 {
            return Self::decode_xxxx(buf, 1);
        }
        Ok(None)
    }

    fn decode_eof(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, Jt1078CodecError> {
        self.eof = true;
        Ok(match self.decode(buf)? {
            Some(frame) => Some(frame),
            None => {
                // No terminating newline - return remaining data, if any
                if buf.is_empty() {
                    None
                } else {
                    None
                    //Some(line.to_string())
                }
            }
        })
    }
}
/// An error occurred while encoding or decoding a line.
#[derive(Debug)]
pub enum Jt1078CodecError {
    /// An IO error occurred.
    Io(io::Error),
    /// 非1078封包格式
    No1078,
}

impl fmt::Display for Jt1078CodecError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Jt1078CodecError::Io(e) => write!(f, "{}", e),
            &Jt1078CodecError::No1078 => write!(f, "no 1078"),
        }
    }
}

impl From<io::Error> for Jt1078CodecError {
    fn from(e: io::Error) -> Jt1078CodecError {
        Jt1078CodecError::Io(e)
    }
}

impl CodecError for Jt1078CodecError {
    fn is_io_err(&self) -> bool {
        if let Self::Io(_) = self {
            return true;
        }
        return false;
    }
}

// impl std::error::Error for Jt1078CodecError {}