@@ -89,16 +89,17 @@ pub fn validate_sysex_group_statuses<
8989 Ok ( ( ) )
9090}
9191
92- pub fn try_insert_sysex_data <
92+ pub fn try_splice_sysex_data <
9393 B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut + crate :: buffer:: BufferTryResize ,
9494 S : SysexInternal < B > ,
9595 D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
96+ R : core:: ops:: RangeBounds < usize > ,
9697> (
9798 sysex : & mut S ,
9899 data : D ,
99- before : usize ,
100+ range : R ,
100101) -> 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 ) {
102103 Err ( e) => {
103104 // if the write failed we reset the message
104105 // back to zero data
@@ -111,23 +112,24 @@ pub fn try_insert_sysex_data<
111112 }
112113}
113114
114- pub fn insert_sysex_data <
115+ pub fn splice_sysex_data <
115116 B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut + crate :: buffer:: BufferResize ,
116117 S : SysexInternal < B > ,
117118 D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
119+ R : core:: ops:: RangeBounds < usize > ,
118120> (
119121 sysex : & mut S ,
120122 data : D ,
121- before : usize ,
123+ range : R ,
122124) {
123- detail:: try_insert_sysex_data (
125+ detail:: try_splice_sysex_data (
124126 sysex,
125127 data,
126128 |s, sz| {
127129 s. resize ( sz) ;
128130 Ok ( ( ) )
129131 } ,
130- before ,
132+ range ,
131133 )
132134 . expect ( "Resizable buffers should not fail here" )
133135}
@@ -137,23 +139,37 @@ mod detail {
137139
138140 use super :: * ;
139141
140- pub fn try_insert_sysex_data <
142+ pub fn try_splice_sysex_data <
141143 B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut ,
142144 S : crate :: traits:: SysexInternal < B > ,
143145 D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
144146 R : Fn ( & mut S , usize ) -> core:: result:: Result < ( ) , SysexTryResizeError > ,
147+ Rg : core:: ops:: RangeBounds < usize > ,
145148 > (
146149 sysex : & mut S ,
147150 data : D ,
148151 resize : R ,
149- before : usize ,
152+ range : Rg ,
150153 ) -> core:: result:: Result < ( ) , crate :: error:: BufferOverflow > {
151154 // reformat first to ensure data is optimally filling the
152155 // underlying buffer
153156 sysex. compact ( ) ;
154157
155158 // get an initial estimate for the size of the data
156159 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+
157173 let mut running_data_size_estimate = match data. size_hint ( ) {
158174 ( _, Some ( upper) ) => upper,
159175 // not the optimal case - could lead to additional copying
@@ -163,27 +179,26 @@ mod detail {
163179 let mut additional_size_for_overflow = 1 ;
164180 let mut data = data. peekable ( ) ;
165181
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+ }
178193
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) ;
181196
182197 ' main: loop {
183198 while written < running_data_size_estimate {
184199 match data. next ( ) {
185200 Some ( v) => {
186- sysex. write_datum ( v, before + written) ;
201+ sysex. write_datum ( v, splice_begin + written) ;
187202 written += 1 ;
188203 }
189204 None => {
@@ -199,28 +214,41 @@ mod detail {
199214 }
200215
201216 // we underestimated.
202- // resize to make more space
203217 running_data_size_estimate += additional_size_for_overflow;
204- if let Err ( SysexTryResizeError ( sz) ) =
205- resize ( sysex, running_data_size_estimate + initial_size)
218+
206219 {
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+
212240 additional_size_for_overflow *= 2 ;
213241
214242 if written >= running_data_size_estimate {
215243 return Err ( BufferOverflow ) ;
216244 }
217245 }
218246
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 ) ? ;
224252
225253 Ok ( ( ) )
226254 }
0 commit comments