29
29
module MAT_HDF5
30
30
31
31
using HDF5, SparseArrays
32
+ using .. MAT_subsys
32
33
33
34
import Base: names, read, write, close
34
35
import HDF5: Reference
@@ -69,8 +70,13 @@ function close(f::MatlabHDF5File)
69
70
unsafe_copyto! (magicptr, idptr, length (identifier))
70
71
end
71
72
magic[126 ] = 0x02
72
- magic[127 ] = 0x49
73
- magic[128 ] = 0x4d
73
+ if Base. ENDIAN_BOM == 0x04030201
74
+ magic[127 ] = 0x49
75
+ magic[128 ] = 0x4d
76
+ else
77
+ magic[127 ] = 0x4d
78
+ magic[128 ] = 0x49
79
+ end
74
80
rawfid = open (f. plain. filename, " r+" )
75
81
write (rawfid, magic)
76
82
close (rawfid)
@@ -80,7 +86,7 @@ function close(f::MatlabHDF5File)
80
86
nothing
81
87
end
82
88
83
- function matopen (filename:: AbstractString , rd:: Bool , wr:: Bool , cr:: Bool , tr:: Bool , ff:: Bool , compress:: Bool )
89
+ function matopen (filename:: AbstractString , rd:: Bool , wr:: Bool , cr:: Bool , tr:: Bool , ff:: Bool , compress:: Bool , endian_indicator :: Bool )
84
90
local f
85
91
if ff && ! wr
86
92
error (" Cannot append to a read-only file" )
@@ -109,6 +115,11 @@ function matopen(filename::AbstractString, rd::Bool, wr::Bool, cr::Bool, tr::Boo
109
115
fid. refcounter = length (g)- 1
110
116
close (g)
111
117
end
118
+ subsys_refs = " #subsystem#"
119
+ if haskey (fid. plain, subsys_refs)
120
+ subsys_data = m_read (fid. plain[subsys_refs])
121
+ MAT_subsys. load_subsys! (subsys_data, endian_indicator)
122
+ end
112
123
fid
113
124
end
114
125
@@ -118,6 +129,7 @@ const name_type_attr_matlab = "MATLAB_class"
118
129
const empty_attr_matlab = " MATLAB_empty"
119
130
const sparse_attr_matlab = " MATLAB_sparse"
120
131
const int_decode_attr_matlab = " MATLAB_int_decode"
132
+ const object_type_attr_matlab = " MATLAB_object_decode"
121
133
122
134
# ## Reading
123
135
function read_complex (dtype:: HDF5.Datatype , dset:: HDF5.Dataset , :: Type{T} ) where T
@@ -128,6 +140,21 @@ function read_complex(dtype::HDF5.Datatype, dset::HDF5.Dataset, ::Type{T}) where
128
140
return read (dset, Complex{T})
129
141
end
130
142
143
+ function read_cell (dset:: HDF5.Dataset )
144
+ refs = read (dset, Reference)
145
+ out = Array {Any} (undef, size (refs))
146
+ f = HDF5. file (dset)
147
+ for i = 1 : length (refs)
148
+ dset = f[refs[i]]
149
+ try
150
+ out[i] = m_read (dset)
151
+ finally
152
+ close (dset)
153
+ end
154
+ end
155
+ return out
156
+ end
157
+
131
158
function m_read (dset:: HDF5.Dataset )
132
159
if haskey (dset, empty_attr_matlab)
133
160
# Empty arrays encode the dimensions as the dataset
@@ -150,36 +177,46 @@ function m_read(dset::HDF5.Dataset)
150
177
end
151
178
152
179
mattype = haskey (dset, name_type_attr_matlab) ? read_attribute (dset, name_type_attr_matlab) : " cell"
180
+ objecttype = haskey (dset, object_type_attr_matlab) ? read_attribute (dset, object_type_attr_matlab) : nothing
153
181
154
- if mattype == " cell"
182
+ if mattype == " cell" && objecttype === nothing
155
183
# Cell arrays, represented as an array of refs
156
- refs = read (dset, Reference)
157
- out = Array {Any} (undef, size (refs))
158
- f = HDF5. file (dset)
159
- for i = 1 : length (refs)
160
- dset = f[refs[i]]
161
- try
162
- out[i] = m_read (dset)
163
- finally
164
- close (dset)
165
- end
184
+ return read_cell (dset)
185
+ elseif objecttype != = nothing
186
+ if objecttype != 3
187
+ @warn " MATLAB Object Type $mattype is currently not supported."
188
+ return missing
189
+ end
190
+ if mattype == " FileWrapper__"
191
+ return read_cell (dset)
192
+ end
193
+ if haskey (dset, " MATLAB_fields" )
194
+ @warn " Enumeration Instances are not supported currently."
195
+ return missing
166
196
end
167
- return out
168
197
elseif ! haskey (str2type_matlab,mattype)
169
- @warn " MATLAB $mattype values are currently not supported"
198
+ @warn " MATLAB $mattype values are currently not supported. "
170
199
return missing
171
200
end
172
201
173
202
# Regular arrays of values
174
203
# Convert to Julia type
175
- T = str2type_matlab[mattype]
204
+ if objecttype === nothing
205
+ T = str2type_matlab[mattype]
206
+ else
207
+ T = UInt32 # FIXME : Default for MATLAB objects?
208
+ end
176
209
177
210
# Check for a COMPOUND data set, and if so handle complex numbers specially
178
211
dtype = datatype (dset)
179
212
try
180
213
class_id = HDF5. API. h5t_get_class (dtype. id)
181
214
d = class_id == HDF5. API. H5T_COMPOUND ? read_complex (dtype, dset, T) : read (dset, T)
182
- length (d) == 1 ? d[1 ] : d
215
+ if objecttype != = nothing
216
+ return MAT_subsys. load_mcos_object (d, " MCOS" )
217
+ else
218
+ return length (d) == 1 ? d[1 ] : d
219
+ end
183
220
finally
184
221
close (dtype)
185
222
end
194
231
195
232
# reading a struct, struct array, or sparse matrix
196
233
function m_read (g:: HDF5.Group )
197
- mattype = read_attribute (g, name_type_attr_matlab)
234
+ if HDF5. name (g) == " /#subsystem#"
235
+ mattype = " #subsystem#"
236
+ else
237
+ mattype = read_attribute (g, name_type_attr_matlab)
238
+ end
198
239
if mattype != " struct"
199
240
# Check if this is a sparse matrix.
200
241
fn = keys (g)
@@ -226,10 +267,11 @@ function m_read(g::HDF5.Group)
226
267
end
227
268
return SparseMatrixCSC (convert (Int, read_attribute (g, sparse_attr_matlab)), length (jc)- 1 , jc, ir, data)
228
269
elseif mattype == " function_handle"
229
- @warn " MATLAB $mattype values are currently not supported"
230
- return missing
270
+ # Fall through
231
271
else
232
- @warn " Unknown non-struct group of type $mattype detected; attempting to read as struct"
272
+ if mattype != " #subsystem#"
273
+ @warn " Unknown non-struct group of type $mattype detected; attempting to read as struct"
274
+ end
233
275
end
234
276
end
235
277
if haskey (g, " MATLAB_fields" )
0 commit comments