@@ -26,7 +26,7 @@ pub enum DType {
2626
2727impl DType {
2828 /// Returns the size of the associated type in bytes.
29- fn size_of ( self ) -> usize {
29+ pub fn size_of ( self ) -> usize {
3030 match self {
3131 Self :: Int32 => std:: mem:: size_of :: < i32 > ( ) ,
3232 Self :: Int64 => std:: mem:: size_of :: < i64 > ( ) ,
@@ -164,16 +164,47 @@ fn validate_shape_selection(
164164 Ok ( ( ) )
165165}
166166
167+ /// Validate raw data size against data type and shape.
168+ ///
169+ /// # Arguments
170+ ///
171+ /// * `raw_size`: Raw (uncompressed) size of the data in bytes.
172+ /// * `dtype`: Data type
173+ /// * `shape`: Optional shape of the multi-dimensional array
174+ pub fn validate_raw_size (
175+ raw_size : usize ,
176+ dtype : DType ,
177+ shape : & Option < Vec < usize > > ,
178+ ) -> Result < ( ) , ValidationError > {
179+ let dtype_size = dtype. size_of ( ) ;
180+ if let Some ( shape) = shape {
181+ let expected_size = shape. iter ( ) . product :: < usize > ( ) * dtype_size;
182+ if raw_size != expected_size {
183+ let mut error =
184+ ValidationError :: new ( "Raw data size must be equal to the product of shape indices and dtype size in bytes" ) ;
185+ error. add_param ( "raw size" . into ( ) , & raw_size) ;
186+ error. add_param ( "dtype size" . into ( ) , & dtype_size) ;
187+ error. add_param ( "expected size" . into ( ) , & expected_size) ;
188+ return Err ( error) ;
189+ }
190+ } else if raw_size % dtype_size != 0 {
191+ let mut error =
192+ ValidationError :: new ( "Raw data size must be a multiple of dtype size in bytes" ) ;
193+ error. add_param ( "raw size" . into ( ) , & raw_size) ;
194+ error. add_param ( "dtype size" . into ( ) , & dtype_size) ;
195+ return Err ( error) ;
196+ }
197+ Ok ( ( ) )
198+ }
199+
167200/// Validate request data
168201fn validate_request_data ( request_data : & RequestData ) -> Result < ( ) , ValidationError > {
169202 // Validation of multiple fields in RequestData.
170203 if let Some ( size) = & request_data. size {
171- let dtype_size = request_data. dtype . size_of ( ) ;
172- if size % dtype_size != 0 {
173- let mut error = ValidationError :: new ( "Size must be a multiple of dtype size in bytes" ) ;
174- error. add_param ( "size" . into ( ) , & size) ;
175- error. add_param ( "dtype size" . into ( ) , & dtype_size) ;
176- return Err ( error) ;
204+ // If the data is compressed then the size refers to the size of the compressed data, so we
205+ // can't validate it at this point.
206+ if request_data. compression . is_none ( ) {
207+ validate_raw_size ( * size, request_data. dtype , & request_data. shape ) ?;
177208 }
178209 } ;
179210 match ( & request_data. shape , & request_data. selection ) {
@@ -531,13 +562,24 @@ mod tests {
531562 }
532563
533564 #[ test]
534- #[ should_panic( expected = "Size must be a multiple of dtype size in bytes" ) ]
565+ #[ should_panic( expected = "Raw data size must be a multiple of dtype size in bytes" ) ]
535566 fn test_invalid_size_for_dtype ( ) {
536567 let mut request_data = get_test_request_data ( ) ;
537568 request_data. size = Some ( 1 ) ;
538569 request_data. validate ( ) . unwrap ( )
539570 }
540571
572+ #[ test]
573+ #[ should_panic(
574+ expected = "Raw data size must be equal to the product of shape indices and dtype size in bytes"
575+ ) ]
576+ fn test_invalid_size_for_shape ( ) {
577+ let mut request_data = get_test_request_data ( ) ;
578+ request_data. size = Some ( 4 ) ;
579+ request_data. shape = Some ( vec ! [ 1 , 2 ] ) ;
580+ request_data. validate ( ) . unwrap ( )
581+ }
582+
541583 #[ test]
542584 #[ should_panic( expected = "Shape and selection must have the same length" ) ]
543585 fn test_shape_selection_mismatch ( ) {
0 commit comments