Skip to content

Commit d8a7d83

Browse files
committed
New type FunctionHandle with RW support in v7 and HDF formats
1 parent e16b030 commit d8a7d83

File tree

5 files changed

+28
-11
lines changed

5 files changed

+28
-11
lines changed

src/MAT.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ include("MAT_v4.jl")
3737
using .MAT_HDF5, .MAT_v5, .MAT_v4, .MAT_subsys
3838

3939
export matopen, matread, matwrite, @read, @write
40-
export MatlabStructArray, MatlabClassObject, MatlabOpaque, MatlabTable
40+
export MatlabStructArray, MatlabClassObject, MatlabOpaque, MatlabTable, FunctionHandle
4141

4242
# Open a MATLAB file
4343
const HDF5_HEADER = UInt8[0x89, 0x48, 0x44, 0x46, 0x0d, 0x0a, 0x1a, 0x0a]

src/MAT_HDF5.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,9 @@ function m_read(g::HDF5.Group, subsys::Subsystem)
324324
if haskey(attr, sparse_attr_matlab)
325325
return read_sparse_matrix(g, mattype)
326326
elseif mattype == "function_handle"
327-
# TODO: fall through for now, will become a Dict
327+
if haskey(attr, object_decode_attr_matlab) && read_attribute(g, object_decode_attr_matlab)==1
328+
is_object = true
329+
end
328330
else
329331
if haskey(attr, object_decode_attr_matlab) && read_attribute(g, object_decode_attr_matlab)==2
330332
# I think this means it's an old object class similar to mXOBJECT_CLASS in MAT_v5

src/MAT_types.jl

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export MatlabClassObject
4141
export MatlabOpaque, convert_opaque
4242
export MatlabTable
4343
export ScalarOrArray
44+
export FunctionHandle
4445

4546
const ScalarOrArray{T} = Union{T, AbstractArray{T}}
4647

@@ -176,7 +177,7 @@ function Base.:(==)(m1::MatlabStructArray{N}, m2::MatlabStructArray{N}) where {N
176177
end
177178

178179
function Base.isapprox(m1::MatlabStructArray, m2::MatlabStructArray; kwargs...)
179-
return isequal(m1.class, m2.class) && issetequal(m1.names, m2.names) &&
180+
return isequal(m1.class, m2.class) && issetequal(m1.names, m2.names) &&
180181
key_based_isapprox(m1.names, m1, m2; kwargs...)
181182
end
182183

@@ -300,6 +301,13 @@ struct EmptyStruct
300301
end
301302
class(m::EmptyStruct) = ""
302303

304+
"""
305+
Function Handles which are stored as structs
306+
"""
307+
struct FunctionHandle
308+
d::Dict{String,Any}
309+
end
310+
303311
"""
304312
MatlabClassObject(
305313
d::Dict{String, Any},
@@ -357,6 +365,8 @@ function convert_struct_array(d::AbstractDict{String,Any}, class::String="")
357365
else
358366
if isempty(class)
359367
return d
368+
elseif class == "function_handle"
369+
return FunctionHandle(d)
360370
else
361371
return MatlabClassObject(d, class)
362372
end

src/MAT_v5.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
module MAT_v5
2929
using CodecZlib, HDF5, SparseArrays
3030
import Base: read, write, close
31-
import ..MAT_types: MatlabStructArray, MatlabClassObject, MatlabTable
31+
import ..MAT_types: MatlabStructArray, MatlabClassObject, MatlabTable, FunctionHandle
3232

3333
using ..MAT_subsys
3434

@@ -325,6 +325,11 @@ function read_string(f::IO, swap_bytes::Bool, dimensions::Vector{Int32})
325325
data
326326
end
327327

328+
function read_function_handle(f::IO, swap_bytes::Bool, subsys::Subsystem)
329+
data = read_matrix(f, swap_bytes, subsys)[2] # read_matrix returns (var_name, data)
330+
return FunctionHandle(data)
331+
end
332+
328333
function read_opaque(f::IO, swap_bytes::Bool, subsys::Subsystem)
329334
type_name = String(read_element(f, swap_bytes, UInt8))
330335
classname = String(read_element(f, swap_bytes, UInt8))
@@ -375,7 +380,7 @@ function read_matrix(f::IO, swap_bytes::Bool, subsys::Subsystem)
375380
elseif class == mxCHAR_CLASS && length(dimensions) <= 2
376381
data = read_string(f, swap_bytes, dimensions)
377382
elseif class == mxFUNCTION_CLASS
378-
data = read_matrix(f, swap_bytes, subsys)
383+
data = read_function_handle(f, swap_bytes, subsys)
379384
elseif class == mxOPAQUE_CLASS
380385
data = read_opaque(f, swap_bytes, subsys)
381386
else

test/read.jl

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,12 @@ end
222222
# test reading file containing Matlab function handle, table, and datetime objects
223223
let objtestfile = "function_handles.mat"
224224
vars = matread(joinpath(dirname(@__FILE__), "v7.3", objtestfile))
225-
@test "sin" in keys(vars)
226-
@test typeof(vars["sin"]) == Dict{String, Any}
227-
@test Set(keys(vars["sin"])) == Set(["function_handle", "sentinel", "separator", "matlabroot"])
228-
@test "anonymous" in keys(vars)
229-
@test typeof(vars["anonymous"]) == Dict{String, Any}
230-
@test Set(keys(vars["anonymous"])) == Set(["function_handle", "sentinel", "separator", "matlabroot"])
225+
@test haskey(vars, "sin")
226+
@test haskey(vars, "anonymous")
227+
@test vars["sin"] isa FunctionHandle
228+
@test vars["anonymous"] isa FunctionHandle
229+
@test Set(keys(vars["sin"].d)) == Set(["function_handle", "sentinel", "separator", "matlabroot"])
230+
@test Set(keys(vars["anonymous"].d)) == Set(["function_handle", "sentinel", "separator", "matlabroot"])
231231
end
232232

233233
for format in ["v7", "v7.3"]

0 commit comments

Comments
 (0)