diff --git a/src/hdf5_hl.ts b/src/hdf5_hl.ts index 4feda52..4453c76 100644 --- a/src/hdf5_hl.ts +++ b/src/hdf5_hl.ts @@ -208,6 +208,30 @@ function process_data(data: Uint8Array, metadata: Metadata, json_compatible: boo return output_data; } + else if (type === Module.H5T_class_t.H5T_VLEN.value) { + // Data buffer holds HDF5 `hvl_t` struct + // https://docs.hdfgroup.org/hdf5/v1_12/structhvl__t.html + const ptr_pairs = new Uint32Array(data.buffer); // both `size_t` length and pointer are 4-byte-long + const num_ptrs = ptr_pairs.length / 2; + const vlen_type = metadata.vlen_type as Metadata; + const { size } = vlen_type; + + let output: (OutputData | JSONCompatibleOutputData)[] = []; + for (let p = 0; p < num_ptrs; p += 1) { + const length = ptr_pairs[p * 2]; // number of elements in this vlen array + const data_ptr = ptr_pairs[p * 2 + 1]; // pointer to this vlen array's data + + // Read vlen array data from memory + const data_nbytes = length * size; + const data = Module.HEAPU8.slice(data_ptr, data_ptr + data_nbytes); + + // Process this vlen array's data according to base datatype + output.push(process_data(data, { ...vlen_type, shape: [length] }, json_compatible)); + } + + output_data = output; + } + else { known_type = false; output_data = data; @@ -948,7 +972,7 @@ export class Dataset extends HasAttrs { let data = Module.HEAPU8.slice(data_ptr, data_ptr + nbytes); processed = process_data(data, metadata, false); } finally { - if (metadata.vlen) { + if (metadata.vlen || metadata.type === Module.H5T_class_t.H5T_VLEN.value) { Module.reclaim_vlen_memory(this.file_id, this.path, "", BigInt(data_ptr)); } Module._free(data_ptr); diff --git a/test/vlen_test.mjs b/test/vlen_test.mjs index e291893..a6e552a 100644 --- a/test/vlen_test.mjs +++ b/test/vlen_test.mjs @@ -44,6 +44,16 @@ async function vlen_test() { vlen: false, }, }); + + assert.deepEqual(f.get('int8_scalar').value, new Int8Array([0, 1])); + assert.deepEqual( + f.get('float32_oneD').value, + [ + new Float32Array([0]), + new Float32Array([0, 1]), + new Float32Array([0, 1, 2]) + ] + ); } export const tests = [