Class: HDF5::Attribute

Inherits:
Object
  • Object
show all
Defined in:
lib/hdf5/attribute.rb

Instance Method Summary collapse

Constructor Details

#initialize(dataset_id, attr_name, context = nil) ⇒ Attribute

Returns a new instance of Attribute.

Raises:



3
4
5
6
7
8
9
# File 'lib/hdf5/attribute.rb', line 3

def initialize(dataset_id, attr_name, context = nil)
  @dataset_id = dataset_id
  @attr_name = attr_name
  context&.ensure_open!(dataset_id)
  @attr_id = HDF5::FFI.H5Aopen(@dataset_id, @attr_name, HDF5::DEFAULT_PROPERTY_LIST)
  raise HDF5::Error, 'Failed to open attribute' if @attr_id < 0
end

Instance Method Details

#close ⇒ Object



39
40
41
42
43
44
# File 'lib/hdf5/attribute.rb', line 39

def close
  return if @attr_id.nil?

  HDF5::FFI.H5Aclose(@attr_id)
  @attr_id = nil
end

#read ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/hdf5/attribute.rb', line 11

def read
  type_id = HDF5::FFI.H5Aget_type(@attr_id)
  raise HDF5::Error, 'Failed to get attribute datatype' if type_id < 0

  space_id = HDF5::FFI.H5Aget_space(@attr_id)
  raise HDF5::Error, 'Failed to get attribute dataspace' if space_id < 0
  return HDF5::Empty.new(DType.for_hdf5(type_id)) if HDF5::FFI.H5Sget_simple_extent_type(space_id) == :H5S_NULL

  return read_string(type_id, space_id) if HDF5::FFI.H5Tget_class(type_id) == :H5T_STRING

  dtype_object = DType.for_hdf5(type_id)
  attribute_shape = shape(space_id)
  size = attribute_shape.empty? ? 1 : attribute_shape.inject(:*)
  buffer = ::FFI::MemoryPointer.new(:char, size * dtype_object.itemsize)
  status = HDF5::FFI.H5Aread(@attr_id, dtype_object.memory_type_id, buffer)
  raise HDF5::Error, 'Failed to read attribute' if status < 0

  result = HDF5::DataHelpers.from_binary(dtype_object, buffer.read_bytes(size * dtype_object.itemsize),
                                         attribute_shape)
  return result unless attribute_shape.empty?

  scalar = result.extract
  dtype_object.kind == :bool ? !scalar.zero? : scalar
ensure
  HDF5::FFI.H5Tclose(type_id) if type_id && type_id >= 0
  HDF5::FFI.H5Sclose(space_id) if space_id && space_id >= 0
end