diff --git a/src/MAT_HDF5.jl b/src/MAT_HDF5.jl index 8bbb39b..d31652d 100644 --- a/src/MAT_HDF5.jl +++ b/src/MAT_HDF5.jl @@ -27,6 +27,16 @@ ########################################### module MAT_HDF5 +if VERSION < v"0.4.0-dev+980" + macro Dict(pairs...) + esc(Expr(:dict, pairs...)) + end +else + macro Dict(pairs...) + esc(Expr(:call, :Dict, pairs...)) + end +end + using HDF5 import Base: read, write, close import HDF5: names, exists, HDF5ReferenceObj, HDF5BitsKind @@ -163,11 +173,13 @@ function m_read(dset::HDF5Dataset) # Check for a COMPOUND data set, and if so handle complex numbers specially dtype = datatype(dset) - class_id = HDF5.h5t_get_class(dtype.id) - d = class_id == HDF5.H5T_COMPOUND ? read_complex(dtype, dset, T) : read(dset, T) - - close(dtype) - length(d) == 1 ? d[1] : d + try + class_id = HDF5.h5t_get_class(dtype.id) + d = class_id == HDF5.H5T_COMPOUND ? read_complex(dtype, dset, T) : read(dset, T) + length(d) == 1 ? d[1] : d + finally + close(dtype) + end end function add!(A, x) @@ -313,6 +325,8 @@ function m_writearray{T<:Union(HDF5BitsKind,Bool)}(parent::Union(HDF5File, HDF5G catch e close(dset) rethrow(e) + finally + close(stype) end dset finally @@ -484,7 +498,7 @@ end type MatlabString; end -const str2type_matlab = [ +const str2type_matlab = @Dict( "canonical empty" => nothing, "int8" => Array{Int8}, "uint8" => Array{Uint8}, @@ -499,9 +513,9 @@ const str2type_matlab = [ "cell" => Array{Any}, "char" => MatlabString, "logical" => Array{Bool} -] +) # These operate on the element type rather than the whole type -const str2eltype_matlab = [ +const str2eltype_matlab = @Dict( "canonical empty" => nothing, "int8" => Int8, "uint8" => Uint8, @@ -516,8 +530,8 @@ const str2eltype_matlab = [ "cell" => Any, "char" => MatlabString, "logical" => Bool -] -const type2str_matlab = [ +) +const type2str_matlab = @Dict( Int8 => "int8", Uint8 => "uint8", Int16 => "int16", @@ -529,7 +543,7 @@ const type2str_matlab = [ Float32 => "single", Float64 => "double", Bool => "logical" -] +) function read(obj::HDF5Object, ::Type{MatlabString}) diff --git a/test/read.jl b/test/read.jl index 5576581..f809de6 100644 --- a/test/read.jl +++ b/test/read.jl @@ -1,4 +1,5 @@ using MAT, Base.Test +using MAT.HDF5: @Dict function check(filename, result) matfile = matopen(filename) @@ -47,7 +48,7 @@ global format for format in ["v6", "v7", "v7.3"] cd(joinpath(dirname(@__FILE__), format)) - result = { + result = @Dict( "int8" => int8(1), "uint8" => uint8(1), "int16" => int16(1), @@ -59,7 +60,7 @@ for format in ["v6", "v7", "v7.3"] "single" => float32(1), "double" => float64(1), "logical" => true - } + ) check("simple.mat", result) matfile = matopen("simple.mat") mat = read(matfile) @@ -70,68 +71,68 @@ for format in ["v6", "v7", "v7.3"] end end - result = { + result = @Dict( "imaginary" => Complex128[1 -1 1+im 1-im -1+im -1-im im] - } + ) check("complex.mat", result) - result = { + result = @Dict( "simple_string" => "the quick brown fox", "accented_string" => "thé qüîck browñ fòx", "concatenated_strings" => ByteString["this is a string", "this is another string"], "cell_strings" => {"this is a string" "this is another string"}, "empty_string" => "" - } + ) check("string.mat", result) - result = { + result = @Dict( "a1x2" => [1.0 2.0], "a2x1" => zeros(2, 1)+[1.0, 2.0], "a2x2" => [1.0 3.0; 4.0 2.0], "a2x2x2" => cat(3, [1.0 3.0; 4.0 2.0], [1.0 2.0; 3.0 4.0]), "empty" => zeros(0, 0), "string" => "string" - } + ) check("array.mat", result) - result = { + result = @Dict( "cell" => {1.0 2.01 "string" {"string1" "string2"}} - } + ) check("cell.mat", result) - result = { - "s" => (ASCIIString=>Any)[ - "a" => 1.0, - "b" => [1.0 2.0], - "c" => [1.0 2.0 3.0] - ], - "s2" => (ASCIIString=>Any)[ "a" => {1.0 2.0} ] - } + result = @Dict( + "s" => Dict{ASCIIString,Any}([ + ("a", 1.0), + ("b", [1.0 2.0]), + ("c", [1.0 2.0 3.0]) + ]), + "s2" => Dict{ASCIIString,Any}([("a", {1.0 2.0})]) + ) check("struct.mat", result) - result = { + result = @Dict( "logical" => false, "logical_mat" => [ true false false false true false true false false ] - } + ) check("logical.mat", result) - result = { + result = @Dict( "empty_cells" => {zeros(0, 0) "test" zeros(0, 0)} - } + ) check("empty_cells.mat", result) - result = { + result = @Dict( "sparse_empty" => sparse(Array(Float64, 0, 0)), "sparse_eye" => speye(20), "sparse_logical" => SparseMatrixCSC{Bool,Int64}(5, 5, [1:6], [1:5], bitunpack(trues(5))), "sparse_random" => sparse([0 6. 0; 8. 0 1.; 0 0 9.]), "sparse_complex" => sparse([0 6. 0; 8. 0 1.; 0 0 9.]*(1. + 1.im)), "sparse_zeros" => SparseMatrixCSC(20, 20, ones(Int, 21), Int[], Float64[]) - } + ) check("sparse.mat", result) matfile = matopen("partial.mat") @@ -143,7 +144,7 @@ for format in ["v6", "v7", "v7.3"] end -result = { +result = @Dict( "index" => [8.8604784000000000e+04 9.8707212000000000e+04 1.0394035200000000e+05 1.1429712000000000e+05 1.5474923999999999e+05 1.5475435200000001e+05 1.5501074400000001e+05 1.5505315200000000e+05 1.5505718400000001e+05 1.5506168400000001e+05 1.5506524799999999e+05 5.4945741599999997e+05 5.6345896799999999e+05 5.9956981200000003e+05 7.0691623199999996e+05 7.9063657200000004e+05 8.4311938800000004e+05 9.2225131200000003e+05 1.1248994160000000e+06 1.2508148520000000e+06 1.4164141320000000e+06 1.4275988280000000e+06 1.4744331000000001e+06 1.4982212879999999e+06 1.5549058440000000e+06 1.5870300840000000e+06 1.6192005120000001e+06 1.6766071560000000e+06 1.9386816839999999e+06 1.9969427879999999e+06 2.0021861880000001e+06 2.3272494120000000e+06 2.5309351080000000e+06 2.6743788720000000e+06], "spikes" => [ -3.9146236245031032e+00 -6.7657651330021364e+00 -1.0780027188484372e+01 -1.4345619557780790e+01 -1.5488781013877338e+01 -1.3241531877846004e+01 -8.6339302778751907e+00 -4.1571900578409995e+00 -1.4845719040296610e+00 2.3147400250828232e-01 2.8917910181412778e+00 6.4067867244186800e+00 8.3368575385567603e+00 7.0732985406218223e+00 4.4095174940268036e+00 3.8495932342509342e+00 7.0605464919276546e+00 1.2892731012948772e+01 1.8593404980539656e+01 2.1332908128411184e+01 2.0142332517120792e+01 1.6740473413471157e+01 1.3650330377340575e+01 1.1913871749214691e+01 1.0804794411826084e+01 8.8366401987297127e+00 5.1092331749990514e+00 5.1218216653980408e-01 -2.9327647633922682e+00 -4.4870896208146753e+00 -5.0598199463728655e+00 -4.8330524336350118e+00 -2.8556000012645000e+00 2.9794817723619027e-01 1.8265416505730325e+00 -8.6155940979615875e-02 -3.9623352473810947e+00 -6.9070013227561047e+00 -7.3941131196997647e+00 -5.7411207637544166e+00 -3.2366812420300106e+00 -1.1460492068000723e+00 1.2381260731009580e-01 1.0930145325605314e+00 2.1927876983540933e+00 2.6570284430776856e+00 1.3381366125210661e+00 -1.2539624260623763e+00 -3.3642620416729994e+00 -4.1849749207505456e+00 -3.8760400918509301e+00 -2.6869552030388291e+00 -1.6718246062697015e+00 -2.3709942853677934e+00 -4.6623835517993664e+00 -6.6575320887201714e+00 -6.9891263747717174e+00 -5.7017039068420186e+00 -3.4759011423153079e+00 -1.7092931352045238e+00 -2.3854494206243695e+00 -5.8068462168496913e+00 -9.1001745572212531e+00 -8.8479323560036516e+00 @@ -181,5 +182,5 @@ result = { -2.5417468582312877e+00 -1.9298735695592950e-01 1.4524591906329190e+00 1.4111623962585536e+00 -3.3194621049731687e-01 -2.5702905387021753e+00 -3.3145376224302021e+00 -1.6531002526600589e+00 1.5085470936791965e+00 4.9384825610490894e+00 8.1158180601966112e+00 1.0592317046651424e+01 1.1720352844683582e+01 1.1731547138555802e+01 1.1880590058094510e+01 1.2779413370052000e+01 1.4075646883094780e+01 1.5918248275430194e+01 1.8326489365386571e+01 1.9316206123129387e+01 1.6690629155310674e+01 1.1661681239753394e+01 8.0053968635282153e+00 7.5533291045585287e+00 8.4805002524471416e+00 7.9431009917907147e+00 4.7893096294793169e+00 -2.9205326061448478e-01 -5.9299905729305458e+00 -1.0889025474342041e+01 -1.4253802911511571e+01 -1.5424425634403272e+01 -1.4219613607718578e+01 -1.0988129270893715e+01 -6.7271231240914489e+00 -2.8803629271713325e+00 -5.3221218228894118e-01 -1.4819897860306691e-01 -2.2309622192950278e+00 -6.7555441266626337e+00 -1.1288796495269558e+01 -1.1879369455774969e+01 -7.6695223775198915e+00 -2.7345250210875287e+00 -1.2464522929563033e+00 -2.5982520939275595e+00 -3.2907753012277650e+00 -2.0946248103194671e+00 -1.2670396502483379e+00 -2.9734875330694628e+00 -6.1944576306095183e+00 -8.0259110770747917e+00 -7.0406747672630017e+00 -4.3818830819913117e+00 -2.2337026899490038e+00 -1.7757039249321303e+00 -2.1690903031406541e+00 -1.7112483834128271e+00 -2.2443726961269805e-01 7.8312271984712389e-01 7.2340304513709708e-01 9.8143716696324113e-01 2.5456848227724063e+00 4.1446278797649949e+00 5.9509298374097952e+00 5.0678810528340978e+00 4.6985100256137695e+00 5.6806474798139019e+00 7.1270807068985986e+00 7.3896907513926973e+00 6.1956015245970972e+00 5.5852197604153861e+00 7.9143806050507850e+00 1.2903336221013145e+01 1.7478615210727796e+01 1.8733526717119613e+01 1.6557524998442712e+01 1.3237833414525580e+01 1.1194587213855545e+01 1.1742137197718762e+01 1.5292487123411739e+01 2.1089872768798958e+01 2.6615090233197662e+01 2.9112067948790987e+01 2.8381112807191901e+01 2.6745309556602031e+01 2.6230622139582557e+01 2.6873626067912664e+01 2.7379954661291766e+01 2.6724918542001461e+01 2.5352283105591539e+01 2.4558243711441179e+01 2.4278527981980282e+01 2.2429473534878777e+01 1.7501264178786681e+01 1.0987541340332779e+01 5.6451288588220212e+00 1.5426875751835269e+00 -4.2209755312065607e+00 -1.3196792287091672e+01 -2.2788705236686901e+01 -2.9082273423343587e+01 -3.1121693514905303e+01 -3.0849786691440926e+01 -2.9901975701231901e+01 -2.8187902353798506e+01 -2.4897002861955549e+01 -1.9629404309588349e+01 -1.3381778061564034e+01 -8.8077830839680740e+00 -8.0332756560395637e+00 -1.0120926859300432e+01 -1.2004163217689651e+01 -1.1842485990658060e+01 -1.0575962516702482e+01 -1.0149295488895902e+01 -1.0971618377841839e+01 -1.1645676947992518e+01 -1.0824020132311130e+01 -8.7473035146007145e+00 -6.7816366706045397e+00 -5.8695256679524599e+00 -6.1984801392743734e+00 -7.8537905857434129e+00 -1.0416960930281348e+01 -1.2429989647191839e+01 -1.2650740393840184e+01 -1.1521198276477271e+01 ] -} +) check(joinpath(dirname(@__FILE__), "big_endian.mat"), result) diff --git a/test/write.jl b/test/write.jl index 989834b..8088bf7 100644 --- a/test/write.jl +++ b/test/write.jl @@ -1,4 +1,5 @@ using MAT +using MAT.HDF5: @Dict tmpfile = string(tempname, ".mat") @@ -18,7 +19,7 @@ function test_write(data) end end -test_write({ +test_write(@Dict( "int8" => int8(1), "uint8" => uint8(1), "int16" => int16(1), @@ -30,56 +31,56 @@ test_write({ "single" => float32(1), "double" => float64(1), "logical" => true -}) +)) -test_write({ +test_write(@Dict( "Complex128" => [1.0 -1.0 1.0+1.0im 1.0-1.0im -1.0+1.0im -1.0-1.0im 1.0im], "ComplexPair" => [1 2-3im 4+5im] -}) -test_write({ "Complex128" => 1.0im, "ComplexPair" => 2-3im }) +)) +test_write(@Dict("Complex128" => 1.0im, "ComplexPair" => 2-3im)) -test_write({ +test_write(@Dict( "simple_string" => "the quick brown fox", "accented_string" => "thé qüîck browñ fòx", "concatenated_strings" => ["this is a string", "this is another string"], "cell_strings" => ["this is a string" "this is another string"], "empty_string" => "" -}) +)) -test_write({ +test_write(@Dict( "a1x2" => [1.0 2.0], "a2x1" => zeros(2, 1)+[1.0, 2.0], "a2x2" => [1.0 3.0; 4.0 2.0], "a2x2x2" => cat(3, [1.0 3.0; 4.0 2.0], [1.0 2.0; 3.0 4.0]), "empty" => zeros(0, 0), "string" => "string" -}) +)) -test_write({ +test_write(@Dict( "cell" => {1 2.01 "string" {"string1" "string2"}} -}) +)) -test_write({ - "s" => { +test_write(@Dict( + "s" => @Dict( "a" => 1.0, "b" => [1.0 2.0], "c" => [1.0 2.0 3.0] - }, - "s2" => { "a" => [1.0 2.0] } -}) + ), + "s2" => @Dict("a" => [1.0 2.0]) +)) -test_write({ +test_write(@Dict( "sparse_empty" => sparse(Array(Float64, 0, 0)), "sparse_eye" => speye(20), "sparse_logical" => SparseMatrixCSC{Bool,Int64}(5, 5, [1:6], [1:5], bitunpack(trues(5))), "sparse_random" => sparse([0 6. 0; 8. 0 1.; 0 0 9.]), "sparse_complex" => sparse([0 6. 0; 8. 0 1.; 0 0 9.]*(1. + 1.im)), "sparse_zeros" => SparseMatrixCSC(20, 20, ones(Int, 21), Int[], Float64[]) -}) +)) -@test_throws ErrorException test_write({ "1invalidkey" => "starts with a number" }) -@test_throws ErrorException test_write({ "another invalid key" => "invalid characters" }) -@test_throws ErrorException test_write({ "yetanotherinvalidkeyyetanotherinvalidkeyyetanotherinvalidkeyyetanotherinvalidkey" => "too long" }) +@test_throws ErrorException test_write(@Dict("1invalidkey" => "starts with a number")) +@test_throws ErrorException test_write(@Dict("another invalid key" => "invalid characters")) +@test_throws ErrorException test_write(@Dict("yetanotherinvalidkeyyetanotherinvalidkeyyetanotherinvalidkeyyetanotherinvalidkey" => "too long")) type TestCompositeKind field1::String @@ -90,7 +91,7 @@ close(fid) fid = matopen(tmpfile, "r") result = read(fid, "test") close(fid) -@assert result == { "field1" => "test value" } +@assert result == @Dict("field1" => "test value") fid = matopen(tmpfile, "w")