diff --git a/Cargo.toml b/Cargo.toml index 43bce0a..05ef905 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,4 @@ tokio = { version = "1.16.1", features = ["full"] } dirs = "4.0.0" serde_json = "1.0.79" serde = { version = "1.0.136", features= ["derive"] } +bytes = "1.1.0" diff --git a/src/mpvctl/mod.rs b/src/mpvctl/mod.rs index 0d0fa9f..93a2d86 100644 --- a/src/mpvctl/mod.rs +++ b/src/mpvctl/mod.rs @@ -1,4 +1,5 @@ mod command; +mod mpv_framed; mod mpvctl; pub use mpvctl::MpvCtl; diff --git a/src/mpvctl/mpv_framed.rs b/src/mpvctl/mpv_framed.rs new file mode 100644 index 0000000..757009a --- /dev/null +++ b/src/mpvctl/mpv_framed.rs @@ -0,0 +1,58 @@ +use bytes::{Buf, BytesMut}; +use std::io::{self, Cursor}; +use tokio::{io::AsyncReadExt, net::unix::OwnedReadHalf}; + +pub struct MpvFramed { + buffer: BytesMut, + socket_read: OwnedReadHalf, +} + +impl MpvFramed { + pub fn new(socket_read: OwnedReadHalf) -> Self { + MpvFramed { + socket_read, + buffer: BytesMut::with_capacity(4 * 1024), + } + } + + pub async fn read_frame( + &mut self, + ) -> Result, Box> { + // + todo!() + } + + fn parse_frame(&mut self) -> Result, Box> { + let mut cursor = Cursor::new(&self.buffer[..]); + if Self::has_frame(&mut cursor) { + let len = cursor.position() as usize; + cursor.set_position(0); + let frame: serde_json::Value = serde_json::from_slice(&cursor.get_ref()[0..len])?; + self.buffer.advance(len); + return Ok(Some(frame)); + } + Ok(None) + } + + fn has_frame(cursor: &mut Cursor<&[u8]>) -> bool { + loop { + match Self::next_byte(cursor) { + Some(nb) if nb == b'\n' => { + return true; + } + Some(_) => (), + None => { + return false; + } + }; + } + } + + fn next_byte(cursor: &mut Cursor<&[u8]>) -> Option { + if !cursor.has_remaining() { + None + } else { + Some(cursor.get_u8()) + } + } +} diff --git a/src/mpvctl/mpvctl.rs b/src/mpvctl/mpvctl.rs index cc9a171..84bce53 100644 --- a/src/mpvctl/mpvctl.rs +++ b/src/mpvctl/mpvctl.rs @@ -1,3 +1,5 @@ +use super::command::Command; +use bytes::BytesMut; use std::collections::HashMap; use std::io::Read; use std::os::unix::prelude::OsStrExt; @@ -7,8 +9,6 @@ use tokio::net::unix::OwnedWriteHalf; use tokio::net::UnixStream; use tokio::sync::oneshot; -use super::command::Command; - pub struct MpvCtl { socket: OwnedWriteHalf, next_request_id: u64,