• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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