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:



5
6
7
8
9
10
11
12
# File 'lib/hdf5/attribute.rb', line 5

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

Instance Method Details

#closeObject



44
45
46
47
48
49
# File 'lib/hdf5/attribute.rb', line 44

def close
  return if @attr_id.nil?

  Native.check(HDF5::FFI.H5Aclose(@attr_id), 'Failed to close HDF5 attribute')
  @attr_id = nil
end

#readObject



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

def read
  raise ClosedError, 'HDF5 attribute is closed' if @attr_id.nil?

  @context&.ensure_open!(@dataset_id)
  type_id = HDF5::FFI.H5Aget_type(@attr_id)
  raise NativeError, 'Failed to get attribute datatype' if type_id < 0

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

  return read_string(type_id, space_id) if Native.datatype_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 NativeError, '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
  Native.close([:H5Tclose, type_id], [:H5Sclose, space_id])
end