1 // Copyright 2023 The ChromiumOS Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 use std::collections::BTreeMap; 6 use std::io::Read; 7 use std::io::Write; 8 9 use zerocopy::AsBytes; 10 use zerocopy::FromBytes; 11 12 pub struct RutabagaSnapshot { 13 pub resources: BTreeMap<u32, RutabagaResourceSnapshot>, 14 } 15 16 pub struct RutabagaResourceSnapshot { 17 pub resource_id: u32, 18 pub width: u32, 19 pub height: u32, 20 } 21 22 impl RutabagaSnapshot { 23 // To avoid adding a build dependency, we use a custom serialization format. It is an internal 24 // detail, doesn't need to support host migration (e.g. we don't need to care about endianess 25 // or integer sizes), and isn't expected to be stable across releases. serialize_to(&self, w: &mut impl Write) -> std::io::Result<()>26 pub fn serialize_to(&self, w: &mut impl Write) -> std::io::Result<()> { 27 fn write(w: &mut impl Write, v: impl AsBytes) -> std::io::Result<()> { 28 w.write_all(v.as_bytes()) 29 } 30 31 write(w, self.resources.len())?; 32 for (id, resource) in self.resources.iter() { 33 assert_eq!(*id, resource.resource_id); 34 write(w, resource.resource_id)?; 35 write(w, resource.width)?; 36 write(w, resource.height)?; 37 } 38 39 Ok(()) 40 } 41 deserialize_from(r: &mut impl Read) -> std::io::Result<Self>42 pub fn deserialize_from(r: &mut impl Read) -> std::io::Result<Self> { 43 fn read<T: AsBytes + FromBytes + Default>(r: &mut impl Read) -> std::io::Result<T> { 44 let mut v: T = Default::default(); 45 r.read_exact(v.as_bytes_mut())?; 46 Ok(v) 47 } 48 49 let num_resources: usize = read::<usize>(r)?; 50 let mut resources = BTreeMap::new(); 51 for _ in 0..num_resources { 52 let resource_id = read(r)?; 53 let width = read(r)?; 54 let height = read(r)?; 55 resources.insert( 56 resource_id, 57 RutabagaResourceSnapshot { 58 resource_id, 59 width, 60 height, 61 }, 62 ); 63 } 64 65 // Verify we have consumed the all the input by checking for EOF. 66 let mut buf = [0u8]; 67 if r.read(&mut buf)? != 0 { 68 return Err(std::io::ErrorKind::InvalidData.into()); 69 } 70 71 Ok(RutabagaSnapshot { resources }) 72 } 73 } 74