summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2020-06-07 09:41:43 +0000
committerAlyssa Ross <hi@alyssa.is>2020-06-15 09:37:46 +0000
commit5b422013619bb20b3595c2a89ad8a0a4875e41f9 (patch)
tree4e1d44112aafbce00f6dc1f49d60b56d574cca19
parentfd20697db144fc6e4dbd06856efb61abba236648 (diff)
downloadcrosvm-5b422013619bb20b3595c2a89ad8a0a4875e41f9.tar
crosvm-5b422013619bb20b3595c2a89ad8a0a4875e41f9.tar.gz
crosvm-5b422013619bb20b3595c2a89ad8a0a4875e41f9.tar.bz2
crosvm-5b422013619bb20b3595c2a89ad8a0a4875e41f9.tar.lz
crosvm-5b422013619bb20b3595c2a89ad8a0a4875e41f9.tar.xz
crosvm-5b422013619bb20b3595c2a89ad8a0a4875e41f9.tar.zst
crosvm-5b422013619bb20b3595c2a89ad8a0a4875e41f9.zip
impl MsgOnSocket for String
-rw-r--r--msg_socket/src/msg_on_socket.rs35
1 files changed, 35 insertions, 0 deletions
diff --git a/msg_socket/src/msg_on_socket.rs b/msg_socket/src/msg_on_socket.rs
index ddf8622..06b2e3c 100644
--- a/msg_socket/src/msg_on_socket.rs
+++ b/msg_socket/src/msg_on_socket.rs
@@ -5,6 +5,7 @@
 mod slice;
 mod tuple;
 
+use std::borrow::Cow;
 use std::fmt::{self, Display};
 use std::fs::File;
 use std::mem::{size_of, transmute_copy, MaybeUninit};
@@ -33,6 +34,8 @@ pub enum MsgError {
     Recv(SysError),
     /// The type of a received request or response is unknown.
     InvalidType,
+    /// Deserialized data was not valid.
+    InvalidData,
     /// There was not the expected amount of data when receiving a message. The inner
     /// value is how much data is expected and how much data was actually received.
     BadRecvSize { expected: usize, actual: usize },
@@ -63,6 +66,7 @@ impl Display for MsgError {
             Send(e) => write!(f, "failed to send request or response: {}", e),
             Recv(e) => write!(f, "failed to receive request or response: {}", e),
             InvalidType => write!(f, "invalid type"),
+            InvalidData => write!(f, "invalid data"),
             BadRecvSize { expected, actual } => write!(
                 f,
                 "wrong amount of data received; expected {} bytes; got {} bytes",
@@ -483,6 +487,37 @@ le_impl!(Le16, u16);
 le_impl!(Le32, u32);
 le_impl!(Le64, u64);
 
+impl MsgOnSocket for String {
+    fn uses_fd() -> bool {
+        false
+    }
+
+    fn msg_size(&self) -> usize {
+        Cow::Borrowed(self.as_bytes()).msg_size()
+    }
+
+    unsafe fn read_from_buffer(buffer: &[u8], fds: &[RawFd]) -> MsgResult<(Self, usize)> {
+        let (bytes, fd_count) = Vec::read_from_buffer(buffer, fds)?;
+        match String::from_utf8(bytes) {
+            Ok(string) => Ok((string, fd_count)),
+            Err(_) => Err(MsgError::InvalidData),
+        }
+    }
+
+    fn write_to_buffer(&self, buffer: &mut [u8], fds: &mut [RawFd]) -> MsgResult<usize> {
+        Cow::Borrowed(self.as_bytes()).write_to_buffer(buffer, fds)
+    }
+}
+
+#[test]
+fn round_trip_string() {
+    use crate::{MsgReceiver, MsgSender};
+    let (sock_in, sock_out) = crate::pair::<String, ()>().unwrap();
+    sock_in.send(&"hello world".to_string()).unwrap();
+    let out = sock_out.recv().unwrap();
+    assert_eq!(out, "hello world");
+}
+
 fn simple_read<T: MsgOnSocket>(buffer: &[u8], offset: &mut usize) -> MsgResult<T> {
     assert!(!T::uses_fd());
     // Safety for T::read_from_buffer depends on the given FDs being valid, but we pass no FDs.