@@ -11,17 +11,17 @@ use std::{
1111 marker:: PhantomData ,
1212} ;
1313
14- /// The multichannel contigious reader will read from an contigous block.
14+ /// The multichannel contiguous reader will read from a contiguous block.
1515///
1616/// We will assume a single datatype as it is unclear if multiple types exist in the wild.
17- pub struct MultiChannelContigousReader < R : Read + Seek , T : TdmsReader < R > > {
17+ pub struct MultiChannelContiguousReader < R : Read + Seek , T : TdmsReader < R > > {
1818 reader : T ,
1919 _marker : PhantomData < R > ,
2020 block_size : NonZeroU64 ,
2121 block_start : u64 ,
2222}
2323
24- impl < R : Read + Seek , T : TdmsReader < R > > MultiChannelContigousReader < R , T > {
24+ impl < R : Read + Seek , T : TdmsReader < R > > MultiChannelContiguousReader < R , T > {
2525 pub fn new ( reader : T , block_start : u64 , block_size : NonZeroU64 ) -> Self {
2626 Self {
2727 reader,
@@ -75,10 +75,28 @@ impl<R: Read + Seek, T: TdmsReader<R>> MultiChannelContigousReader<R, T> {
7575 self . reader . move_position ( skip_bytes) ?;
7676 } else if sub_block_idx == sub_blocks_to_skip {
7777 // First sub-block to read - apply remainder skip
78- length += self . read_sub_block_with_offset ( & mut channels, remainder_skip) ?;
78+ for channel in channels. read_instructions ( ) {
79+ if let RecordEntryPlan :: Read {
80+ block_skip : skip_first_samples,
81+ ..
82+ } = & mut channel. plan
83+ {
84+ * skip_first_samples = remainder_skip;
85+ }
86+ }
87+ length += self . read_sub_block ( & mut channels) ?;
7988 } else {
89+ for channel in channels. read_instructions ( ) {
90+ if let RecordEntryPlan :: Read {
91+ block_skip : skip_first_samples,
92+ ..
93+ } = & mut channel. plan
94+ {
95+ * skip_first_samples = 0 ;
96+ }
97+ }
8098 // Subsequent sub-blocks - no skip
81- length += self . read_sub_block_with_offset ( & mut channels, 0 ) ?;
99+ length += self . read_sub_block ( & mut channels) ?;
82100 }
83101 }
84102
@@ -109,7 +127,6 @@ impl<R: Read + Seek, T: TdmsReader<R>> MultiChannelContigousReader<R, T> {
109127 . collect ( ) ;
110128
111129 let mut length = 0 ;
112- let mut sub_block_skips = Vec :: with_capacity ( skip_amounts. len ( ) ) ;
113130
114131 for sub_block_idx in 0 ..total_sub_blocks {
115132 // Check if any channel needs to read from this sub-block
@@ -121,40 +138,69 @@ impl<R: Read + Seek, T: TdmsReader<R>> MultiChannelContigousReader<R, T> {
121138 self . reader . move_position ( skip_bytes) ?;
122139 } else {
123140 // Build skip amounts for this sub-block
124- sub_block_skips. clear ( ) ;
125- for ( idx, & blocks_to_skip) in sub_blocks_to_skip. iter ( ) . enumerate ( ) {
126- if sub_block_idx == blocks_to_skip {
127- // First sub-block to read for this channel - use remainder
128- sub_block_skips. push ( remainder_skips[ idx] ) ;
129- } else if sub_block_idx > blocks_to_skip {
130- // Subsequent sub-blocks - no skip
131- sub_block_skips. push ( 0 ) ;
132- } else {
133- // Should not happen if any_channel_reads is correct
134- sub_block_skips. push ( 0 ) ;
135- }
141+ let channel_skip_values =
142+ channels
143+ . read_instructions ( )
144+ . iter_mut ( )
145+ . filter_map ( |instruction| {
146+ if let RecordEntryPlan :: Read {
147+ block_skip : skip_first_samples,
148+ ..
149+ } = & mut instruction. plan
150+ {
151+ Some ( skip_first_samples)
152+ } else {
153+ None
154+ }
155+ } ) ;
156+ for ( ( blocks_to_skip, remainder_skip) , sub_block_skip) in sub_blocks_to_skip
157+ . iter ( )
158+ . zip ( remainder_skips. iter ( ) )
159+ . zip ( channel_skip_values)
160+ {
161+ * sub_block_skip = Self :: calculate_skip_for_this_block (
162+ sub_block_idx,
163+ * blocks_to_skip,
164+ * remainder_skip,
165+ ) ;
136166 }
137- length +=
138- self . read_sub_block_with_per_channel_skip ( & mut channels, & sub_block_skips) ?;
167+ length += self . read_sub_block ( & mut channels) ?;
139168 }
140169 }
141170
142171 Ok ( length)
143172 }
144173
145- fn read_sub_block_with_per_channel_skip < D : TdmsStorageType > (
174+ fn calculate_skip_for_this_block (
175+ sub_block_idx : u64 ,
176+ blocks_to_skip : u64 ,
177+ remainder_skip : u64 ,
178+ ) -> u64 {
179+ if sub_block_idx == blocks_to_skip {
180+ // First sub-block to read for this channel - use remainder
181+ remainder_skip
182+ } else if sub_block_idx > blocks_to_skip {
183+ // Subsequent sub-blocks - no skip
184+ 0
185+ } else {
186+ // Should not happen if any_channel_reads is correct
187+ 0
188+ }
189+ }
190+
191+ fn read_sub_block < D : TdmsStorageType > (
146192 & mut self ,
147193 channels : & mut RecordPlan < ' _ , D > ,
148- skip_amounts : & [ u64 ] ,
149194 ) -> Result < usize , TdmsError > {
150195 let mut length = 0 ;
151- let mut skip_idx = 0 ;
152196
153197 for read_instruction in channels. read_instructions ( ) . iter_mut ( ) {
154198 match & mut read_instruction. plan {
155- RecordEntryPlan :: Read ( output) => {
156- let skip = skip_amounts[ skip_idx] . min ( read_instruction. length as u64 ) as usize ;
157- skip_idx += 1 ;
199+ RecordEntryPlan :: Read {
200+ output,
201+ block_skip : skip_first_samples,
202+ } => {
203+ let skip = ( * skip_first_samples) . min ( read_instruction. length as u64 ) as usize ;
158204
159205 let samples_to_read = read_instruction. length . saturating_sub ( skip) ;
160206
@@ -165,12 +211,7 @@ impl<R: Read + Seek, T: TdmsReader<R>> MultiChannelContigousReader<R, T> {
165211 }
166212
167213 // Read the remaining samples
168- for _ in 0 ..samples_to_read {
169- let read_value = self . reader . read_value ( ) ?;
170- if let Some ( value) = output. next ( ) {
171- * value = read_value;
172- }
173- }
214+ self . read_sequential_samples ( output, samples_to_read) ?;
174215 length = samples_to_read;
175216 }
176217 RecordEntryPlan :: Skip ( bytes) => {
@@ -183,42 +224,18 @@ impl<R: Read + Seek, T: TdmsReader<R>> MultiChannelContigousReader<R, T> {
183224 Ok ( length)
184225 }
185226
186- fn read_sub_block_with_offset < D : TdmsStorageType > (
227+ fn read_sequential_samples < ' a , D : TdmsStorageType , I : Iterator < Item = & ' a mut D > > (
187228 & mut self ,
188- channels : & mut RecordPlan < ' _ , D > ,
189- start_sample : u64 ,
190- ) -> Result < usize , TdmsError > {
191- let mut length = 0 ;
192- for read_instruction in channels. read_instructions ( ) . iter_mut ( ) {
193- match & mut read_instruction. plan {
194- RecordEntryPlan :: Read ( output) => {
195- // Skip the specified number of samples at the start
196- let samples_to_skip = start_sample. min ( read_instruction. length as u64 ) as usize ;
197- let samples_to_read = read_instruction. length . saturating_sub ( samples_to_skip) ;
198-
199- // Skip samples by seeking
200- if samples_to_skip > 0 {
201- let skip_bytes = samples_to_skip as i64 * D :: SIZE_BYTES as i64 ;
202- self . reader . move_position ( skip_bytes) ?;
203- }
204-
205- // Read the remaining samples
206- for _ in 0 ..samples_to_read {
207- let read_value = self . reader . read_value ( ) ?;
208- if let Some ( value) = output. next ( ) {
209- * value = read_value;
210- }
211- }
212- length = samples_to_read;
213- }
214- RecordEntryPlan :: Skip ( bytes) => {
215- let skip_bytes = * bytes * read_instruction. length as i64 ;
216- self . reader . move_position ( skip_bytes) ?;
217- }
218- } ;
229+ output : & mut I ,
230+ samples_to_read : usize ,
231+ ) -> Result < ( ) , TdmsError > {
232+ for _ in 0 ..samples_to_read {
233+ let read_value = self . reader . read_value ( ) ?;
234+ if let Some ( value) = output. next ( ) {
235+ * value = read_value;
236+ }
219237 }
220-
221- Ok ( length)
238+ Ok ( ( ) )
222239 }
223240}
224241
@@ -259,7 +276,7 @@ mod tests {
259276 let mut buffer = create_test_buffer ( ) ;
260277 let meta = create_test_meta_data ( 2 ) ;
261278
262- let mut reader = MultiChannelContigousReader :: < _ , _ > :: new (
279+ let mut reader = MultiChannelContiguousReader :: < _ , _ > :: new (
263280 BigEndianReader :: from_reader ( & mut buffer) ,
264281 0 ,
265282 800 . try_into ( ) . unwrap ( ) ,
@@ -277,7 +294,7 @@ mod tests {
277294 let meta = create_test_meta_data ( 4 ) ;
278295 let length = meta. first ( ) . unwrap ( ) . number_of_values as f64 ;
279296
280- let mut reader = MultiChannelContigousReader :: < _ , _ > :: new (
297+ let mut reader = MultiChannelContiguousReader :: < _ , _ > :: new (
281298 BigEndianReader :: from_reader ( & mut buffer) ,
282299 0 ,
283300 800 . try_into ( ) . unwrap ( ) ,
@@ -312,7 +329,7 @@ mod tests {
312329 // ch3: 4, 5, 12, 13
313330 // ch4: 6, 7, 14, 15
314331
315- let mut reader = MultiChannelContigousReader :: < _ , _ > :: new (
332+ let mut reader = MultiChannelContiguousReader :: < _ , _ > :: new (
316333 BigEndianReader :: from_reader ( & mut buffer) ,
317334 0 ,
318335 800 . try_into ( ) . unwrap ( ) ,
@@ -333,7 +350,7 @@ mod tests {
333350 let meta = create_test_meta_data ( 4 ) ;
334351 let length = meta. first ( ) . unwrap ( ) . number_of_values as f64 ;
335352
336- let mut reader = MultiChannelContigousReader :: < _ , _ > :: new (
353+ let mut reader = MultiChannelContiguousReader :: < _ , _ > :: new (
337354 BigEndianReader :: from_reader ( & mut buffer) ,
338355 0 ,
339356 800 . try_into ( ) . unwrap ( ) ,
@@ -356,7 +373,7 @@ mod tests {
356373 let meta = create_test_meta_data ( 4 ) ;
357374 let length = meta. first ( ) . unwrap ( ) . number_of_values as f64 ;
358375
359- let mut reader = MultiChannelContigousReader :: < _ , _ > :: new (
376+ let mut reader = MultiChannelContiguousReader :: < _ , _ > :: new (
360377 BigEndianReader :: from_reader ( & mut buffer) ,
361378 0 ,
362379 800 . try_into ( ) . unwrap ( ) ,
@@ -391,7 +408,7 @@ mod tests {
391408 channel. number_of_values = 3 ;
392409 }
393410
394- let mut reader = MultiChannelContigousReader :: < _ , _ > :: new (
411+ let mut reader = MultiChannelContiguousReader :: < _ , _ > :: new (
395412 BigEndianReader :: from_reader ( & mut buffer) ,
396413 0 ,
397414 800 . try_into ( ) . unwrap ( ) ,
0 commit comments