@@ -89,15 +89,16 @@ pub fn validate_sysex_group_statuses<
89
89
Ok ( ( ) )
90
90
}
91
91
92
- pub fn try_set_sysex_data <
92
+ pub fn try_insert_sysex_data <
93
93
B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut + crate :: buffer:: BufferTryResize ,
94
94
S : SysexInternal < B > ,
95
95
D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
96
96
> (
97
97
sysex : & mut S ,
98
98
data : D ,
99
+ before : usize ,
99
100
) -> core:: result:: Result < ( ) , crate :: error:: BufferOverflow > {
100
- match detail:: try_set_sysex_data ( sysex, data, |s, sz| s. try_resize ( sz) ) {
101
+ match detail:: try_insert_sysex_data ( sysex, data, |s, sz| s. try_resize ( sz) , before ) {
101
102
Err ( e) => {
102
103
// if the write failed we reset the message
103
104
// back to zero data
@@ -110,25 +111,33 @@ pub fn try_set_sysex_data<
110
111
}
111
112
}
112
113
113
- pub fn set_sysex_data <
114
+ pub fn insert_sysex_data <
114
115
B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut + crate :: buffer:: BufferResize ,
115
116
S : SysexInternal < B > ,
116
117
D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
117
118
> (
118
119
sysex : & mut S ,
119
120
data : D ,
121
+ before : usize ,
120
122
) {
121
- detail:: try_set_sysex_data ( sysex, data, |s, sz| {
122
- s. resize ( sz) ;
123
- Ok ( ( ) )
124
- } )
123
+ detail:: try_insert_sysex_data (
124
+ sysex,
125
+ data,
126
+ |s, sz| {
127
+ s. resize ( sz) ;
128
+ Ok ( ( ) )
129
+ } ,
130
+ before,
131
+ )
125
132
. expect ( "Resizable buffers should not fail here" )
126
133
}
127
134
128
135
mod detail {
136
+ use crate :: error:: BufferOverflow ;
137
+
129
138
use super :: * ;
130
139
131
- pub fn try_set_sysex_data <
140
+ pub fn try_insert_sysex_data <
132
141
B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut ,
133
142
S : crate :: traits:: SysexInternal < B > ,
134
143
D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
@@ -137,8 +146,14 @@ mod detail {
137
146
sysex : & mut S ,
138
147
data : D ,
139
148
resize : R ,
149
+ before : usize ,
140
150
) -> core:: result:: Result < ( ) , crate :: error:: BufferOverflow > {
151
+ // reformat first to ensure data is optimally filling the
152
+ // underlying buffer
153
+ sysex. compact ( ) ;
154
+
141
155
// get an initial estimate for the size of the data
156
+ let initial_size = sysex. payload_size ( ) ;
142
157
let mut running_data_size_estimate = match data. size_hint ( ) {
143
158
( _, Some ( upper) ) => upper,
144
159
// not the optimal case - could lead to additional copying
@@ -149,45 +164,62 @@ mod detail {
149
164
let mut data = data. peekable ( ) ;
150
165
151
166
// initial buffer resize
152
- if let Err ( SysexTryResizeError ( sz) ) = resize ( sysex, running_data_size_estimate) {
167
+ if let Err ( SysexTryResizeError ( sz) ) =
168
+ resize ( sysex, running_data_size_estimate + initial_size)
169
+ {
153
170
// failed. we'll work with what we've got
154
- running_data_size_estimate = sz;
171
+ running_data_size_estimate = sz. saturating_sub ( initial_size ) ;
155
172
} ;
156
173
174
+ debug_assert_eq ! (
175
+ sysex. payload_size( ) ,
176
+ running_data_size_estimate + initial_size
177
+ ) ;
178
+
179
+ let mut tail = before + running_data_size_estimate;
180
+ sysex. move_payload_tail ( before, tail) ;
181
+
157
182
' main: loop {
158
183
while written < running_data_size_estimate {
159
184
match data. next ( ) {
160
185
Some ( v) => {
161
- sysex. write_datum ( v, written) ;
186
+ sysex. write_datum ( v, before + written) ;
162
187
written += 1 ;
163
188
}
164
189
None => {
165
190
break ' main;
166
191
}
167
192
}
168
193
}
169
- assert_eq ! ( written, running_data_size_estimate) ;
194
+ debug_assert_eq ! ( written, running_data_size_estimate) ;
195
+
196
+ if data. peek ( ) . is_none ( ) {
197
+ // done
198
+ break ;
199
+ }
170
200
171
201
// we underestimated.
172
202
// resize to make more space
173
203
running_data_size_estimate += additional_size_for_overflow;
204
+ if let Err ( SysexTryResizeError ( sz) ) =
205
+ resize ( sysex, running_data_size_estimate + initial_size)
206
+ {
207
+ // failed. we'll work with what we've got
208
+ running_data_size_estimate = sz. saturating_sub ( initial_size) ;
209
+ } ;
210
+ sysex. move_payload_tail ( tail, before + running_data_size_estimate) ;
211
+ tail = before + running_data_size_estimate;
174
212
additional_size_for_overflow *= 2 ;
175
213
176
- if data. peek ( ) . is_some ( ) {
177
- if let Err ( SysexTryResizeError ( sz) ) = resize ( sysex, running_data_size_estimate) {
178
- // failed. we'll work with what we've got
179
- running_data_size_estimate = sz;
180
- } ;
181
- }
182
-
183
214
if written >= running_data_size_estimate {
184
- return Err ( Default :: default ( ) ) ;
215
+ return Err ( BufferOverflow ) ;
185
216
}
186
217
}
187
218
188
219
if written < running_data_size_estimate {
189
220
// we shrink the buffer back down to the correct size
190
- resize ( sysex, written) . map_err ( |_| crate :: error:: BufferOverflow ) ?;
221
+ sysex. move_payload_tail ( tail, before + written) ;
222
+ resize ( sysex, written + initial_size) . map_err ( |_| crate :: error:: BufferOverflow ) ?;
191
223
}
192
224
193
225
Ok ( ( ) )
0 commit comments