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

📄 bvqxinifile.m

📁 toolbox of BVQX, This is the access between BV and matlab. It will help you to analysis data from BV
💻 M
📖 第 1 页 / 共 5 页
字号:
function [varargout] = BVQXinifile(varargin)
% BVQXinifile (class)
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Version:      v0.7b
% Build:        7090311
% Date:         Sep-03 2007, 11:17 AM CEST
% Author:       Jochen Weber, Brain Innovation, B.V., Maastricht, NL
% URL / Info:   http://wiki.brainvoyager.com/BVQXtools
%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% creates an object for ini-file handling
%
% Input: for meaningful object construction, give filename!
%
% ___ Constructor methods: ___
% ----------------------------
%
% BVQXinifile           returns a handle to an BVQXinifile object
%       FORMAT:         IniFileObject = BVQXinifile(Filename [,convert]);
%       FORMAT:         NewObject = BVQXinifile('convert' | 'new');
%       FORMAT:         FactoryObject = BVQXinifile;
%
% ReleaseAllFiles       issue release for all open objects
% ReloadAllFiles        issue reload for all open objects
% ResetClass            resets the internal variable, useful for debugging
% SetIniString          create an IniFile object from an inistring
%
% ___ NOTES: ___
% --------------
%
%  *)   with conversion active, BVQXinifile uses any2ascii, another part
%       of this toolbox to write non-character variables to disk;
%       when not active, only valid one-line char arrays are allowed!
%
%  **)  storage for the ini file settings is NOT part of the object, but
%       is requested and maintained by the singleton object itself, thus
%       only little memory is needed for argument handling, even with
%       bigger ini file, plus multiple functions can share one ini file!

% persistent storage for BVQXinifile object and factory variables
persistent bvqxinic;
persistent bvqxinif;

% bvqxinic              internal object with subfields
%    .caller            who opened this file initially
%    .children          internal list of file-IDs that depend on this file
%    .convert           is the content converted (evaled/hxdouble'd)
%    .filename          holds the filename (or a temporary name)
%    .icontent          content of the file as struct representation
%    .parent            either empty or internal file-ID of parent file
%    .postfile          string of characters after terminating sequence
%    .prefile           string of characters before first section
%    .readwrite         single character option for write protection,
%                       whereas 'a' stands for all, 'c' for caller,
%                       'm' for memory-only, and 'n' for no write access
%
% bvqxinif              factory object with subfields
%    .fterm             ini-file terminator
%    .is_init           initialization complete flag
%    .lineout           configurable line break character sequence
%    .matrix            ID lookup table
%    .raction           read-only actions
%    .uaction           list of actions that don't need a valid ID
%    .waction           write-file actions

% check for class initialization -> do if necessary
if isempty(bvqxinif) || ...
   ~bvqxinif.is_init

    % configuration settings
    bvqxinif.fterm = '[/EndOfBVQXinifile]';
    bvqxinif.is_init = false;
    bvqxinif.lineout = char(10);
    bvqxinif.matrix = [];

    % array of read-only actions for protection scheme
    bvqxinif.raction = struct( ...
        'display',            true, ...
        'getcaller',          true, ...
        'getchildren',        true, ...
        'getcomplete',        true, ...
        'getfilename',        true, ...
        'getfoot',            true, ...
        'gethead',            true, ...
        'getid',              true, ...
        'getinisection',      true, ...
        'getinisetting',      true, ...
        'getinistring',       true, ...
        'getparents',         true, ...
        'getprotection',      true, ...
        'getsections',        true, ...
        'getsectionsettings', true, ...
        'issection',          true, ...
        'issetting',          true, ...
        'isvalid',            true  ...
    );
    
    % array of available actions for calls with object ID = 0
    bvqxinif.uaction = struct( ...
        'display',         true, ...
        'isvalid',         true, ...
        'loadinifile',     true, ...
        'newinifile',      true, ...
        'parseinistring',  true, ...
        'releaseallfiles', true, ...
        'reloadallfiles',  true, ...
        'resetclass',      true  ...
    );
    
    % array of file-write actions for protection scheme
    bvqxinif.waction = struct( ...
        'saveinifile',   true, ...
        'saveinifileas', true  ...
    );
    
    % initialize object structure
    bvqxinic = struct(    ...
        'caller'   , '',     ...
        'children' , [],     ...
        'convert'  , 0,      ...
        'filename' , '',     ...
        'icontent' , struct, ...
        'parent'   , [],     ...
        'postfile' , '',     ...
        'prefile'  , '',     ...
        'readwrite', 'a'     ...
    );
    
    % set initialization successful to true
    bvqxinif.is_init = true;
    
    % and get factory handle
    bvqxinif.xhfactory = class(struct('L', 0), 'BVQXinifile');
end
hf = bvqxinif.xhfactory;

% if no arguments given return factory
if nargin < 1

    % initialize basic return object and return
    varargout{1} = hf;
    return;
end

% input argument check
if nargin < 3 && ...
   ~isa(varargin{1}, 'BVQXinifile')

    % first is string
    if ischar(varargin{1}) && ...
       ~isempty(varargin{1})

        % but no filename...
        if exist(varargin{1}(:)','file') ~= 2

            % if it is neither 'convert', 'exact', or 'new'
            if ~any(strcmpi(varargin{1}(:)', {'convert', 'exact', 'new'}))
                error( ...
                    'BVQXinifile:FileNotFound', ...
                    'The specified file wasn''t found.' ...
                );

            % assume NewIniFile constructor meaning
            else
                varargout{1} = ...
                    BVQXinifile(hf, 'newinifile', lower(varargin{1}(:)'));
                return;
            end
        end

        % perform filename call
        varargout{1} = BVQXinifile(hf, 'loadinifile', varargin{:});
        return;
        
    % if we get a numeric argument...
    elseif isa(varargin{1}, 'double') && ...
        numel(varargin{1}) == 1
        
        % is an object in list
        if any(bvqxinif.matrix == varargin{1})
            varargout{1} = class(struct('L', varargin{1}), 'BVQXinifile');
            return;
            
        % give an error otherwise
        else
            error( ...
                'BVQXinifile:InvalidFileID', ...
                'The given ID wasn''t found in the lookup matrix.' ...
            );
        end
    end

% otherwise bark out if first argument in NOT an BVQXinifile object
elseif ~isa(varargin{1}, 'BVQXinifile') || ...
    numel(varargin{1}) ~= 1 || ...
    nargin < 2 || ...
   ~ischar(varargin{2})
    error( ...
        'BVQXinifile:CallingConvention', ...
        'Illegal call to BVQXinifile.' ...
    );
end
hIniFile = varargin{1};
action = lower(varargin{2}(:)');
varargout{1} = hIniFile;

% get ID and look up the matrix position of file...
cfid = hIniFile.L;
if cfid ~= 0
    cfid = find(bvqxinif.matrix == cfid);
    if isempty(cfid)
        if ~strcmp(action, 'isvalid')
            error( ...
                'BVQXinifile:InvalidFileID', ...
                'File lookup error. Possible programming error?' ...
            );
        else
            varargout{1} = false;
            return;
        end
    end
end

% disallow all actions that do need a "vadid" ID
if ~isfield(bvqxinif.uaction, action) && ...
    cfid == 0
    error( ...
        'BVQXinifile:InvalidAction', ...
        'The requested action needs a valid object to work.' ...
    );
end

% get current object
if cfid > 0
    cfile = bvqxinic(cfid);

    % check protection first
    switch cfile.readwrite

        % only caller
        case {'c'}

            % test caller / action pair
            ncaller = extcaller(1);
            ocaller = cfile.caller;
            if ~isfield(bvqxinif.raction, action) && ...
               ~strcmp(ncaller, ocaller)
                warning( ...
                    'BVQXinifile:ProtectionViolation', ...
                    'The object has ''caller-only'' write access.' ...
                );
                return;
            end

        % file protection only
        case {'m'}

            % test for writefile action strings
            if isfield(bvqxinif.waction, action)
                warning( ...
                    'BVQXinifile:ProtectionViolation', ...
                    'The object has ''memory-only'' write access.' ...
                );
                return;
            end

        % no write access at all
        case {'n'}

            % test for read-only action string
            if ~isfield(bvqxinif.raction, action)
                warning( ...
                    'BVQXinifile:ProtectionViolation', ...
                    'The object has write access disabled.' ...
                );
                return;
            end
    end
end

%  switch over action
switch (action)
    
    % display (also used for writing!)
    case {'display'}
    
        % initialize output variable
        lineout = bvqxinif.lineout;
        dispout = '';
        filepost = '';
        indent = '   ';
        equalchar = ' = ';

        % if we have a valid object ID (other than the factory)
        if cfid > 0

            % get conversion state
            tconvert = cfile.convert;
            issave = false;

            % if we're going to write the file to disk reset some vars!
            if nargin > 2 && ...
                ischar(varargin{3}) && ...
                strcmpi(varargin{3}(:)', 'saveinifile')
                dispout = cfile.prefile(:)';
                filepost = cfile.postfile(:)';
                indent = '';
                equalchar = '=';
                lineout = char([13, 10]);
                issave = true;

                % make sure to add correct footer if is invalid or empty
                if ~ischar(filepost) || ...
                    numel(filepost) < 1
                    filepost = [bvqxinif.fterm lineout];
                end

                % do we have a correct footer now?
                hasend = strfind(filepost,bvqxinif.fterm);
                if isempty(hasend)
                    filepost = [bvqxinif.fterm lineout filepost];

                % remove any leading chars before good terminator
                elseif hasend(1) ~= 1
                    filepost(1:(hasend(1)-1)) = [];
                end
            end

            % correctly terminate header and footer
            if numel(dispout) > 0 && ...
                dispout(end) ~= char(10) && ...
                dispout(end) ~= char(13)
                dispout = [dispout lineout];
            end
            if numel(filepost) > 0 && ...
                filepost(end) ~= char(10) && ...
                filepost(end) ~= char(13)
                filepost = [filepost lineout];
            end

            % iterate over sections
            cfs = fieldnames(cfile.icontent);
            for sectcount = 1:numel(cfs)

                % initialize section output
                sdispout = '';
                extralarge = {};

                % get section name and content, and add name to dispout
                sectname = cfs{sectcount};
                csection = cfile.icontent.(cfs{sectcount});
                sdispout = [sdispout '[' sectname ']' lineout];

                % re-set non-structs
                if ~isstruct(csection)
                    if ~iscell(csection)
                        csection = struct('Value', csection);
                    else
                        csection = struct('Value', {csection});
                    end
                end

                % iterate over settings in section
                namsettings = fieldnames(csection);
                for namecount = 1:numel(namsettings)

                    % get value for setting
                    fvalue = csection.(namsettings{namecount});

                    % do we have non character, invalid characters or not 1xN
                    if tconvert < 1 && ...
                       (~ischar(fvalue) || ...
                        any(fvalue < 32 | fvalue > 127) || ...
                        size(fvalue, 1) > 1 || ...
                        ndims(fvalue) > 2)
                        if issave
                            error( ...
                                'BVQXinifile:BadSettingValue', ...
                                'Bad value for %s.%s (no conversion).', ...
                                sectname, ...
                                namsettings{namecount} ...
                            );
                        else
                            warning( ...
                                'BVQXinifile:BadSettingValue', ...
                                'Bad value for %s.%s (no conversion).', ...
                                sectname, ...

⌨️ 快捷键说明

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