@@ -89,16 +89,17 @@ pub fn validate_sysex_group_statuses<
89
89
Ok ( ( ) )
90
90
}
91
91
92
- pub fn try_insert_sysex_data <
92
+ pub fn try_splice_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
+ R : core:: ops:: RangeBounds < usize > ,
96
97
> (
97
98
sysex : & mut S ,
98
99
data : D ,
99
- before : usize ,
100
+ range : R ,
100
101
) -> core:: result:: Result < ( ) , crate :: error:: BufferOverflow > {
101
- match detail:: try_insert_sysex_data ( sysex, data, |s, sz| s. try_resize ( sz) , before ) {
102
+ match detail:: try_splice_sysex_data ( sysex, data, |s, sz| s. try_resize ( sz) , range ) {
102
103
Err ( e) => {
103
104
// if the write failed we reset the message
104
105
// back to zero data
@@ -111,23 +112,24 @@ pub fn try_insert_sysex_data<
111
112
}
112
113
}
113
114
114
- pub fn insert_sysex_data <
115
+ pub fn splice_sysex_data <
115
116
B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut + crate :: buffer:: BufferResize ,
116
117
S : SysexInternal < B > ,
117
118
D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
119
+ R : core:: ops:: RangeBounds < usize > ,
118
120
> (
119
121
sysex : & mut S ,
120
122
data : D ,
121
- before : usize ,
123
+ range : R ,
122
124
) {
123
- detail:: try_insert_sysex_data (
125
+ detail:: try_splice_sysex_data (
124
126
sysex,
125
127
data,
126
128
|s, sz| {
127
129
s. resize ( sz) ;
128
130
Ok ( ( ) )
129
131
} ,
130
- before ,
132
+ range ,
131
133
)
132
134
. expect ( "Resizable buffers should not fail here" )
133
135
}
@@ -137,23 +139,37 @@ mod detail {
137
139
138
140
use super :: * ;
139
141
140
- pub fn try_insert_sysex_data <
142
+ pub fn try_splice_sysex_data <
141
143
B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut ,
142
144
S : crate :: traits:: SysexInternal < B > ,
143
145
D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
144
146
R : Fn ( & mut S , usize ) -> core:: result:: Result < ( ) , SysexTryResizeError > ,
147
+ Rg : core:: ops:: RangeBounds < usize > ,
145
148
> (
146
149
sysex : & mut S ,
147
150
data : D ,
148
151
resize : R ,
149
- before : usize ,
152
+ range : Rg ,
150
153
) -> core:: result:: Result < ( ) , crate :: error:: BufferOverflow > {
151
154
// reformat first to ensure data is optimally filling the
152
155
// underlying buffer
153
156
sysex. compact ( ) ;
154
157
155
158
// get an initial estimate for the size of the data
156
159
let initial_size = sysex. payload_size ( ) ;
160
+
161
+ let splice_begin = match range. start_bound ( ) {
162
+ core:: ops:: Bound :: Included ( & v) => v,
163
+ core:: ops:: Bound :: Excluded ( & v) => v + 1 ,
164
+ core:: ops:: Bound :: Unbounded => 0 ,
165
+ } ;
166
+ let splice_end = match range. end_bound ( ) {
167
+ core:: ops:: Bound :: Included ( & v) => v + 1 ,
168
+ core:: ops:: Bound :: Excluded ( & v) => v,
169
+ core:: ops:: Bound :: Unbounded => initial_size,
170
+ } ;
171
+ let splice_size = splice_end - splice_begin;
172
+
157
173
let mut running_data_size_estimate = match data. size_hint ( ) {
158
174
( _, Some ( upper) ) => upper,
159
175
// not the optimal case - could lead to additional copying
@@ -163,27 +179,26 @@ mod detail {
163
179
let mut additional_size_for_overflow = 1 ;
164
180
let mut data = data. peekable ( ) ;
165
181
166
- // initial buffer resize
167
- if let Err ( SysexTryResizeError ( sz) ) =
168
- resize ( sysex, running_data_size_estimate + initial_size)
169
- {
170
- // failed. we'll work with what we've got
171
- running_data_size_estimate = sz. saturating_sub ( initial_size) ;
172
- } ;
173
-
174
- debug_assert_eq ! (
175
- sysex. payload_size( ) ,
176
- running_data_size_estimate + initial_size
177
- ) ;
182
+ if splice_end < splice_end + running_data_size_estimate - splice_size {
183
+ // we need to grow
184
+ // initial buffer resize
185
+ if let Err ( SysexTryResizeError ( sz) ) = resize (
186
+ sysex,
187
+ running_data_size_estimate + initial_size - splice_size,
188
+ ) {
189
+ // failed. we'll work with what we've got
190
+ running_data_size_estimate = sz. saturating_sub ( initial_size - splice_size) ;
191
+ } ;
192
+ }
178
193
179
- let mut tail = before + running_data_size_estimate;
180
- sysex. move_payload_tail ( before , tail) ;
194
+ let mut tail = splice_end + running_data_size_estimate - splice_size ;
195
+ sysex. move_payload_tail ( splice_end , tail) ;
181
196
182
197
' main: loop {
183
198
while written < running_data_size_estimate {
184
199
match data. next ( ) {
185
200
Some ( v) => {
186
- sysex. write_datum ( v, before + written) ;
201
+ sysex. write_datum ( v, splice_begin + written) ;
187
202
written += 1 ;
188
203
}
189
204
None => {
@@ -199,28 +214,41 @@ mod detail {
199
214
}
200
215
201
216
// we underestimated.
202
- // resize to make more space
203
217
running_data_size_estimate += additional_size_for_overflow;
204
- if let Err ( SysexTryResizeError ( sz) ) =
205
- resize ( sysex, running_data_size_estimate + initial_size)
218
+
206
219
{
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;
220
+ let mut to = splice_begin + running_data_size_estimate;
221
+ if tail < to {
222
+ // we need to grow
223
+ // resize to make more space
224
+ // and move tail
225
+
226
+ if let Err ( SysexTryResizeError ( sz) ) = resize (
227
+ sysex,
228
+ running_data_size_estimate + initial_size - splice_size,
229
+ ) {
230
+ // failed. we'll work with what we've got
231
+ running_data_size_estimate = sz. saturating_sub ( initial_size - splice_size) ;
232
+ to = splice_begin + running_data_size_estimate - splice_size;
233
+ } ;
234
+ }
235
+
236
+ sysex. move_payload_tail ( tail, to) ;
237
+ tail = splice_begin + running_data_size_estimate;
238
+ }
239
+
212
240
additional_size_for_overflow *= 2 ;
213
241
214
242
if written >= running_data_size_estimate {
215
243
return Err ( BufferOverflow ) ;
216
244
}
217
245
}
218
246
219
- if written < running_data_size_estimate {
220
- // we shrink the buffer back down to the correct size
221
- sysex. move_payload_tail ( tail, before + written) ;
222
- resize ( sysex, written + initial_size) . map_err ( |_| crate :: error :: BufferOverflow ) ? ;
223
- }
247
+ // we ensure the buffer is the correct size and move the tail
248
+ // to the final position
249
+ sysex. move_payload_tail ( tail, splice_begin + written) ;
250
+ resize ( sysex, written + initial_size - splice_size )
251
+ . map_err ( |_| crate :: error :: BufferOverflow ) ? ;
224
252
225
253
Ok ( ( ) )
226
254
}
0 commit comments