⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bffparse.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
📖 第 1 页 / 共 3 页
字号:
function bffspec = bffparse(bffcont)
% bffparse  - parse BFF binary file format description
%
% FORMAT:       bffspec = bffparse(bffcont)
%
% Input fields:
%
%       bffcont     1xN char: BFF specification file name or content
%
% Output fields:
%
%       bffspec     1x1 struct with BFF specification
%
% See also bffdocu, bffio

% Version:  v0.7b
% Build:    7083014
% Date:     Aug-30 2007, 2:51 PM CEST
% Author:   Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

bffversion = 'v0.7b';
default_tiosize = Inf;

% create persistent datatype sizes struct if needed
persistent bff_dtsize;
if isempty(bff_dtsize)
    bff_dtsize = struct( ...
        'double', 8, ...
        'int16',  2, ...
        'int32',  4, ...
        'int64',  8, ...
        'int8',   1, ...
        'single', 4, ...
        'uchar',  1, ...
        'uint16', 2, ...
        'uint32', 4, ...
        'uint64', 8, ...
        'uint8',  1  ...
    );
end

% argument check
if nargin < 1 || ...
   ~ischar(bffcont) || ...
    isempty(bffcont)
    error( ...
        'BVQXtools:BadArgument', ...
        'Invalid BFF specification argument given.' ...
    );
end

% check for line feeds and try to read file
if ~any(bffcont == char(10))
    if exist(bffcont, 'file') ~= 2
        error( ...
            'BVQXtools:FileNotFound', ...
            'Either invalid content or file not found.' ...
        );
    end

    % read bffspec
    try
        bffcont = asciiread(bffcont);
    catch
        rethrow(lasterror);
    end
end

% check content
if isempty(strfind(bffcont, 'BinaryFileFormat'))
    error( ...
        'BVQXtools:BadBFFSpec', ...
        'Invalid BFF specification file/content given.' ...
    );
end

% split into lines
bfflines = splittocell(bffcont(:)', char([10, 13]), 1, 1);

% remove empty ones and comments
for lc = length(bfflines):-1:1

    % deblank lines
    bffline = deblank(bfflines{lc});

    % remove comment
    bffcomm = find(bffline == '#');
    if ~isempty(bffcomm)
        bffline(bffcomm(1):end) = [];
        bfflines{lc} = bffline;
    end

    % if is empty, remove line
    if isempty(bffline)
        bfflines(lc) = [];
        continue;
    end
end

% initialize content
bffspec = struct;
bffspec.FFTYPE          = 'BFF';
bffspec.BFFVERSION      = bffversion;
bffspec.AfterReadCode   = '';
bffspec.BeforeWriteCode = '';
bffspec.Description     = 'All files';
bffspec.EncodingSyntax  = 'native';
bffspec.Extensions      = {};
bffspec.FilenameMatch   = {};
bffspec.Filetype        = 'Custom BFF file';
bffspec.ListOfFields    = cell2struct(cell(0,0,0), {}, 3);
bffspec.Loops           = struct;
bffspec.Magic           = cell2struct(cell(0,0,0), {}, 3);
bffspec.NewFileCode     = '';
bffspec.TransIOSize     = default_tiosize;
bffspec.Variables       = struct;

% parse content
lc  = 1;
llc = length(bfflines);
while (lc <= llc)

    % regexpi line matches '<TOKEN>:<VALUE>' ?
    bffline = bfflines{lc};
    [tlmatcht{1:3}] = regexpi( ...
        bffline, '^([a-z][a-z_0-9]*)\:\s*(.*)\s*$');
    tlmatcht = tlmatcht{3};

    % continue with next line if no match
    lc = lc + 1;
    if isempty(tlmatcht)
        continue;
    end

    % handle those sections/keywords:
    bffkey = bffline(tlmatcht{1}(1, 1):tlmatcht{1}(1, 2));
    bffval = bffline(tlmatcht{1}(2, 1):tlmatcht{1}(2, 2));
    switch (lower(bffkey))

        % after read code snippet
        case {'afterreadcode'}

            % find "EndAfterReadCode"
            endline = llc + 1;
            for slc = lc:llc
                if ~isempty(regexpi(bfflines{slc}, '^endafterreadcode'))
                    endline = slc - 1;
                    break;
                end
            end

            % check endline
            if endline > llc
                error( ...
                    'BVQXtools:BadBFFSpec', ...
                    'Unclosed AfterReadCode section in BFF spec.' ...
                );
            end

            % generate and check code snippet
            codesnip  = gluetostring(bfflines(lc:endline), char(10), 1);
            tcodesnip = codesnip;
            tcodesnip(tcodesnip == '$' | tcodesnip == '@') = [];
            try
                eval(['if 1==0,' tcodesnip ';end']);
            catch
                error( ...
                    'BVQXtools:BadBFFSpec', ...
                    'Syntax error detected in AfterReadCode: ''%s''.', ...
                    lasterr ...
                );
            end

            % store code
            bffspec.AfterReadCode = codesnip;

        % before write code snippet
        case {'beforewritecode'}

            % find "EndBeforeWriteCode"
            endline = llc + 1;
            for slc = lc:llc
                if ~isempty(regexpi(bfflines{slc}, '^endbeforewritecode'))
                    endline = slc - 1;
                    break;
                end
            end

            % check endline
            if endline > llc
                error( ...
                    'BVQXtools:BadBFFSpec', ...
                    'Unclosed BeforeWriteCode section in BFF spec.' ...
                );
            end

            % generate and check code snippet
            codesnip  = gluetostring(bfflines(lc:endline), char(10), 1);
            tcodesnip = codesnip;
            tcodesnip(tcodesnip == '$' | tcodesnip == '@') = [];
            try
                eval(['if 1==0,' tcodesnip ';end']);
            catch
                error( ...
                    'BVQXtools:BadBFFSpec', ...
                    'Syntax error detected in BeforeWriteCode: ''%s''.', ...
                    lasterr ...
                );
            end

            % store code
            bffspec.BeforeWriteCode = codesnip;

        % file open description
        case {'description'}
            bffspec.Description = splittocell(bffval, ';,', 1, 1);

        % encoding syntax
        case {'encodingsyntax'}
            bffspec.EncodingSyntax = bffval;

        % valid extensions list
        case {'extensions'}
            bffspec.Extensions = splittocell(bffval, ';,. ', 1, 1);

        % valid extensions list
        case {'filenamematch'}
            bffspec.FilenameMatch = splittocell(bffval, ';, ', 1, 1);

        % list of fields
        case {'listoffields'}

            % find "EndListOfFields" line
            endline = llc + 1;
            for slc = (lc + 1):llc
                if ~isempty(regexpi(bfflines{slc}, '^endlistoffields'))
                    endline = slc - 1;
                    break;
                end
            end
            blc = lc;
            lc = endline + 1;

            % invalid ListOfFields
            if lc > llc
                error( ...
                    'BVQXtools:BadBFFSpec', ...
                    'Unclosed or bad ListOfFields block.' ...
                );
            end

            % list/table field separator
            listsep = bffval;

            % get rule headers
            rhead = splittocell(bfflines{blc}, listsep, 0);

            % build header struct
            hstruct = struct;
            for hfc = 1:length(rhead)
                hfield = lower(makelabel(rhead{hfc}));
                hstruct.(hfield) = hfc;
                rhead{hfc} = hfield;
            end
            blc = blc + 1;

            % bail out if invalid header given
            if ~isfield(hstruct, 'type') || ...
               ~isfield(hstruct, 'cond') || ...
               ~isfield(hstruct, 'disktype') || ...
               ~isfield(hstruct, 'datatype') || ...
               ~isfield(hstruct, 'dim') || ...
               ~isfield(hstruct, 'default') || ...
               ~isfield(hstruct, 'varname')
                warning( ...
                    'BVQXtools:BadBFFSpec', ...
                    'ListOfFields with bad headers.' ...
                );
                continue;
            end

            % get list of header field names (in their order)
            hfields = fieldnames(hstruct);
            nfields = length(hfields);

            % build empty field list struct
            frules = cell2struct(cell(1, 1, nfields), hfields, 3);
            frules.disksize = 0;
            frules(1) = [];

            % check global fieldlist struct
            tfields = fieldnames(bffspec.ListOfFields);

            % no rules yet -> OK
            if isempty(tfields)
                bffspec.ListOfFields = frules;

            % otherwise compare header fields
            else

                % assume no mismatch
                headermismatch = false;

                % check number of fields
                if length(tfields) ~= length(fieldnames(frules))
                    headermismatch = true;
                else

                    % only if still content in tfields, check names
                    for tfc = 1:nfields
                        if ~strcmp(tfields{tfc}, hfields{tfc})
                            headermismatch = true;
                            break;
                        end
                    end
                end

                % if mismatch give warning and continue with next block
                if headermismatch
                    warning( ...
                        'BVQXtools:BadBFFSpec', ...
                        'ListOfFields blocks must match in their headers.' ...
                    );
                    continue;
                end
            end

            % build list of rules to consider
            actrules = frules;
            for slc = blc:endline

                % split to fields
                rcont = splittocell(bfflines{slc}, listsep, 0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -