@@ -89,15 +89,16 @@ pub fn validate_sysex_group_statuses<
8989 Ok ( ( ) )
9090}
9191
92- pub fn try_set_sysex_data <
92+ pub fn try_insert_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 > ,
9696> (
9797 sysex : & mut S ,
9898 data : D ,
99+ before : usize ,
99100) -> 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 ) {
101102 Err ( e) => {
102103 // if the write failed we reset the message
103104 // back to zero data
@@ -110,25 +111,33 @@ pub fn try_set_sysex_data<
110111 }
111112}
112113
113- pub fn set_sysex_data <
114+ pub fn insert_sysex_data <
114115 B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut + crate :: buffer:: BufferResize ,
115116 S : SysexInternal < B > ,
116117 D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
117118> (
118119 sysex : & mut S ,
119120 data : D ,
121+ before : usize ,
120122) {
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+ )
125132 . expect ( "Resizable buffers should not fail here" )
126133}
127134
128135mod detail {
136+ use crate :: error:: BufferOverflow ;
137+
129138 use super :: * ;
130139
131- pub fn try_set_sysex_data <
140+ pub fn try_insert_sysex_data <
132141 B : crate :: buffer:: Buffer + crate :: buffer:: BufferMut ,
133142 S : crate :: traits:: SysexInternal < B > ,
134143 D : core:: iter:: Iterator < Item = <S as crate :: traits:: Sysex < B > >:: Byte > ,
@@ -137,8 +146,14 @@ mod detail {
137146 sysex : & mut S ,
138147 data : D ,
139148 resize : R ,
149+ before : usize ,
140150 ) -> core:: result:: Result < ( ) , crate :: error:: BufferOverflow > {
151+ // reformat first to ensure data is optimally filling the
152+ // underlying buffer
153+ sysex. compact ( ) ;
154+
141155 // get an initial estimate for the size of the data
156+ let initial_size = sysex. payload_size ( ) ;
142157 let mut running_data_size_estimate = match data. size_hint ( ) {
143158 ( _, Some ( upper) ) => upper,
144159 // not the optimal case - could lead to additional copying
@@ -149,45 +164,62 @@ mod detail {
149164 let mut data = data. peekable ( ) ;
150165
151166 // 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+ {
153170 // 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 ) ;
155172 } ;
156173
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+
157182 ' main: loop {
158183 while written < running_data_size_estimate {
159184 match data. next ( ) {
160185 Some ( v) => {
161- sysex. write_datum ( v, written) ;
186+ sysex. write_datum ( v, before + written) ;
162187 written += 1 ;
163188 }
164189 None => {
165190 break ' main;
166191 }
167192 }
168193 }
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+ }
170200
171201 // we underestimated.
172202 // resize to make more space
173203 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;
174212 additional_size_for_overflow *= 2 ;
175213
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-
183214 if written >= running_data_size_estimate {
184- return Err ( Default :: default ( ) ) ;
215+ return Err ( BufferOverflow ) ;
185216 }
186217 }
187218
188219 if written < running_data_size_estimate {
189220 // 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 ) ?;
191223 }
192224
193225 Ok ( ( ) )
0 commit comments