ironrdp_pdu/rdp/vc/dvc/gfx/graphics_messages/
client.rs1use ironrdp_core::{
2 cast_length, ensure_fixed_part_size, ensure_size, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
3 WriteCursor,
4};
5
6use super::CapabilitySet;
7
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct CapabilitiesAdvertisePdu(pub Vec<CapabilitySet>);
10
11impl CapabilitiesAdvertisePdu {
12 const NAME: &'static str = "CapabilitiesAdvertisePdu";
13
14 const FIXED_PART_SIZE: usize = 2 ;
15}
16
17impl Encode for CapabilitiesAdvertisePdu {
18 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
19 ensure_size!(in: dst, size: self.size());
20
21 dst.write_u16(cast_length!("Count", self.0.len())?);
22
23 for capability_set in self.0.iter() {
24 capability_set.encode(dst)?;
25 }
26
27 Ok(())
28 }
29
30 fn name(&self) -> &'static str {
31 Self::NAME
32 }
33
34 fn size(&self) -> usize {
35 Self::FIXED_PART_SIZE + self.0.iter().map(|c| c.size()).sum::<usize>()
36 }
37}
38
39impl<'a> Decode<'a> for CapabilitiesAdvertisePdu {
40 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
41 ensure_fixed_part_size!(in: src);
42
43 let capabilities_count = cast_length!("Count", src.read_u16())?;
44
45 ensure_size!(in: src, size: capabilities_count * CapabilitySet::FIXED_PART_SIZE);
46
47 let capabilities = (0..capabilities_count)
48 .map(|_| CapabilitySet::decode(src))
49 .collect::<Result<_, _>>()?;
50
51 Ok(Self(capabilities))
52 }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct FrameAcknowledgePdu {
57 pub queue_depth: QueueDepth,
58 pub frame_id: u32,
59 pub total_frames_decoded: u32,
60}
61
62impl FrameAcknowledgePdu {
63 const NAME: &'static str = "FrameAcknowledgePdu";
64
65 const FIXED_PART_SIZE: usize = 4 + 4 + 4 ;
66}
67
68impl Encode for FrameAcknowledgePdu {
69 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
70 ensure_fixed_part_size!(in: dst);
71
72 dst.write_u32(self.queue_depth.to_u32());
73 dst.write_u32(self.frame_id);
74 dst.write_u32(self.total_frames_decoded);
75
76 Ok(())
77 }
78
79 fn name(&self) -> &'static str {
80 Self::NAME
81 }
82
83 fn size(&self) -> usize {
84 Self::FIXED_PART_SIZE
85 }
86}
87
88impl<'a> Decode<'a> for FrameAcknowledgePdu {
89 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
90 ensure_fixed_part_size!(in: src);
91
92 let queue_depth = QueueDepth::from_u32(src.read_u32());
93 let frame_id = src.read_u32();
94 let total_frames_decoded = src.read_u32();
95
96 Ok(Self {
97 queue_depth,
98 frame_id,
99 total_frames_decoded,
100 })
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Eq)]
105pub struct CacheImportReplyPdu {
106 pub cache_slots: Vec<u16>,
107}
108
109impl CacheImportReplyPdu {
110 const NAME: &'static str = "CacheImportReplyPdu";
111
112 const FIXED_PART_SIZE: usize = 2 ;
113}
114
115impl Encode for CacheImportReplyPdu {
116 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
117 ensure_size!(in: dst, size: self.size());
118
119 dst.write_u16(cast_length!("Count", self.cache_slots.len())?);
120
121 for cache_slot in self.cache_slots.iter() {
122 dst.write_u16(*cache_slot);
123 }
124
125 Ok(())
126 }
127
128 fn name(&self) -> &'static str {
129 Self::NAME
130 }
131
132 fn size(&self) -> usize {
133 Self::FIXED_PART_SIZE + self.cache_slots.iter().map(|_| 2).sum::<usize>()
134 }
135}
136
137impl<'a> Decode<'a> for CacheImportReplyPdu {
138 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
139 ensure_fixed_part_size!(in: src);
140
141 let entries_count = src.read_u16();
142
143 let cache_slots = (0..entries_count).map(|_| src.read_u16()).collect();
144
145 Ok(Self { cache_slots })
146 }
147}
148
149#[repr(u32)]
150#[derive(Debug, Copy, Clone, PartialEq, Eq)]
151pub enum QueueDepth {
152 Unavailable,
153 AvailableBytes(u32),
154 Suspend,
155}
156
157impl QueueDepth {
158 pub fn from_u32(v: u32) -> Self {
159 match v {
160 0x0000_0000 => Self::Unavailable,
161 0x0000_0001..=0xFFFF_FFFE => Self::AvailableBytes(v),
162 0xFFFF_FFFF => Self::Suspend,
163 }
164 }
165
166 pub fn to_u32(self) -> u32 {
167 match self {
168 Self::Unavailable => 0x0000_0000,
169 Self::AvailableBytes(v) => v,
170 Self::Suspend => 0xFFFF_FFFF,
171 }
172 }
173}