📄 bffio.m
字号:
);
end
end
% more strings
else
% verbose
if verbosemode
% loop over strings
try
for strc = 1:numel(towritedata)
verbosewritecstring( ...
fid, towritedata{strc}, ...
sprintf('%s{%d}', rexpr, strc));
end
catch
error( ...
'BVQXtools:WriteFailed', ...
'Writing to file failed: ''%s''.', ...
lasterr ...
);
end
% non-verbose
else
% loop over strings
try
for strc = 1:numel(towritedata)
fwrite(fid, ...
uint8(double(towritedata{strc})), ...
'uint8');
fwrite(fid, 0, 'uint8');
end
catch
error( ...
'BVQXtools:WriteFailed', ...
'Writing to file failed: ''%s''.', ...
lasterr ...
);
end
end
end
end
% end of 'if readfield, elseif writefield'
end
% skip N rules
case {'skipn'}
% extra check dim field
if ~all(prule.dim > 47 & prule.dim < 58)
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid SKIPN dim (N) given.' ...
);
end
% conditional skip
if ~isempty(rcond)
performskip = false;
try
eval(['if ' rcond ',performskip=true;end']);
catch
error( ...
'BVQXtools:EvaluationError', ...
'Error evaluating SKIPN condition: ''%s''.', ...
rcond ...
);
end
% if not skip, continue with next rule
if ~performskip
continue;
end
end
% get dim
nskipdim = str2double(prule.dim);
nskiptgt = rulec + nskipdim;
nskiplst = nskiptgt - 1;
% skip too high ?
if nskiplst > rules
error( ...
'BVQXtools:BadBFFSpec', ...
'Can''t skip %d rules at rule %d/%d.', ...
nskipdim, rulec, rules ...
);
end
% correctly leave any loops on our way
for trulec = rulec:nskiplst
% get shortcut for rule
tstruct = rule(trulec);
% eloop
switch (lower(tstruct.type)), case {'eloop'}
% matching with last entered loop
if ~strcmp(tstruct.varname, loopx{end})
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid LOOP (ELOOP) nesting found: ''%s''.', ...
tstruct.varname ...
);
end
% pop loop
loopi(end) = [];
loopx(end) = [];
loopc = loopc - 1;
end
end
% set new rulec
rulec = nskiptgt;
% exit of a loop
case {'xloop'}
% check name of ENTERED loops
if ~any(strcmp(rexpr, loopx))
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid XLOOP token found: ''%s''.', ...
rexpr ...
);
end
% check cond, whether loop has to be left
try
if isempty(rcond)
leaveloop = true;
else
eval([ ...
'leaveloop=false;if ' rcond ',leaveloop=true;end']);
end
catch
error( ...
'BVQXtools:EvaluationFailed', ...
'Error evaluating XLOOP condition: ''%s''.', ...
rcond ...
);
end
% if we're leaving loop
if leaveloop
% find loop to leave
leaveloop = find(strcmp(rexpr, loopx));
% set rulec to lastloop of this loop
rulec = loopi(leaveloop).lastrule;
% clear loopi and loopx, set loopc
loopi(leaveloop:end) = [];
loopx(leaveloop:end) = [];
loopc = leaveloop - 1;
end
% otherwise bail out
otherwise
error( ...
'BVQXtools:BadBFFSpec', ...
'Invalid rule type ''%s''.', ...
rtype ...
);
end
% increase next rule counter
rulec = rulec + 1;
end
% forcemode catch
catch % catch forcemode
if forcemode
% only warning
warning( ...
'BVQXtools:ForcedOverride', ...
'Forceing error override: ''%s''.', ...
lasterr ...
);
% otherwise
else
% simply don't allow this
rethrow(lasterror);
end
end % try forcemode
% AfterReadCode ?
if ~isempty(bffspec.AfterReadCode)
try
eval(bff_parsecode(bffspec.AfterReadCode(:)', 'namevars', 'bffcont'));
catch
error( ...
'BVQXtools:EvaluationError', ...
'Error raised by AfterReadCode: ''%s''.', ...
lasterr ...
);
end
end
% fclose on file
fclose(fid);
% print in verbosemode
if ~writemode && ...
verbosemode
disp(bffcont);
end
% give correct output
if ~writemode
varargout{1} = bffcont;
else
% rename file
try
succ = renamefile(wfilename, filename);
if succ ~= 0
error('MOVE_ERROR');
end
catch
error( ...
'BVQXtools:FileNotMovable', ...
'Error moving file ''%s'' to ''%s''.', ...
wfilename, filename ...
);
end
if nargout > 0
varargout{1} = bffcont;
if nargout > 1
varargout(2:nargout) = cell(1, nargout - 1);
end
end
end
% %%% subfunctions
function cstring = freadcstring(fid)
% initialize cstring to '' ('\0')
cstring = '';
% read first byte from stream
cnull = char(0);
cbyte = fread(fid, [1, 1], 'uint8=>char');
% continue reading until \0 is hit
while cbyte ~= cnull
% put character to end of string
cstring(end + 1) = char(cbyte);
% read next byte
cbyte = fread(fid, [1, 1], 'uint8=>char');
end
% end of function cstring = freadcstring(fid)
function readdata = verboseread(fid, rdim, rtype, target)
% make output
fpos = ftell(fid);
% read (at max) 16 bytes
vout = fread(fid, [1, 16], 'uint8=>double');
fseek(fid, fpos, -1);
% make output
disp(sprintf('0x%08X:%-48s -> %s (%s)', fpos, ...
sprintf(' %02X', vout), target, rtype));
% read data
readdata = reshape(fread(fid, [1, prod(rdim)], ['*' rtype]), rdim);
% print some data ?
if ~isempty(readdata)
disp(sprintf(' ->%s ...', ...
sprintf(' %d', double(readdata(1:min(8, numel(readdata)))))));
end
% end of function readdata = verboseread(fid, rdim, type)
function readdata = verbosereadcstring(fid, target)
% make output
fpos = ftell(fid);
% read (at max) 16 bytes
vout = fread(fid, [1, 16], 'uint8=>double');
fseek(fid, fpos, -1);
% make output
disp(sprintf('0x%08X:%-48s -> %s (%s)', fpos, ...
sprintf(' %02X', vout), target, 'cstring'));
% read data
readdata = freadcstring(fid);
% print some data
disp(sprintf(' -> %s...', readdata(1:min(60, numel(readdata)))));
% end of function readdata = verbosereadcstring(fid, rdim, target)
function verbosewrite(fid, wdata, wtype, target)
% make output
fpos = ftell(fid);
% write data
fwrite(fid, wdata, wtype);
% rewind to previous pos
if fseek(fid, fpos, -1) < 0
warning( ...
'BVQXtools:FileIOError', ...
'Error seeking to %d in file ID %d.', ...
fpos, fid ...
);
return;
end
% read at max 16 bytes
bdata = fread(fid, [1, 16], 'uint8=>double');
% and read at max 8 elements of type datatype
fseek(fid, fpos, -1);
tdata = fread(fid, [1, min(numel(wdata), 8)], [wtype '=>double']);
% go back to end of file
fseek(fid, 0, 1);
% make output
disp(sprintf('0x%08X:%-48s -> %s (%s)', fpos, ...
sprintf(' %02X', bdata), target, wtype));
% print some data ?
if ~isempty(tdata)
disp(sprintf(' ->%s ...', ...
sprintf(' %d', tdata(1:min(8, numel(tdata))))));
end
% end of function verbosewrite(fid, wdata, wtype, target)
function verbosewritecstring(fid, wstring, target)
% use verbosewrite(...)
verbosewrite(fid, uint8([double(wstring(:)'), 0]), target);
% end of function verbosewritecstring(fid, wstring, target)
function parsedcode = bff_parsecode(unparsed, nv, cnt)
% what pattern
if nargin > 2
pattern = '(\$|\@)([a-z][a-z_0-9]*)';
else
cnt = 'INVALID';
pattern = '(\$)([a-z][a-z_0-9]*)';
end
% find first occurance
[pcmt{1:3}] = regexpi(unparsed, pattern);
% loop until tokens are gone
while ~isempty(pcmt{3})
% what kind of token
pcmt = pcmt{3};
switch (unparsed(pcmt{1}(1, 1)))
% replace $var
case {'$'}
unparsed = [ ...
unparsed(1:pcmt{1}(1, 1) - 1) ...
nv '.' ...
unparsed(pcmt{1}(2, 1):end)];
% @var
case {'@'}
unparsed = [ ...
unparsed(1:pcmt{1}(1, 1) - 1) ...
cnt '.' ...
unparsed(pcmt{1}(2, 1):end)];
end
% rematch
[pcmt{1:3}] = regexpi(unparsed, pattern);
end
% any occurance of $$/@@
if nargin > 2
unparsed = strrep(unparsed, '@@', cnt);
end
parsedcode = strrep(unparsed, '$$', nv);
% end of function parsedcode = bff_parsecode(unparsed, nv, cnt)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -