use std::ops::{Deref, DerefMut};
use crate::error::SshResult;
use super::Packet;
#[derive(Debug, Clone)]
pub(crate) struct Data(Vec<u8>);
impl Default for Data {
fn default() -> Self {
Self::new()
}
}
impl Data {
pub fn new() -> Data {
Data(Vec::new())
}
#[allow(clippy::uninit_vec)]
pub fn uninit_new(len: usize) -> Data {
let mut v = Vec::with_capacity(len);
unsafe { v.set_len(len) }
Data(v)
}
pub fn put_u8(&mut self, v: u8) -> &mut Self {
self.0.push(v);
self
}
pub fn put_u32(&mut self, v: u32) -> &mut Self {
let vec = v.to_be_bytes().to_vec();
self.0.extend(&vec);
self
}
pub fn put_str(&mut self, str: &str) -> &mut Self {
let v = str.as_bytes();
self.put_u32(v.len() as u32);
self.0.extend(v);
self
}
pub fn put_u8s(&mut self, v: &[u8]) -> &mut Self {
self.put_u32(v.len() as u32);
self.0.extend(v);
self
}
pub fn put_mpint(&mut self, v: &[u8]) -> Vec<u8> {
let mut result: Vec<u8> = Vec::new();
if v[0] & 0x80 != 0 {
result.push(0);
}
result.extend(v);
self.put_u8s(&result).to_vec()
}
pub fn skip(&mut self, size: usize) {
self.0.drain(..size);
}
pub fn get_u8(&mut self) -> u8 {
self.0.remove(0)
}
pub fn get_u32(&mut self) -> u32 {
let u32_buf = self.0.drain(..4).into_iter().collect::<Vec<u8>>();
u32::from_be_bytes(u32_buf.try_into().unwrap())
}
pub fn get_u8s(&mut self) -> Vec<u8> {
let len = self.get_u32() as usize;
let bytes = self.0.drain(..len).into_iter().collect::<Vec<u8>>();
bytes
}
pub fn into_inner(self) -> Vec<u8> {
self.0
}
}
impl From<Vec<u8>> for Data {
fn from(v: Vec<u8>) -> Self {
Data(v)
}
}
impl From<&[u8]> for Data {
fn from(v: &[u8]) -> Self {
Data(v.into())
}
}
impl From<Data> for Vec<u8> {
fn from(data: Data) -> Self {
data.0
}
}
impl Deref for Data {
type Target = Vec<u8>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Data {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl<'a> Packet<'a> for Data {
fn pack(self, client: &'a mut crate::client::Client) -> super::packet::SecPacket<'a> {
(self, client).into()
}
fn unpack(pkt: super::packet::SecPacket) -> SshResult<Self>
where
Self: Sized,
{
Ok(pkt.into_inner())
}
}