Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 26 additions & 15 deletions +io/+backend/+base/Writer.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,6 @@
ObjectIdToPathMap
end

properties (Dependent, SetAccess = private, Hidden)
FileId
end

methods
function obj = Writer(filename)
if nargin < 1
Expand Down Expand Up @@ -109,6 +105,32 @@ function copyDatasetFromFile(obj, sourceFilename, sourcePath, destinationPath) %
io.backend.base.Writer.throwNotImplemented("copyDatasetFromFile")
end

function writtenPipe = exportDataPipe(obj, dataPipe, destinationPath) %#ok<INUSD>
% exportDataPipe - Write a DataPipe's dataset into this file.
%
% Writes the dataset held by dataPipe at destinationPath, honouring
% the pipe's storage configuration (chunking, compression and the
% other pipe properties). Returns the pipe state representing the
% dataset as written; DataPipe.export stores it as the pipe's new
% internal state, which is how an in-memory blueprint pipe becomes
% bound to the dataset in this file. A pipe already bound to a
% dataset in this file is left in place. A pipe bound to a dataset
% in a different file holds only a reference to that data, not the
% data itself, so exporting it raises an error
% ('NWB:BoundPipe:CannotExportToNewFile').
%
% Input Arguments:
% obj - Writer instance targeting the destination file.
% dataPipe - types.untyped.DataPipe whose dataset is written.
% destinationPath - Path the dataset is written to in this file.
%
% Output Arguments:
% writtenPipe - Pipe object bound to the dataset as written.

writtenPipe = [];
io.backend.base.Writer.throwNotImplemented("exportDataPipe")
end

function writeSoftLink(obj, linkPath, targetPath) %#ok<INUSD>
% writeSoftLink - Create a link to another location in this file.
%
Expand Down Expand Up @@ -186,10 +208,6 @@ function close(obj) %#ok<MANU>
function abort(obj)
obj.close();
end

function fileId = get.FileId(obj)
fileId = obj.getFileId();
end
end

methods (Static)
Expand All @@ -203,13 +221,6 @@ function abort(obj)
end
end

methods (Access = protected)
function fileId = getFileId(obj) %#ok<MANU>
io.backend.base.Writer.throwNotImplemented("getFileId")
fileId = [];
end
end

methods (Static, Access = private)
function throwNotImplemented(methodName)
error("NWB:Backend:Writer:NotImplemented", ...
Expand Down
14 changes: 9 additions & 5 deletions +io/+backend/+hdf5/HDF5Writer.m
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ function copyDatasetFromFile(obj, sourceFilename, sourcePath, destinationPath)
H5F.close(src_fid);
end

function writtenPipe = exportDataPipe(obj, dataPipe, destinationPath)
% The pipe internals (BoundPipe/BlueprintPipe) drive H5P/H5D
% directly for chunking, compression, dynamic filters and
% extendable datasets, so they legitimately consume a raw HDF5
% file id. Keeping this call inside the HDF5 writer means the
% raw id never crosses the backend interface.
writtenPipe = dataPipe.internal.write(obj.H5FileId, destinationPath);
end

function writeSoftLink(obj, linkPath, targetPath)
io.internal.h5.writeLink(obj.H5FileId, linkPath, "soft", targetPath);
end
Expand Down Expand Up @@ -168,11 +177,6 @@ function deleteGroup(obj, groupPath)
end
end

methods (Access = protected)
function fileId = getFileId(obj)
fileId = obj.H5FileId;
end
end
end

function hasReference = isCompoundWithReference(src_tid)
Expand Down
1 change: 1 addition & 0 deletions +tests/+unit/+io/+backend/+base/BaseWriterTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"writeExternalLink", ...
"validateReferenceResolvable", ...
"copyDatasetFromFile", ...
"exportDataPipe", ...
"getEmbeddedSpecLocation", ...
"listChildGroupNames", ...
"registerWrittenObjectId", ...
Expand Down
2 changes: 1 addition & 1 deletion +tests/+unit/+io/+backend/HDF5WriterTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function deleteGroupDeletesPopulatedGroup(testCase)

writer.deleteGroup('/specifications/core');

groupExists = H5L.exists(writer.FileId, ...
groupExists = H5L.exists(writer.H5FileId, ...
'/specifications/core', 'H5P_DEFAULT');
testCase.verifyFalse(logical(groupExists));
end
Expand Down
2 changes: 1 addition & 1 deletion +types/+untyped/DataPipe.m
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@

function refs = export(obj, writer, fullpath, refs)
writer = io.backend.base.Writer.ensure(writer);
obj.internal = obj.internal.write(writer.FileId, fullpath);
obj.internal = writer.exportDataPipe(obj, fullpath);
end

%% Display
Expand Down
Loading