Class: HDF5::AttributeManager
- Inherits:
-
Object
- Object
- HDF5::AttributeManager
- Defined in:
- lib/hdf5/attribute.rb
Instance Method Summary collapse
- #[](attr_name) ⇒ Object
- #[]=(attr_name, value) ⇒ Object
- #create(attr_name, value) ⇒ Object
- #delete(attr_name) ⇒ Object
-
#initialize(dataset_id, context = nil) ⇒ AttributeManager
constructor
A new instance of AttributeManager.
- #key?(attr_name) ⇒ Boolean
- #keys ⇒ Object
- #modify(attr_name, value) ⇒ Object
- #write(attr_name, value) ⇒ Object
Constructor Details
#initialize(dataset_id, context = nil) ⇒ AttributeManager
83 84 85 86 |
# File 'lib/hdf5/attribute.rb', line 83 def initialize(dataset_id, context = nil) @dataset_id = dataset_id @context = context end |
Instance Method Details
#[](attr_name) ⇒ Object
88 89 90 91 92 93 94 |
# File 'lib/hdf5/attribute.rb', line 88 def [](attr_name) @context&.ensure_open!(@dataset_id) attr = Attribute.new(@dataset_id, attr_name, @context) attr.read ensure attr.close if attr end |
#[]=(attr_name, value) ⇒ Object
96 97 98 |
# File 'lib/hdf5/attribute.rb', line 96 def []=(attr_name, value) write(attr_name, value) end |
#create(attr_name, value) ⇒ Object
131 132 133 134 135 |
# File 'lib/hdf5/attribute.rb', line 131 def create(attr_name, value) raise HDF5::Error, "Attribute already exists: #{attr_name}" if key?(attr_name) write(attr_name, value) end |
#delete(attr_name) ⇒ Object
123 124 125 126 127 128 129 |
# File 'lib/hdf5/attribute.rb', line 123 def delete(attr_name) @context&.ensure_open!(@dataset_id) status = HDF5::FFI.H5Adelete(@dataset_id, attr_name) raise HDF5::Error, "Failed to delete attribute: #{attr_name}" if status < 0 self end |
#key?(attr_name) ⇒ Boolean
115 116 117 118 119 120 121 |
# File 'lib/hdf5/attribute.rb', line 115 def key?(attr_name) @context&.ensure_open!(@dataset_id) exists = HDF5::FFI.H5Aexists(@dataset_id, attr_name) raise HDF5::Error, "Failed to check attribute existence: #{attr_name}" if exists.negative? exists.positive? end |
#keys ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/hdf5/attribute.rb', line 100 def keys @context&.ensure_open!(@dataset_id) names = [] index = ::FFI::MemoryPointer.new(:ulong_long) index.write_ulong_long(0) callback = ::FFI::Function.new(:int, %i[int64_t string pointer pointer]) do |_, name, _, _| names << name 0 end status = HDF5::FFI.H5Aiterate2(@dataset_id, :H5_INDEX_NAME, :H5_ITER_NATIVE, index, callback, nil) raise HDF5::Error, 'Failed to iterate over attributes' if status < 0 names end |
#modify(attr_name, value) ⇒ Object
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/hdf5/attribute.rb', line 137 def modify(attr_name, value) @context&.ensure_open!(@dataset_id) raise HDF5::Error, "Attribute not found: #{attr_name}" unless key?(attr_name) attr_id = HDF5::FFI.H5Aopen(@dataset_id, attr_name, HDF5::DEFAULT_PROPERTY_LIST) raise HDF5::Error, "Failed to open attribute: #{attr_name}" if attr_id < 0 type_id = HDF5::FFI.H5Aget_type(attr_id) space_id = HDF5::FFI.H5Aget_space(attr_id) raise HDF5::Error, "Failed to inspect attribute: #{attr_name}" if type_id < 0 || space_id < 0 if HDF5::FFI.H5Tget_class(type_id) == :H5T_STRING unless HDF5::StringCodec.variable?(type_id) raise UnsupportedTypeError, 'Fixed-length string attributes are not yet supported' end string_values, string_shape = HDF5::StringCodec.normalize_data(value) unless string_shape == attribute_shape(space_id) raise HDF5::ShapeError, 'Attribute shape must not change when modifying' end buffer, _string_pointers = HDF5::StringCodec.buffer_for_values(string_values) status = HDF5::FFI.H5Awrite(attr_id, type_id, buffer) else dtype_object = DType.for_hdf5(type_id) values = HDF5::DataHelpers.normalize_data(value, label: 'Attribute data') expected_shape = attribute_shape(space_id) raise HDF5::Error, 'Attribute shape must not change when modifying' unless values.shape == expected_shape converted = dtype_object.numo_class.cast(values) status = HDF5::FFI.H5Awrite(attr_id, dtype_object.memory_type_id, HDF5::DataHelpers.buffer_for(converted)) end raise HDF5::Error, "Failed to modify attribute: #{attr_name}" if status < 0 value ensure HDF5::FFI.H5Sclose(space_id) if space_id && space_id >= 0 HDF5::FFI.H5Tclose(type_id) if type_id && type_id >= 0 HDF5::FFI.H5Aclose(attr_id) if attr_id && attr_id >= 0 end |
#write(attr_name, value) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/hdf5/attribute.rb', line 179 def write(attr_name, value) @context&.ensure_open!(@dataset_id) string_data = HDF5::StringCodec.string_data?(value) string_values, string_shape = HDF5::StringCodec.normalize_data(value) if string_data values = HDF5::DataHelpers.normalize_data(value, label: 'Attribute data') unless string_data dtype_object = DType.for_numo(values) unless string_data type_id = string_data ? HDF5::StringCodec.datatype_id : dtype_object.storage_type_id exists = HDF5::FFI.H5Aexists(@dataset_id, attr_name) raise HDF5::Error, "Failed to check attribute existence: #{attr_name}" if exists.negative? if exists.positive? status = HDF5::FFI.H5Adelete(@dataset_id, attr_name) raise HDF5::Error, "Failed to replace attribute: #{attr_name}" if status < 0 end dataspace_id = create_dataspace(string_data ? string_shape : values.shape) raise HDF5::Error, 'Failed to create attribute dataspace' if dataspace_id < 0 attr_id = HDF5::FFI.H5Acreate2( @dataset_id, attr_name, type_id, dataspace_id, HDF5::DEFAULT_PROPERTY_LIST, HDF5::DEFAULT_PROPERTY_LIST ) raise HDF5::Error, "Failed to create attribute: #{attr_name}" if attr_id < 0 buffer, _string_pointers = if string_data HDF5::StringCodec.buffer_for_values(string_values) else [HDF5::DataHelpers.buffer_for(values), nil] end memory_type_id = string_data ? type_id : dtype_object.memory_type_id status = HDF5::FFI.H5Awrite(attr_id, memory_type_id, buffer) raise HDF5::Error, "Failed to write attribute: #{attr_name}" if status < 0 value ensure HDF5::FFI.H5Aclose(attr_id) if attr_id && attr_id >= 0 HDF5::FFI.H5Sclose(dataspace_id) if dataspace_id && dataspace_id >= 0 HDF5::FFI.H5Tclose(type_id) if string_data && type_id && type_id >= 0 end |