1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
function SM = StreamMaker()
% StreamMaker (Factory for fie/input/output Streams)
%
% A StreamMaker can make Stream PseudoObjects based on either
% an "fid" or "filename" (and extra arguments for `fopen`).
% The StreamMaker also contains a method `isStream` to validate whether
% the value passed is a valid stream specifier.
%
% Usage
%
% SM = StreamMaker;
%
% Stream = SM.make(fid)
% Stream = SM.make(filename, ...)
%
% This returns a PseudoObject Stream with the following properties:
% - name: (file) name of the stream
% - fid: handle (fid) of the stream
%
% and methods:
% - print: prints to the stream, i.e. fprintf
% - close: closes the stream, i.e. fclose
%
% It may also contain a field to automatically close the Stream when it goes
% out of scope.
%
SM = PseudoObject('StreamMaker', ...
'isStream', @isStream, ...
'make', @constructStream);
end
function PseudoObj = PseudoObject(T, varargin)
% construct a Pseudo-Object with type T (no other fields yet)
PseudoObj = struct('Type', T, varargin{:});
end
function bool = isStream(value)
bool = ischar(value) || ismember(value, [1,2,fopen('all')]);
%TODO: allow others kinds of streams
% Stream -> clipboard (write on close)
% Stream -> string variable
% e.g. a quick-and-dirty way would be to write the file to `tempname`
% putting a flag to read that file back upon completion.
end
function Stream = constructStream(streamSpecifier, varargin)
% this is the actual constructor of a stream
if ~isStream(streamSpecifier)
error('StreamMaker:NotAStream', 'Invalid stream specifier "%s"', ...
streamSpecifier);
end
Stream = PseudoObject('Stream');
closeAfterUse = false;
if ischar(streamSpecifier)
Stream.name = streamSpecifier;
Stream.fid = fopen(Stream.name, varargin{:});
closeAfterUse = true;
elseif isnumeric(streamSpecifier)
Stream.fid = streamSpecifier;
Stream.name = fopen(Stream.fid);
end
if Stream.fid == -1
error('Stream:InvalidStream', ...
'Unable to create stream "%s"!', streamSpecifier);
end
Stream.print = @(varargin) fprintf(Stream.fid, varargin{:});
Stream.close = @() fclose(Stream.fid);
if closeAfterUse
Stream.closeAfterUse = onCleanup(Stream.close);
end
end
|