ironrdp_pdu/rdp/capability_sets/
bitmap_cache.rs1#[cfg(test)]
2mod tests;
3
4use bitflags::bitflags;
5use ironrdp_core::{
6 ensure_fixed_part_size, read_padding, write_padding, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
7 WriteCursor,
8};
9
10pub const BITMAP_CACHE_ENTRIES_NUM: usize = 3;
11
12const BITMAP_CACHE_LENGTH: usize = 36;
13const BITMAP_CACHE_REV2_LENGTH: usize = 36;
14const CELL_INFO_LENGTH: usize = 4;
15const BITMAP_CACHE_REV2_CELL_INFO_NUM: usize = 5;
16const CACHE_ENTRY_LENGTH: usize = 4;
17
18#[derive(Debug, PartialEq, Eq, Clone)]
19pub struct BitmapCache {
20 pub caches: [CacheEntry; BITMAP_CACHE_ENTRIES_NUM],
21}
22
23impl BitmapCache {
24 const NAME: &'static str = "BitmapCache";
25
26 const FIXED_PART_SIZE: usize = BITMAP_CACHE_LENGTH;
27}
28
29impl Encode for BitmapCache {
30 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
31 ensure_fixed_part_size!(in: dst);
32
33 write_padding!(dst, 24);
34
35 for cache in self.caches.iter() {
36 cache.encode(dst)?;
37 }
38
39 Ok(())
40 }
41
42 fn name(&self) -> &'static str {
43 Self::NAME
44 }
45
46 fn size(&self) -> usize {
47 Self::FIXED_PART_SIZE
48 }
49}
50
51impl<'de> Decode<'de> for BitmapCache {
52 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
53 ensure_fixed_part_size!(in: src);
54
55 read_padding!(src, 24);
56
57 let mut caches = [CacheEntry::default(); BITMAP_CACHE_ENTRIES_NUM];
58
59 for cache in caches.iter_mut() {
60 *cache = CacheEntry::decode(src)?;
61 }
62
63 Ok(BitmapCache { caches })
64 }
65}
66
67#[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
68pub struct CacheEntry {
69 pub entries: u16,
70 pub max_cell_size: u16,
71}
72
73impl CacheEntry {
74 const NAME: &'static str = "CacheEntry";
75
76 const FIXED_PART_SIZE: usize = CACHE_ENTRY_LENGTH;
77}
78
79impl Encode for CacheEntry {
80 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
81 ensure_fixed_part_size!(in: dst);
82
83 dst.write_u16(self.entries);
84 dst.write_u16(self.max_cell_size);
85
86 Ok(())
87 }
88
89 fn name(&self) -> &'static str {
90 Self::NAME
91 }
92
93 fn size(&self) -> usize {
94 Self::FIXED_PART_SIZE
95 }
96}
97
98impl<'de> Decode<'de> for CacheEntry {
99 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
100 ensure_fixed_part_size!(in: src);
101
102 let entries = src.read_u16();
103 let max_cell_size = src.read_u16();
104
105 Ok(CacheEntry { entries, max_cell_size })
106 }
107}
108
109bitflags! {
110 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
111 pub struct CacheFlags: u16 {
112 const PERSISTENT_KEYS_EXPECTED_FLAG = 1;
113 const ALLOW_CACHE_WAITING_LIST_FLAG = 2;
114 }
115}
116
117#[derive(Debug, PartialEq, Eq, Clone)]
118pub struct BitmapCacheRev2 {
119 pub cache_flags: CacheFlags,
120 pub num_cell_caches: u8,
121 pub cache_cell_info: [CellInfo; BITMAP_CACHE_REV2_CELL_INFO_NUM],
122}
123
124impl BitmapCacheRev2 {
125 const NAME: &'static str = "BitmapCacheRev2";
126
127 const FIXED_PART_SIZE: usize = BITMAP_CACHE_REV2_LENGTH;
128}
129
130impl Encode for BitmapCacheRev2 {
131 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
132 ensure_fixed_part_size!(in: dst);
133
134 dst.write_u16(self.cache_flags.bits());
135 write_padding!(dst, 1);
136 dst.write_u8(self.num_cell_caches);
137
138 for cell_info in self.cache_cell_info.iter() {
139 cell_info.encode(dst)?;
140 }
141
142 write_padding!(dst, 12);
143
144 Ok(())
145 }
146
147 fn name(&self) -> &'static str {
148 Self::NAME
149 }
150
151 fn size(&self) -> usize {
152 Self::FIXED_PART_SIZE
153 }
154}
155
156impl<'de> Decode<'de> for BitmapCacheRev2 {
157 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
158 ensure_fixed_part_size!(in: src);
159
160 let cache_flags = CacheFlags::from_bits_truncate(src.read_u16());
161 let _padding = src.read_u8();
162 let num_cell_caches = src.read_u8();
163
164 let mut cache_cell_info = [CellInfo::default(); BITMAP_CACHE_REV2_CELL_INFO_NUM];
165
166 for cell in cache_cell_info.iter_mut() {
167 *cell = CellInfo::decode(src)?;
168 }
169
170 read_padding!(src, 12);
171
172 Ok(BitmapCacheRev2 {
173 cache_flags,
174 num_cell_caches,
175 cache_cell_info,
176 })
177 }
178}
179
180#[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
181pub struct CellInfo {
182 pub num_entries: u32,
183 pub is_cache_persistent: bool,
184}
185
186impl CellInfo {
187 const NAME: &'static str = "CellInfo";
188
189 const FIXED_PART_SIZE: usize = CELL_INFO_LENGTH;
190}
191
192impl Encode for CellInfo {
193 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
194 ensure_fixed_part_size!(in: dst);
195
196 let mut data = self.num_entries;
197
198 if self.is_cache_persistent {
199 data |= 1 << 31;
200 }
201
202 dst.write_u32(data);
203
204 Ok(())
205 }
206
207 fn name(&self) -> &'static str {
208 Self::NAME
209 }
210
211 fn size(&self) -> usize {
212 Self::FIXED_PART_SIZE
213 }
214}
215
216impl<'de> Decode<'de> for CellInfo {
217 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
218 ensure_fixed_part_size!(in: src);
219
220 let cell_info = src.read_u32();
221
222 let num_entries = cell_info & !(1 << 31);
223 let is_cache_persistent = cell_info >> 31 != 0;
224
225 Ok(CellInfo {
226 num_entries,
227 is_cache_persistent,
228 })
229 }
230}