@@ -141,79 +141,36 @@ unsafe fn tsk_column_access<
141141 tsk_column_access_detail ( row, column, column_length) . map ( |v| v. into ( ) )
142142}
143143
144- /// # SAFETY
145- ///
146- /// The safety requirements here are a bit fiddly.
147- ///
148- /// The hard case is when the columns contain data:
149- ///
150- /// * column and offset must both not be NULL
151- /// * column_length and offset_length must both be
152- /// the correct lengths for the input pointers
153- /// * we return None if row < 0 or row > array length.
154- /// * Thus, the requirement is that the two _lengths
155- /// == 0 or (pointer both not NULL and the lengths are correct)
156- ///
157- /// When the lengths of each column are 0, we
158- /// don't worry about anything else
159- unsafe fn tsk_ragged_column_access_detail <
160- R : Into < bindings:: tsk_id_t > ,
161- L : Into < bindings:: tsk_size_t > ,
162- T : Copy ,
163- > (
164- row : R ,
165- column : * const T ,
166- column_length : L ,
167- offset : * const bindings:: tsk_size_t ,
168- offset_length : bindings:: tsk_size_t ,
169- ) -> Option < ( * const T , usize ) > {
170- let row = row. into ( ) ;
171- let column_length = column_length. into ( ) ;
172- if row < 0 || row as bindings:: tsk_size_t > column_length || offset_length == 0 {
144+ fn tsk_ragged_column_access_detail < ' a , T > (
145+ row : usize ,
146+ column : & ' a [ T ] ,
147+ raw_offset : & ' a [ bindings:: tsk_size_t ] ,
148+ ) -> Option < & ' a [ T ] > {
149+ if row >= raw_offset. len ( ) || raw_offset. is_empty ( ) {
173150 None
174151 } else {
175- // SAFETY: pointers are not null
176- // and *_length are given by tskit-c
177- let index = row as isize ;
178- let start = * offset. offset ( index) ;
179- let stop = if ( row as bindings:: tsk_size_t ) < column_length {
180- * offset. offset ( index + 1 )
152+ let start = usize:: try_from ( raw_offset[ row] ) . ok ( ) ?;
153+ let stop = if row < raw_offset. len ( ) - 1 {
154+ usize:: try_from ( raw_offset[ row + 1 ] ) . ok ( ) ?
181155 } else {
182- offset_length
156+ column . len ( )
183157 } ;
184158 if start == stop {
185159 None
186160 } else {
187- Some ( (
188- column. offset ( start as isize ) ,
189- stop as usize - start as usize ,
190- ) )
161+ Some ( & column[ start..stop] )
191162 }
192163 }
193164}
194165
195- // SAFETY: see tsk_ragged_column_access_detail
196- // We further erquire that a pointer to a T can
197- // be safely cast to a pointer to an O.
198- unsafe fn tsk_ragged_column_access <
199- ' a ,
200- O ,
201- R : Into < bindings:: tsk_id_t > ,
202- L : Into < bindings:: tsk_size_t > ,
203- T : Copy ,
204- > (
166+ fn tsk_ragged_column_access < ' a , O , R : Into < bindings:: tsk_id_t > > (
205167 row : R ,
206- column : * const T ,
207- column_length : L ,
208- offset : * const bindings:: tsk_size_t ,
209- offset_length : bindings:: tsk_size_t ,
168+ column : & ' a [ O ] ,
169+ raw_offset : & ' a [ bindings:: tsk_size_t ] ,
210170) -> Option < & ' a [ O ] > {
211- unsafe {
212- tsk_ragged_column_access_detail ( row, column, column_length, offset, offset_length)
213- // If the safety requirements of tsk_ragged_column_access_detail are upheld,
214- // then we have received a valid pointer + length from which to make a slice
215- . map ( |( p, n) | std:: slice:: from_raw_parts ( p. cast :: < O > ( ) , n) )
216- }
171+ let row = row. into ( ) ;
172+ let row = usize:: try_from ( row) . ok ( ) ?;
173+ tsk_ragged_column_access_detail ( row, column, raw_offset)
217174}
218175
219176/// # SAFETY
0 commit comments