Skip to content

Commit 3905f6d

Browse files
committed
HDF5: string/char read/write scalar/array
1 parent 63b1e8d commit 3905f6d

File tree

4 files changed

+46
-11
lines changed

4 files changed

+46
-11
lines changed

+stdlib/+hdf5nc/h5save.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ function new_file(filename, varname, A, sizeA)
7070
end
7171

7272
if isempty(sizeA)
73-
if isscalar(A) && ~isstring(A)
73+
if isscalar(A)
7474
h5_write_scalar(filename, varname, A)
7575
elseif isvector(A)
7676
h5create(filename, varname, length(A), 'DataType', class(A))
@@ -79,7 +79,7 @@ function new_file(filename, varname, A, sizeA)
7979
end
8080
else
8181
if isscalar(sizeA)
82-
if sizeA == 0 && ~isstring(A)
82+
if sizeA == 0
8383
h5_write_scalar(filename, varname, A)
8484
else
8585
h5create(filename, varname, sizeA, 'DataType', class(A))

+stdlib/+hdf5nc/private/coerce_ds.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@
3333
if ~isa(A, 'int64')
3434
A = int64(A);
3535
end
36-
case {'char', 'string'}
37-
if ~isstring(A)
38-
A = string(A);
39-
end
36+
case 'char'
37+
A = string(A);
38+
case 'string'
39+
% pass
4040
otherwise, error('create_ds:type_error', 'unknown data type %s', dtype)
4141
end
4242

+stdlib/+hdf5nc/private/h5_write_scalar.m

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,20 @@ function h5_write_scalar(filename, varname, A)
1212
create_hdf5_group(fid, varname);
1313

1414
space_id = H5S.create('H5S_SCALAR');
15-
t = class2h5t(A);
16-
type_id = H5T.copy(t);
15+
if isstring(A)
16+
A = char(A);
17+
end
18+
if ischar(A)
19+
type_id = H5T.copy('H5T_C_S1');
20+
H5T.set_cset(type_id, H5ML.get_constant_value('H5T_CSET_UTF8'));
21+
H5T.set_size(type_id, 'H5T_VARIABLE');
22+
H5T.set_strpad(type_id, 'H5T_STR_NULLTERM');
23+
else
24+
type_id = H5T.copy(class2h5t(A));
25+
end
26+
1727
dset_id = H5D.create(fid, varname, type_id, space_id, dcpl);
28+
1829
H5D.write(dset_id,'H5ML_DEFAULT','H5S_ALL','H5S_ALL', dcpl, A);
1930

2031
H5S.close(space_id);

+stdlib/TestHDF5.m

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,16 @@ function setup_file(tc)
2323
A3 = A2(:,1:3,1);
2424
A3(:,:,2) = 2*A3;
2525
A4(:,:,:,5) = A3;
26+
utf = 'Hello There 😄';
27+
utf2 = [utf; ""];
2628

2729
tc.TestData.A0 = A0;
2830
tc.TestData.A1 = A1;
2931
tc.TestData.A2 = A2;
3032
tc.TestData.A3 = A3;
3133
tc.TestData.A4 = A4;
34+
tc.TestData.utf = utf;
35+
tc.TestData.utf2 = utf2;
3236

3337
basic = tempname + ".h5";
3438
tc.TestData.basic = basic;
@@ -39,6 +43,8 @@ function setup_file(tc)
3943
h5save(basic, '/A2', A2)
4044
h5save(basic, '/A3', A3, "size", size(A3))
4145
h5save(basic, '/A4', A4)
46+
h5save(basic, "/utf", utf)
47+
h5save(basic, "/utf2", utf2)
4248

4349
h5save(basic, '/t/x', 12)
4450
h5save(basic, '/t/y', 13)
@@ -73,7 +79,7 @@ function test_get_variables(tc)
7379
basic = tc.TestData.basic;
7480

7581
v = h5variables(basic);
76-
tc.verifyEqual(sort(v), ["A0", "A1", "A2", "A3", "A4"])
82+
tc.verifyEqual(sort(v), ["A0", "A1", "A2", "A3", "A4", "utf", "utf2"])
7783

7884
[v1,g] = h5variables(basic);
7985
tc.verifyEqual(v,v1)
@@ -145,6 +151,15 @@ function test_size(tc)
145151
tc.verifyEqual(s, [4,3,2,5])
146152
tc.verifyEqual(r, 4)
147153

154+
r = h5ndims(basic, '/utf');
155+
s = h5size(basic, '/utf');
156+
tc.verifyEmpty(s)
157+
tc.verifyEqual(r, 0)
158+
159+
r = h5ndims(basic, '/utf2');
160+
s = h5size(basic, '/utf2');
161+
tc.verifyEqual(s, 2)
162+
tc.verifyEqual(r, 1)
148163
end
149164

150165

@@ -153,7 +168,7 @@ function test_read(tc)
153168

154169
s = h5read(basic, '/A0');
155170
tc.verifyTrue(isscalar(s))
156-
tc.verifyEqual(s, 42)
171+
tc.verifyEqual(s, tc.TestData.A0)
157172

158173
s = h5read(basic, '/A1');
159174
tc.verifyTrue(isvector(s))
@@ -170,6 +185,15 @@ function test_read(tc)
170185
s = h5read(basic, '/A4');
171186
tc.verifyEqual(ndims(s), 4)
172187
tc.verifyEqual(s, tc.TestData.A4)
188+
189+
s = h5read(basic, '/utf');
190+
tc.verifyTrue(ischar(s))
191+
tc.verifyEqual(s, tc.TestData.utf)
192+
193+
s = h5read(basic, '/utf2');
194+
tc.verifyTrue(isstring(s))
195+
tc.verifyEqual(s, tc.TestData.utf2)
196+
173197
end
174198

175199

@@ -222,7 +246,7 @@ function test_string(tc, str)
222246
h5save(basic, "/"+str, str)
223247

224248
a = h5read(basic, "/"+str);
225-
tc.verifyEqual(a, string(str))
249+
tc.verifyEqual(a, char(str))
226250
end
227251

228252
function test_name_only(tc)

0 commit comments

Comments
 (0)