use super::super::{command::*, utils::*};
use std::io::*;
const MAX_RESPONSE_SIZE: usize = 4096;
const ESC: u8 = b'\x1b';
pub trait KittyResponseReader {
fn read_response(&mut self) -> Result<Option<Response>>;
fn has_kitty_and_device_query_responses(&mut self) -> Result<bool>;
}
impl<ReadT> KittyResponseReader for ReadT
where
ReadT: Read,
{
fn read_response(&mut self) -> Result<Option<Response>> {
if (self.read_byte()? != ESC) || (self.read_byte()? != b'_') || (self.read_byte()? != b'G') {
return Ok(None);
}
let mut response = Vec::default();
let mut size = 0;
loop {
match self.read_byte()? {
ESC => break,
byte => {
if size >= MAX_RESPONSE_SIZE {
return Ok(None);
}
size += 1;
response.push(byte);
}
}
}
if self.read_byte()? != b'\\' {
return Ok(None);
}
Ok(Some(response.as_slice().try_into()?))
}
fn has_kitty_and_device_query_responses(&mut self) -> Result<bool> {
if self.read_byte()? != ESC {
return Ok(false);
}
match self.read_byte()? {
b'?' => {
loop {
if self.read_byte()? == b'c' {
break;
}
}
return Ok(false);
}
b'_' => {}
_ => return Ok(false),
}
if self.read_byte()? != b'G' {
return Ok(false);
}
loop {
if self.read_byte()? == ESC {
break;
}
}
if (self.read_byte()? != b'\\')
|| (self.read_byte()? != ESC)
|| (self.read_byte()? != b'[')
|| (self.read_byte()? != b'?')
{
return Ok(false);
}
loop {
if self.read_byte()? == b'c' {
break;
}
}
Ok(true)
}
}