ironrdp_cliprdr/pdu/format_data/
metafile.rs1use std::borrow::Cow;
2
3use bitflags::bitflags;
4use ironrdp_core::{
5 ensure_fixed_part_size, ensure_size, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
6};
7
8bitflags! {
9 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
11 pub struct PackedMetafileMappingMode: u32 {
12 const TEXT = 0x0000_0001;
15 const LO_METRIC = 0x0000_0002;
18 const HI_METRIC = 0x0000_0003;
21 const LO_ENGLISH = 0x0000_0004;
23 const HI_ENGLISH = 0x0000_0005;
25 const TWIPS = 0x0000_0006;
28 const ISOTROPIC = 0x0000_0007;
31 const ANISOTROPIC = 0x0000_0008;
33 }
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct PackedMetafile<'a> {
41 pub mapping_mode: PackedMetafileMappingMode,
42 pub x_ext: u32,
43 pub y_ext: u32,
44 data: Cow<'a, [u8]>,
46}
47
48impl PackedMetafile<'_> {
49 const NAME: &'static str = "CLIPRDR_MFPICT";
50 const FIXED_PART_SIZE: usize = 4 + 4 + 4 ;
51
52 pub fn new(
53 mapping_mode: PackedMetafileMappingMode,
54 x_ext: u32,
55 y_ext: u32,
56 data: impl Into<Cow<'static, [u8]>>,
57 ) -> Self {
58 Self {
59 mapping_mode,
60 x_ext,
61 y_ext,
62 data: data.into(),
63 }
64 }
65
66 pub fn data(&self) -> &[u8] {
67 &self.data
68 }
69}
70
71impl Encode for PackedMetafile<'_> {
72 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
73 ensure_size!(in: dst, size: self.size());
74
75 dst.write_u32(self.mapping_mode.bits());
76 dst.write_u32(self.x_ext);
77 dst.write_u32(self.y_ext);
78 dst.write_slice(&self.data);
79
80 Ok(())
81 }
82
83 fn name(&self) -> &'static str {
84 Self::NAME
85 }
86
87 fn size(&self) -> usize {
88 Self::FIXED_PART_SIZE + self.data.len()
89 }
90}
91
92impl<'de> Decode<'de> for PackedMetafile<'de> {
93 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
94 ensure_fixed_part_size!(in: src);
95
96 let mapping_mode = PackedMetafileMappingMode::from_bits_truncate(src.read_u32());
97 let x_ext = src.read_u32();
98 let y_ext = src.read_u32();
99
100 let data_len = src.len();
101
102 let data = src.read_slice(data_len);
103
104 Ok(Self {
105 mapping_mode,
106 x_ext,
107 y_ext,
108 data: Cow::Borrowed(data),
109 })
110 }
111}