ironrdp_cliprdr/pdu/format_data/
palette.rs

1use ironrdp_core::{Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor};
2use ironrdp_pdu::impl_pdu_pod;
3
4/// Represents `PALETTEENTRY`
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct PaletteEntry {
7    pub red: u8,
8    pub green: u8,
9    pub blue: u8,
10    pub extra: u8,
11}
12
13impl PaletteEntry {
14    const SIZE: usize = 1 /* R */ + 1 /* G */ + 1 /* B */ + 1 /* extra */;
15}
16
17/// Represents `CLIPRDR_PALETTE`
18///
19/// NOTE: `Decode` implementation will read all remaining data in cursor as the palette entries.
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub struct ClipboardPalette {
22    pub entries: Vec<PaletteEntry>,
23}
24
25impl_pdu_pod!(ClipboardPalette);
26
27impl ClipboardPalette {
28    const NAME: &'static str = "CLIPRDR_PALETTE";
29}
30
31impl Encode for ClipboardPalette {
32    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
33        for entry in &self.entries {
34            dst.write_u8(entry.red);
35            dst.write_u8(entry.green);
36            dst.write_u8(entry.blue);
37            dst.write_u8(entry.extra);
38        }
39
40        Ok(())
41    }
42
43    fn name(&self) -> &'static str {
44        Self::NAME
45    }
46
47    fn size(&self) -> usize {
48        self.entries.len() * PaletteEntry::SIZE
49    }
50}
51
52impl<'de> Decode<'de> for ClipboardPalette {
53    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
54        let entries_count = src.len() / PaletteEntry::SIZE;
55
56        let mut entries = Vec::with_capacity(entries_count);
57        for _ in 0..entries_count {
58            let red = src.read_u8();
59            let green = src.read_u8();
60            let blue = src.read_u8();
61            let extra = src.read_u8();
62
63            entries.push(PaletteEntry {
64                red,
65                green,
66                blue,
67                extra,
68            });
69        }
70
71        Ok(Self { entries })
72    }
73}