ruby-hdf5 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/hdf5/file.rb ADDED
@@ -0,0 +1,126 @@
1
+ module HDF5
2
+ class File
3
+ H5F_ACC_RDONLY = 0x0000
4
+ H5F_ACC_RDWR = 0x0001
5
+ H5F_ACC_TRUNC = 0x0002
6
+
7
+ class << self
8
+ def create(filename, flags = H5F_ACC_TRUNC)
9
+ file = from_id(HDF5::FFI.H5Fcreate(filename, flags, HDF5::DEFAULT_PROPERTY_LIST, HDF5::DEFAULT_PROPERTY_LIST),
10
+ filename, flags)
11
+ return file unless block_given?
12
+
13
+ begin
14
+ yield file
15
+ ensure
16
+ file.close
17
+ end
18
+ end
19
+
20
+ def open(filename, mode = H5F_ACC_RDONLY)
21
+ file = from_id(HDF5::FFI.H5Fopen(filename, mode, HDF5::DEFAULT_PROPERTY_LIST), filename, mode)
22
+ return file unless block_given?
23
+
24
+ begin
25
+ yield file
26
+ ensure
27
+ file.close
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def from_id(file_id, filename, mode)
34
+ file = allocate
35
+ file.send(:initialize_from_id, file_id, filename, mode)
36
+ file
37
+ end
38
+ end
39
+
40
+ def initialize(filename, mode = H5F_ACC_RDONLY)
41
+ initialize_from_id(HDF5::FFI.H5Fopen(filename, mode, HDF5::DEFAULT_PROPERTY_LIST), filename, mode)
42
+ end
43
+
44
+ def close
45
+ return if @file_id.nil?
46
+
47
+ HDF5::FFI.H5Fclose(@file_id)
48
+ @file_id = nil
49
+ end
50
+
51
+ def create_group(name, &block)
52
+ Group.create(@file_id, name, &block)
53
+ end
54
+
55
+ def create_dataset(name, data, &block)
56
+ Dataset.create(@file_id, name, data, &block)
57
+ end
58
+
59
+ def list_entries
60
+ list = []
61
+ callback = ::FFI::Function.new(:int, %i[int64_t string pointer pointer]) do |_, name, _, _|
62
+ list << name
63
+ 0 # continue
64
+ end
65
+
66
+ case HDF5::FFI::MiV
67
+ when 10
68
+ HDF5::FFI.H5Literate(@file_id, :H5_INDEX_NAME, :H5_ITER_NATIVE, nil, callback, nil)
69
+ else
70
+ HDF5::FFI.H5Literate2(@file_id, :H5_INDEX_NAME, :H5_ITER_NATIVE, nil, callback, nil)
71
+ end.negative? && raise(HDF5::Error, 'Failed to iterate over file entries')
72
+
73
+ list
74
+ end
75
+
76
+ def [](name)
77
+ if group?(name)
78
+ Group.open(@file_id, name)
79
+ elsif dataset?(name)
80
+ Dataset.open(@file_id, name)
81
+ else
82
+ raise HDF5::Error, 'Unknown object type'
83
+ end
84
+ end
85
+
86
+ def attrs
87
+ @attrs ||= AttributeManager.new(@file_id)
88
+ end
89
+
90
+ private
91
+
92
+ def initialize_from_id(file_id, filename, mode)
93
+ raise HDF5::Error, "Failed to open file: #{filename}" if file_id < 0
94
+
95
+ @filename = filename
96
+ @mode = mode
97
+ @file_id = file_id
98
+ end
99
+
100
+ def group?(name)
101
+ info = if HDF5::FFI::MiV == 10
102
+ HDF5::FFI::H5OInfoT.new.tap do |i|
103
+ HDF5::FFI.H5Oget_info_by_name(@file_id, name, i, 0)
104
+ end
105
+ else
106
+ HDF5::FFI::H5OInfo1T.new.tap do |i|
107
+ HDF5::FFI.H5Oget_info_by_name1(@file_id, name, i, 0)
108
+ end
109
+ end
110
+ info[:type] == :H5O_TYPE_GROUP
111
+ end
112
+
113
+ def dataset?(name)
114
+ info = if HDF5::FFI::MiV == 10
115
+ HDF5::FFI::H5OInfoT.new.tap do |i|
116
+ HDF5::FFI.H5Oget_info_by_name(@file_id, name, i, 0)
117
+ end
118
+ else
119
+ HDF5::FFI::H5OInfo1T.new.tap do |i|
120
+ HDF5::FFI.H5Oget_info_by_name1(@file_id, name, i, 0)
121
+ end
122
+ end
123
+ info[:type] == :H5O_TYPE_DATASET
124
+ end
125
+ end
126
+ end
data/lib/hdf5/group.rb ADDED
@@ -0,0 +1,123 @@
1
+ module HDF5
2
+ class Group
3
+ class << self
4
+ def create(parent_id, name)
5
+ group = from_id(
6
+ HDF5::FFI.H5Gcreate2(parent_id, name, HDF5::DEFAULT_PROPERTY_LIST, HDF5::DEFAULT_PROPERTY_LIST,
7
+ HDF5::DEFAULT_PROPERTY_LIST), name
8
+ )
9
+ return group unless block_given?
10
+
11
+ begin
12
+ yield group
13
+ ensure
14
+ group.close
15
+ end
16
+ end
17
+
18
+ def open(parent_id, name)
19
+ group = from_id(HDF5::FFI.H5Gopen2(parent_id, name, HDF5::DEFAULT_PROPERTY_LIST), name)
20
+ return group unless block_given?
21
+
22
+ begin
23
+ yield group
24
+ ensure
25
+ group.close
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def from_id(group_id, name)
32
+ group = allocate
33
+ group.send(:initialize_from_id, group_id, name)
34
+ group
35
+ end
36
+ end
37
+
38
+ def initialize(file_id, name)
39
+ initialize_from_id(HDF5::FFI.H5Gopen2(file_id, name, HDF5::DEFAULT_PROPERTY_LIST), name)
40
+ end
41
+
42
+ def close
43
+ return if @group_id.nil?
44
+
45
+ HDF5::FFI.H5Gclose(@group_id)
46
+ @group_id = nil
47
+ end
48
+
49
+ def create_group(name, &block)
50
+ self.class.create(@group_id, name, &block)
51
+ end
52
+
53
+ def create_dataset(name, data, &block)
54
+ Dataset.create(@group_id, name, data, &block)
55
+ end
56
+
57
+ def list_datasets
58
+ datasets = []
59
+ callback = ::FFI::Function.new(:int, %i[int64_t string pointer pointer]) do |_, name, _, _|
60
+ datasets << name
61
+ 0 # continue
62
+ end
63
+
64
+ (if HDF5::FFI::MiV == 10
65
+ HDF5::FFI.H5Literate(@group_id, :H5_INDEX_NAME, :H5_ITER_NATIVE, nil, callback, nil)
66
+ else
67
+ HDF5::FFI.H5Literate2(@group_id, :H5_INDEX_NAME, :H5_ITER_NATIVE, nil, callback, nil)
68
+ end).negative? &&
69
+ raise('Failed to list datasets')
70
+
71
+ datasets
72
+ end
73
+
74
+ def [](name)
75
+ if group?(name)
76
+ self.class.open(@group_id, name)
77
+ elsif dataset?(name)
78
+ Dataset.open(@group_id, name)
79
+ else
80
+ raise HDF5::Error, 'Group or Dataset not found'
81
+ end
82
+ end
83
+
84
+ def attrs
85
+ @attrs ||= AttributeManager.new(@group_id)
86
+ end
87
+
88
+ private
89
+
90
+ def initialize_from_id(group_id, name)
91
+ raise HDF5::Error, "Failed to open group: #{name}" if group_id < 0
92
+
93
+ @group_id = group_id
94
+ @name = name
95
+ end
96
+
97
+ def group?(name)
98
+ info = if HDF5::FFI::MiV == 10
99
+ HDF5::FFI::H5OInfoT.new.tap do |i|
100
+ HDF5::FFI.H5Oget_info_by_name(@group_id, name, i, 0)
101
+ end
102
+ else
103
+ HDF5::FFI::H5OInfo1T.new.tap do |i|
104
+ HDF5::FFI.H5Oget_info_by_name1(@group_id, name, i, 0)
105
+ end
106
+ end
107
+ info[:type] == :H5O_TYPE_GROUP
108
+ end
109
+
110
+ def dataset?(name)
111
+ info = if HDF5::FFI::MiV == 10
112
+ HDF5::FFI::H5OInfoT.new.tap do |i|
113
+ HDF5::FFI.H5Oget_info_by_name(@group_id, name, i, 0)
114
+ end
115
+ else
116
+ HDF5::FFI::H5OInfo1T.new.tap do |i|
117
+ HDF5::FFI.H5Oget_info_by_name1(@group_id, name, i, 0)
118
+ end
119
+ end
120
+ info[:type] == :H5O_TYPE_DATASET
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module HDF5
4
+ VERSION = '0.0.1'
5
+ end
data/lib/hdf5.rb ADDED
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ffi'
4
+ require_relative 'hdf5/version'
5
+
6
+ module HDF5
7
+ class Error < StandardError; end
8
+ DEFAULT_PROPERTY_LIST = 0
9
+
10
+ class << self
11
+ attr_accessor :lib_path
12
+
13
+ def search_hdf5lib
14
+ name = "libhdf5.#{FFI::Platform::LIBSUFFIX}"
15
+ env_path = ENV['HDF5_LIB_PATH']
16
+ return env_path if env_path && File.file?(env_path)
17
+ return File.expand_path(name, env_path) if env_path && File.directory?(env_path)
18
+
19
+ begin
20
+ require 'pkg-config'
21
+ libs = PKGConfig.libs('hdf5')
22
+ pattern = %r{(?<=-L)/[^ ]+}
23
+ libs.scan(pattern).each do |lib_dir|
24
+ lib_path = File.expand_path(name, lib_dir)
25
+ return lib_path if File.exist?(lib_path)
26
+ end
27
+ rescue PackageConfig::NotFoundError
28
+ warn 'hdf5.pc not found.'
29
+ end
30
+
31
+ name
32
+ end
33
+ end
34
+
35
+ self.lib_path = search_hdf5lib
36
+ end
37
+
38
+ require_relative 'hdf5/ffi'
39
+
40
+ require_relative 'hdf5/file'
41
+ require_relative 'hdf5/group'
42
+ require_relative 'hdf5/dataset'
43
+ require_relative 'hdf5/attribute'
metadata ADDED
@@ -0,0 +1,79 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ruby-hdf5
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - kojix2
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: ffi
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: pkg-config
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ description: hdf5
41
+ email:
42
+ - 2xijok@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - LICENSE.txt
48
+ - README.md
49
+ - lib/hdf5.rb
50
+ - lib/hdf5/attribute.rb
51
+ - lib/hdf5/dataset.rb
52
+ - lib/hdf5/ffi.rb
53
+ - lib/hdf5/ffi_10.rb
54
+ - lib/hdf5/ffi_14.rb
55
+ - lib/hdf5/file.rb
56
+ - lib/hdf5/group.rb
57
+ - lib/hdf5/version.rb
58
+ licenses:
59
+ - MIT
60
+ metadata:
61
+ msys2_mingw_dependencies: hdf5
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 3.2.0
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubygems_version: 4.0.6
77
+ specification_version: 4
78
+ summary: hdf5
79
+ test_files: []