@@ -28,44 +28,25 @@ const MAX_FASTPATH_UPDATE_SIZE: usize = 16_374;
28
28
const FASTPATH_HEADER_SIZE : usize = 6 ;
29
29
30
30
pub ( crate ) struct UpdateEncoder {
31
- buffer : Vec < u8 > ,
32
- bitmap : BitmapEncoder ,
33
- remotefx : Option < ( RfxEncoder , u8 ) > ,
34
- update : for <' a > fn ( & ' a mut UpdateEncoder , BitmapUpdate ) -> Result < UpdateFragmenter < ' a > > ,
31
+ pdu_encoder : PduEncoder ,
32
+ bitmap_updater : BitmapUpdater ,
35
33
}
36
34
37
35
impl UpdateEncoder {
38
36
pub ( crate ) fn new ( surface_flags : CmdFlags , remotefx : Option < ( EntropyBits , u8 ) > ) -> Self {
39
- let update = if !surface_flags. contains ( CmdFlags :: SET_SURFACE_BITS ) {
40
- Self :: bitmap_update
37
+ let pdu_encoder = PduEncoder :: new ( ) ;
38
+ let bitmap_updater = if !surface_flags. contains ( CmdFlags :: SET_SURFACE_BITS ) {
39
+ BitmapUpdater :: Bitmap ( BitmapHandler :: new ( ) )
41
40
} else if remotefx. is_some ( ) {
42
- Self :: remotefx_update
41
+ let ( algo, id) = remotefx. unwrap ( ) ;
42
+ BitmapUpdater :: RemoteFx ( RemoteFxHandler :: new ( algo, id) )
43
43
} else {
44
- Self :: none_update
44
+ BitmapUpdater :: None ( NoneHandler )
45
45
} ;
46
46
47
47
Self {
48
- buffer : vec ! [ 0 ; 16384 ] ,
49
- bitmap : BitmapEncoder :: new ( ) ,
50
- remotefx : remotefx. map ( |( algo, id) | ( RfxEncoder :: new ( algo) , id) ) ,
51
- update,
52
- }
53
- }
54
-
55
- fn encode_pdu ( & mut self , pdu : impl Encode ) -> Result < usize > {
56
- loop {
57
- let mut cursor = WriteCursor :: new ( self . buffer . as_mut_slice ( ) ) ;
58
- match pdu. encode ( & mut cursor) {
59
- Err ( e) => match e. kind ( ) {
60
- ironrdp_core:: EncodeErrorKind :: NotEnoughBytes { .. } => {
61
- self . buffer . resize ( self . buffer . len ( ) * 2 , 0 ) ;
62
- debug ! ( "encoder buffer resized to: {}" , self . buffer. len( ) * 2 ) ;
63
- }
64
-
65
- _ => Err ( e) . context ( "PDU encode error" ) ?,
66
- } ,
67
- Ok ( ( ) ) => return Ok ( cursor. pos ( ) ) ,
68
- }
48
+ pdu_encoder,
49
+ bitmap_updater,
69
50
}
70
51
}
71
52
@@ -88,8 +69,8 @@ impl UpdateEncoder {
88
69
xor_bpp : 32 ,
89
70
color_pointer,
90
71
} ;
91
- let len = self . encode_pdu ( ptr) ?;
92
- Ok ( UpdateFragmenter :: new ( UpdateCode :: NewPointer , & self . buffer [ ..len ] ) )
72
+ let buf = self . pdu_encoder . encode ( ptr) ?;
73
+ Ok ( UpdateFragmenter :: new ( UpdateCode :: NewPointer , buf ) )
93
74
}
94
75
95
76
pub ( crate ) fn color_pointer ( & mut self , ptr : ColorPointer ) -> Result < UpdateFragmenter < ' _ > > {
@@ -105,8 +86,8 @@ impl UpdateEncoder {
105
86
xor_mask : & ptr. xor_mask ,
106
87
and_mask : & ptr. and_mask ,
107
88
} ;
108
- let len = self . encode_pdu ( ptr) ?;
109
- Ok ( UpdateFragmenter :: new ( UpdateCode :: ColorPointer , & self . buffer [ ..len ] ) )
89
+ let buf = self . pdu_encoder . encode ( ptr) ?;
90
+ Ok ( UpdateFragmenter :: new ( UpdateCode :: ColorPointer , buf ) )
110
91
}
111
92
112
93
#[ allow( clippy:: unused_self) ]
@@ -120,31 +101,93 @@ impl UpdateEncoder {
120
101
}
121
102
122
103
pub ( crate ) fn pointer_position ( & mut self , pos : PointerPositionAttribute ) -> Result < UpdateFragmenter < ' _ > > {
123
- let len = self . encode_pdu ( pos) ?;
124
- Ok ( UpdateFragmenter :: new ( UpdateCode :: PositionPointer , & self . buffer [ ..len ] ) )
104
+ let buf = self . pdu_encoder . encode ( pos) ?;
105
+ Ok ( UpdateFragmenter :: new ( UpdateCode :: PositionPointer , buf ) )
125
106
}
126
107
127
108
pub ( crate ) fn bitmap ( & mut self , bitmap : BitmapUpdate ) -> Result < UpdateFragmenter < ' _ > > {
128
- let update = self . update ;
129
-
130
- update ( self , bitmap)
109
+ self . bitmap_updater . handle ( bitmap, & mut self . pdu_encoder )
131
110
}
132
111
133
112
pub ( crate ) fn fragmenter_from_owned ( & self , res : UpdateFragmenterOwned ) -> UpdateFragmenter < ' _ > {
134
113
UpdateFragmenter {
135
114
code : res. code ,
136
115
index : res. index ,
137
- data : & self . buffer [ 0 ..res. len ] ,
116
+ data : & self . pdu_encoder . buffer [ 0 ..res. len ] ,
117
+ }
118
+ }
119
+ }
120
+
121
+ enum BitmapUpdater {
122
+ None ( NoneHandler ) ,
123
+ Bitmap ( BitmapHandler ) ,
124
+ RemoteFx ( RemoteFxHandler ) ,
125
+ }
126
+
127
+ impl BitmapUpdater {
128
+ fn handle < ' a > ( & mut self , bitmap : BitmapUpdate , encoder : & ' a mut PduEncoder ) -> Result < UpdateFragmenter < ' a > > {
129
+ match self {
130
+ Self :: None ( up) => up. handle ( bitmap, encoder) ,
131
+ Self :: Bitmap ( up) => up. handle ( bitmap, encoder) ,
132
+ Self :: RemoteFx ( up) => up. handle ( bitmap, encoder) ,
133
+ }
134
+ }
135
+ }
136
+
137
+ trait BitmapUpdateHandler {
138
+ fn handle < ' a > ( & mut self , bitmap : BitmapUpdate , encoder : & ' a mut PduEncoder ) -> Result < UpdateFragmenter < ' a > > ;
139
+ }
140
+
141
+ struct NoneHandler ;
142
+
143
+ impl BitmapUpdateHandler for NoneHandler {
144
+ fn handle < ' a > ( & mut self , mut bitmap : BitmapUpdate , encoder : & ' a mut PduEncoder ) -> Result < UpdateFragmenter < ' a > > {
145
+ let stride = usize:: from ( bitmap. format . bytes_per_pixel ( ) ) * usize:: from ( bitmap. width . get ( ) ) ;
146
+ let data = match bitmap. order {
147
+ PixelOrder :: BottomToTop => {
148
+ if stride == bitmap. stride {
149
+ mem:: take ( & mut bitmap. data )
150
+ } else {
151
+ let mut data = Vec :: with_capacity ( stride * usize:: from ( bitmap. height . get ( ) ) ) ;
152
+ for row in bitmap. data . chunks ( bitmap. stride ) {
153
+ data. extend_from_slice ( & row[ ..stride] ) ;
154
+ }
155
+ data
156
+ }
157
+ }
158
+ PixelOrder :: TopToBottom => {
159
+ let mut data = Vec :: with_capacity ( stride * usize:: from ( bitmap. height . get ( ) ) ) ;
160
+ for row in bitmap. data . chunks ( bitmap. stride ) . rev ( ) {
161
+ data. extend_from_slice ( & row[ ..stride] ) ;
162
+ }
163
+ data
164
+ }
165
+ } ;
166
+
167
+ encoder. set_surface ( bitmap, CodecId :: None as u8 , data)
168
+ }
169
+ }
170
+
171
+ struct BitmapHandler {
172
+ bitmap : BitmapEncoder ,
173
+ }
174
+
175
+ impl BitmapHandler {
176
+ fn new ( ) -> Self {
177
+ Self {
178
+ bitmap : BitmapEncoder :: new ( ) ,
138
179
}
139
180
}
181
+ }
140
182
141
- fn bitmap_update ( & mut self , bitmap : BitmapUpdate ) -> Result < UpdateFragmenter < ' _ > > {
183
+ impl BitmapUpdateHandler for BitmapHandler {
184
+ fn handle < ' a > ( & mut self , bitmap : BitmapUpdate , encoder : & ' a mut PduEncoder ) -> Result < UpdateFragmenter < ' a > > {
142
185
let len = loop {
143
- match self . bitmap . encode ( & bitmap, self . buffer . as_mut_slice ( ) ) {
186
+ match self . bitmap . encode ( & bitmap, encoder . buffer . as_mut_slice ( ) ) {
144
187
Err ( e) => match e. kind ( ) {
145
188
ironrdp_core:: EncodeErrorKind :: NotEnoughBytes { .. } => {
146
- self . buffer . resize ( self . buffer . len ( ) * 2 , 0 ) ;
147
- debug ! ( "encoder buffer resized to: {}" , self . buffer. len( ) * 2 ) ;
189
+ encoder . buffer . resize ( encoder . buffer . len ( ) * 2 , 0 ) ;
190
+ debug ! ( "encoder buffer resized to: {}" , encoder . buffer. len( ) * 2 ) ;
148
191
}
149
192
150
193
_ => Err ( e) . context ( "bitmap encode error" ) ?,
@@ -153,7 +196,58 @@ impl UpdateEncoder {
153
196
}
154
197
} ;
155
198
156
- Ok ( UpdateFragmenter :: new ( UpdateCode :: Bitmap , & self . buffer [ ..len] ) )
199
+ Ok ( UpdateFragmenter :: new ( UpdateCode :: Bitmap , & encoder. buffer [ ..len] ) )
200
+ }
201
+ }
202
+
203
+ struct RemoteFxHandler {
204
+ remotefx : RfxEncoder ,
205
+ codec_id : u8 ,
206
+ }
207
+
208
+ impl RemoteFxHandler {
209
+ fn new ( algo : EntropyBits , codec_id : u8 ) -> Self {
210
+ Self {
211
+ remotefx : RfxEncoder :: new ( algo) ,
212
+ codec_id,
213
+ }
214
+ }
215
+ }
216
+
217
+ impl BitmapUpdateHandler for RemoteFxHandler {
218
+ fn handle < ' a > ( & mut self , bitmap : BitmapUpdate , encoder : & ' a mut PduEncoder ) -> Result < UpdateFragmenter < ' a > > {
219
+ let data = self . remotefx . encode ( & bitmap) . context ( "RemoteFX encoding" ) ?;
220
+
221
+ encoder. set_surface ( bitmap, self . codec_id , data)
222
+ }
223
+ }
224
+
225
+ struct PduEncoder {
226
+ buffer : Vec < u8 > ,
227
+ }
228
+
229
+ impl PduEncoder {
230
+ fn new ( ) -> Self {
231
+ Self { buffer : vec ! [ 0 ; 16384 ] }
232
+ }
233
+
234
+ fn encode ( & mut self , pdu : impl Encode ) -> Result < & [ u8 ] > {
235
+ let pos = loop {
236
+ let mut cursor = WriteCursor :: new ( self . buffer . as_mut_slice ( ) ) ;
237
+ match pdu. encode ( & mut cursor) {
238
+ Err ( e) => match e. kind ( ) {
239
+ ironrdp_core:: EncodeErrorKind :: NotEnoughBytes { .. } => {
240
+ self . buffer . resize ( self . buffer . len ( ) * 2 , 0 ) ;
241
+ debug ! ( "encoder buffer resized to: {}" , self . buffer. len( ) * 2 ) ;
242
+ }
243
+
244
+ _ => Err ( e) . context ( "PDU encode error" ) ?,
245
+ } ,
246
+ Ok ( ( ) ) => break cursor. pos ( ) ,
247
+ }
248
+ } ;
249
+
250
+ Ok ( & self . buffer [ ..pos] )
157
251
}
158
252
159
253
fn set_surface ( & mut self , bitmap : BitmapUpdate , codec_id : u8 , data : Vec < u8 > ) -> Result < UpdateFragmenter < ' _ > > {
@@ -176,42 +270,8 @@ impl UpdateEncoder {
176
270
extended_bitmap_data,
177
271
} ;
178
272
let cmd = SurfaceCommand :: SetSurfaceBits ( pdu) ;
179
- let len = self . encode_pdu ( cmd) ?;
180
- Ok ( UpdateFragmenter :: new ( UpdateCode :: SurfaceCommands , & self . buffer [ ..len] ) )
181
- }
182
-
183
- fn remotefx_update ( & mut self , bitmap : BitmapUpdate ) -> Result < UpdateFragmenter < ' _ > > {
184
- let ( remotefx, codec_id) = self . remotefx . as_mut ( ) . unwrap ( ) ;
185
- let codec_id = * codec_id;
186
- let data = remotefx. encode ( & bitmap) . context ( "RemoteFX encoding" ) ?;
187
-
188
- self . set_surface ( bitmap, codec_id, data)
189
- }
190
-
191
- fn none_update ( & mut self , mut bitmap : BitmapUpdate ) -> Result < UpdateFragmenter < ' _ > > {
192
- let stride = usize:: from ( bitmap. format . bytes_per_pixel ( ) ) * usize:: from ( bitmap. width . get ( ) ) ;
193
- let data = match bitmap. order {
194
- PixelOrder :: BottomToTop => {
195
- if stride == bitmap. stride {
196
- mem:: take ( & mut bitmap. data )
197
- } else {
198
- let mut data = Vec :: with_capacity ( stride * usize:: from ( bitmap. height . get ( ) ) ) ;
199
- for row in bitmap. data . chunks ( bitmap. stride ) {
200
- data. extend_from_slice ( & row[ ..stride] ) ;
201
- }
202
- data
203
- }
204
- }
205
- PixelOrder :: TopToBottom => {
206
- let mut data = Vec :: with_capacity ( stride * usize:: from ( bitmap. height . get ( ) ) ) ;
207
- for row in bitmap. data . chunks ( bitmap. stride ) . rev ( ) {
208
- data. extend_from_slice ( & row[ ..stride] ) ;
209
- }
210
- data
211
- }
212
- } ;
213
-
214
- self . set_surface ( bitmap, CodecId :: None as u8 , data)
273
+ let buf = self . encode ( cmd) ?;
274
+ Ok ( UpdateFragmenter :: new ( UpdateCode :: SurfaceCommands , buf) )
215
275
}
216
276
}
217
277
0 commit comments