@@ -46,6 +46,7 @@ def normalize_data(data)
4646
4747 def datatype_id_for ( data )
4848 if data . all? { |value | value . is_a? ( Integer ) }
49+ validate_native_int_range! ( data )
4950 HDF5 ::FFI . H5T_NATIVE_INT
5051 elsif data . all? { |value | value . is_a? ( Numeric ) }
5152 HDF5 ::FFI . H5T_NATIVE_DOUBLE
@@ -66,7 +67,23 @@ def buffer_for(data)
6667 buffer
6768 end
6869
69- private :normalize_data , :datatype_id_for , :buffer_for
70+ def native_int_bounds
71+ bits = ::FFI . type_size ( :int ) * 8
72+ max = ( 1 << ( bits - 1 ) ) - 1
73+ min = -( 1 << ( bits - 1 ) )
74+ [ min , max ]
75+ end
76+
77+ def validate_native_int_range! ( values )
78+ min , max = native_int_bounds
79+ out_of_range = values . find { |value | value < min || value > max }
80+ return unless out_of_range
81+
82+ raise HDF5 ::Error ,
83+ "Integer value #{ out_of_range } is outside native int range (#{ min } ..#{ max } ). Use a smaller value."
84+ end
85+
86+ private :normalize_data , :datatype_id_for , :buffer_for , :native_int_bounds , :validate_native_int_range!
7087
7188 private
7289
@@ -87,8 +104,8 @@ def attrs
87104
88105 def write ( data )
89106 values = self . class . send ( :normalize_data , data )
90- buffer = self . class . send ( :buffer_for , values )
91107 mem_type_id = self . class . send ( :datatype_id_for , values )
108+ buffer = self . class . send ( :buffer_for , values )
92109 status = HDF5 ::FFI . H5Dwrite ( @dataset_id , mem_type_id , HDF5 ::DEFAULT_PROPERTY_LIST , HDF5 ::DEFAULT_PROPERTY_LIST ,
93110 HDF5 ::DEFAULT_PROPERTY_LIST , buffer )
94111 raise HDF5 ::Error , 'Failed to write dataset' if status < 0
0 commit comments