Skip to content

Commit f92aca4

Browse files
committed
Add High level classes
1 parent 0975d19 commit f92aca4

File tree

4 files changed

+172
-0
lines changed

4 files changed

+172
-0
lines changed

lib/hdf5.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,7 @@ def search_hdf5lib(name = nil)
3333
end
3434

3535
require_relative 'hdf5/ffi3'
36+
37+
require_relative 'hdf5/file'
38+
require_relative 'hdf5/group'
39+
require_relative 'hdf5/dataset'

lib/hdf5/dataset.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
module HDF5
2+
class Dataset
3+
def initialize(parent_id, name)
4+
@dataset_id = HDF5::FFI.H5Dopen1(parent_id, name)
5+
end
6+
7+
def write(data)
8+
HDF5::FFI.H5Dwrite(@dataset_id, data)
9+
end
10+
11+
def close
12+
HDF5::FFI.H5Dclose(@dataset_id)
13+
end
14+
15+
def dtype
16+
datatype_id = HDF5::FFI.H5Dget_type(@dataset_id)
17+
HDF5::FFI.H5Tget_class(datatype_id)
18+
end
19+
20+
def shape
21+
dataspace_id = HDF5::FFI.H5Dget_space(@dataset_id)
22+
raise 'Failed to get dataspace' if dataspace_id < 0
23+
24+
ndims = HDF5::FFI.H5Sget_simple_extent_ndims(dataspace_id)
25+
raise 'Failed to get number of dimensions' if ndims < 0
26+
27+
dims = ::FFI::MemoryPointer.new(:ulong_long, ndims)
28+
HDF5::FFI.H5Sget_simple_extent_dims(dataspace_id, dims, nil)
29+
30+
dims.read_array_of_uint64(ndims)
31+
ensure
32+
HDF5::FFI.H5Sclose(dataspace_id) if dataspace_id && dataspace_id >= 0
33+
end
34+
35+
# def read
36+
# dtype = dtype()
37+
# shape = shape()
38+
39+
# total_elements = shape.inject(:*)
40+
# case dtype
41+
# when :H5T_INTEGER
42+
# read_integer_data(total_elements)
43+
# when :H5T_FLOAT
44+
# read_float_data(total_elements)
45+
# when :H5T_STRING
46+
# read_string_data(total_elements)
47+
# else
48+
# raise 'Unsupported datatype'
49+
# end
50+
# end
51+
end
52+
end

lib/hdf5/file.rb

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
module HDF5
2+
class File
3+
def initialize(filename, mode = 0)
4+
@filename = filename
5+
@mode = mode
6+
@file_id = HDF5::FFI.H5Fopen(filename, mode, 0)
7+
end
8+
9+
def close
10+
HDF5::FFI.H5Fclose(@file_id)
11+
end
12+
13+
def create_group(name)
14+
Group.new(@file_id, name)
15+
end
16+
17+
def create_dataset(name, data)
18+
Dataset.new(@file_id, name, data)
19+
end
20+
21+
def [](name)
22+
if HDF5::FFI.group_exists?(@file_id, name)
23+
Group.new(@file_id, name)
24+
elsif HDF5::FFI.dataset_exists?(@file_id, name)
25+
Dataset.new(@file_id, name, nil)
26+
else
27+
raise 'Group or Dataset not found'
28+
end
29+
end
30+
31+
def list_entries
32+
list = []
33+
callback = ::FFI::Function.new(:int, %i[int64_t string pointer pointer]) do |_, name, _, _|
34+
list << name
35+
0 # continue
36+
end
37+
38+
status = HDF5::FFI.H5Literate(@file_id, :H5_INDEX_NAME, :H5_ITER_NATIVE, nil, callback, nil)
39+
raise 'Failed to iterate over file entries' if status < 0
40+
41+
list
42+
end
43+
44+
def [](name)
45+
if group?(name)
46+
Group.new(@file_id, name)
47+
elsif dataset?(name)
48+
Dataset.new(@file_id, name)
49+
else
50+
raise 'Unknown object type'
51+
end
52+
end
53+
54+
private
55+
56+
def group?(name)
57+
info = HDF5::FFI::H5OInfoT.new
58+
HDF5::FFI.H5Oget_info_by_name(@file_id, name, info, 0)
59+
info[:type] == :H5O_TYPE_GROUP
60+
end
61+
62+
def dataset?(name)
63+
info = HDF5::FFI::H5OInfoT.new
64+
HDF5::FFI.H5Oget_info_by_name(@file_id, name, info, 0)
65+
info[:type] == :H5O_TYPE_DATASET
66+
end
67+
end
68+
end

lib/hdf5/group.rb

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module HDF5
2+
class Group
3+
def initialize(file_id, name)
4+
@group_id = HDF5::FFI.H5Gopen1(file_id, name)
5+
raise "Failed to open group: #{name}" if @group_id < 0
6+
end
7+
8+
def close
9+
HDF5::FFI.H5Gclose(@group_id)
10+
end
11+
12+
def list_datasets
13+
datasets = []
14+
callback = ::FFI::Function.new(:int, %i[int64_t string pointer pointer]) do |_, name, _, _|
15+
datasets << name
16+
0 # continue
17+
end
18+
status = HDF5::FFI.H5Literate(@group_id, :H5_INDEX_NAME, :H5_ITER_NATIVE, nil, callback, nil)
19+
raise 'Failed to list datasets' if status < 0
20+
21+
datasets
22+
end
23+
24+
def [](name)
25+
if group?(name)
26+
Group.new(@group_id, name)
27+
elsif dataset?(name)
28+
Dataset.new(@group_id, name)
29+
else
30+
raise 'Group or Dataset not found'
31+
end
32+
end
33+
34+
private
35+
36+
def group?(name)
37+
info = HDF5::FFI::H5OInfoT.new
38+
HDF5::FFI.H5Oget_info_by_name(@group_id, name, info, 0)
39+
info[:type] == :H5O_TYPE_GROUP
40+
end
41+
42+
def dataset?(name)
43+
info = HDF5::FFI::H5OInfoT.new
44+
HDF5::FFI.H5Oget_info_by_name(@group_id, name, info, 0)
45+
info[:type] == :H5O_TYPE_DATASET
46+
end
47+
end
48+
end

0 commit comments

Comments
 (0)