245 lines
7.9 KiB
Matlab
245 lines
7.9 KiB
Matlab
classdef ini < handle
|
|
% Low-level utilities for INI files.
|
|
properties (Access = public)
|
|
File % file name
|
|
IOMode % file opened in read-only or read-write mode?
|
|
FileSize % file size
|
|
NumSection % maximum number of datasets in this file (over all time steps)
|
|
Verbosity % verbose output?
|
|
end
|
|
%%
|
|
properties (Access = private)
|
|
% File info
|
|
fileID
|
|
fileBeg
|
|
fileEnd
|
|
ioflag
|
|
tarflag
|
|
content
|
|
end
|
|
%% ------------------------------------------------------------------------%%
|
|
%% CONSTRUCORS/DESTRUCTORS %%
|
|
%% ------------------------------------------------------------------------%%
|
|
methods (Access = public)
|
|
function obj = ini(varargin)
|
|
% [obj] = ini(varargin)
|
|
% Default contructor
|
|
% Input
|
|
% ? verbosity verbose output? (default: no)
|
|
par = inputParser;
|
|
addParamValue(par,'verbosity',0,@isnumeric);
|
|
parse(par,varargin{:});
|
|
obj.resetPublicProperties();
|
|
obj.resetPrivateProperties();
|
|
obj.fileID = -1;
|
|
obj.tarflag = false;
|
|
obj.setVerbosity(par.Results.verbosity);
|
|
end
|
|
function delete(obj)
|
|
% obj.delete()
|
|
% Object destructor
|
|
obj.close();
|
|
end
|
|
end
|
|
%% ------------------------------------------------------------------------%%
|
|
%% INITIALIZATION METHODS %%
|
|
%% ------------------------------------------------------------------------%%
|
|
methods(Access=public)
|
|
function open(obj,fname)
|
|
% obj.open()
|
|
% Opens an INI file.
|
|
% Input
|
|
% fname file name
|
|
obj.File = fname;
|
|
obj.IOMode = 'read';
|
|
obj.ioflag = 'r';
|
|
obj.tarflag = false;
|
|
obj.fileID = fopen(obj.File,obj.ioflag);
|
|
obj.fileBeg = 0;
|
|
fseek(obj.fileID,0,'eof');
|
|
obj.fileEnd = ftell(obj.fileID);
|
|
obj.FileSize = obj.fileEnd-obj.fileBeg;
|
|
obj.parse();
|
|
end
|
|
function opentar(obj,ptr)
|
|
% obj.opentar(ptr)
|
|
% Opens a subfile from tar in read-only mode.
|
|
% Input
|
|
% ptr pointer: [fid,first byte,number of bytes]
|
|
obj.File = 'tar-mode'; % Set generic file name
|
|
obj.IOMode = 'read'; % abstract IO mode
|
|
obj.ioflag = 'r'; % internal IO mode
|
|
obj.tarflag = true; % reading from tar archive?
|
|
% Set file ID to tar file ID
|
|
obj.fileID = ptr(1);
|
|
if obj.fileID<0
|
|
error('Unable to access file: %s',obj.File);
|
|
end
|
|
obj.fileBeg = ptr(2);
|
|
obj.fileEnd = ptr(2)+ptr(3);
|
|
obj.FileSize = ptr(3);
|
|
obj.parse();
|
|
end
|
|
end
|
|
methods(Access=public)
|
|
function close(obj)
|
|
% obj.close()
|
|
% Closes a file.
|
|
obj.resetPublicProperties();
|
|
obj.resetPrivateProperties();
|
|
if obj.tarflag
|
|
obj.tarflag = false;
|
|
obj.fileID = -1;
|
|
return;
|
|
end
|
|
if obj.fileID<0
|
|
return;
|
|
end
|
|
status = fclose(obj.fileID);
|
|
if status<0
|
|
warning('Error while closing: %d',status);
|
|
return;
|
|
end
|
|
obj.fileID = -1;
|
|
end
|
|
function setVerbosity(obj,flag)
|
|
% obj.setVerbosity(flag)
|
|
% Sets verbosity
|
|
% Input
|
|
% flag '1' -> verbose output
|
|
obj.Verbosity = flag;
|
|
end
|
|
function [data] = getContent(obj)
|
|
% [data] = obj.getContent()
|
|
% Get the entire content of the INI file.
|
|
% Output
|
|
% data entire content of file as structure
|
|
data = obj.content;
|
|
end
|
|
function [data] = getSection(obj,section)
|
|
% [data] = obj.getSection(section)
|
|
% Get the content of a single section of the INI file.
|
|
% Input
|
|
% section name of the requested section
|
|
% Output
|
|
% data content of one section of file as structure
|
|
if isfield(obj.content,section)
|
|
data = obj.content.(section);
|
|
else
|
|
error('Section not found: %s',name);
|
|
end
|
|
end
|
|
function [data] = getEntry(obj,section,entry)
|
|
% [data] = obj.getEntry(section,entry)
|
|
% Get the value of a single entry within the INI file.
|
|
% Input
|
|
% section name of the requested section
|
|
% entry name of the entry within requested section
|
|
% Output
|
|
% data value of the requested entry
|
|
if ~isfield(obj.content,section)
|
|
error('Section not found: %s',section);
|
|
elseif ~isfield(obj.content.(section),entry)
|
|
error('Entry not found: %s',entry);
|
|
else
|
|
data = obj.content.(section).(entry);
|
|
end
|
|
end
|
|
function [data] = listSections(obj)
|
|
% [data] = obj.listSections()
|
|
% Get a list of section names.
|
|
% Output
|
|
% data cell array with section names
|
|
data = fieldnames(obj.content);
|
|
end
|
|
function [data] = listEntries(obj,section)
|
|
% [data] = obj.listEntries(section)
|
|
% Get a list of entry names within a section..
|
|
% Input
|
|
% section name of the requested section
|
|
% Output
|
|
% data cell array with section names
|
|
data = fieldnames(obj.content.(section));
|
|
end
|
|
end
|
|
%% ------------------------------------------------------------------------%%
|
|
%% PRIVATE STATIC METHODS %%
|
|
%% ------------------------------------------------------------------------%%
|
|
methods(Access=private)
|
|
function parse(obj)
|
|
fseek(obj.fileID,obj.fileBeg,'bof');
|
|
% Construct a struct with content of file
|
|
obj.content = [];
|
|
curSection = '';
|
|
while ftell(obj.fileID)<obj.fileEnd
|
|
str = strtrim(fgetl(obj.fileID));
|
|
% Check for empty lines and comments (; or #)
|
|
if isempty(str)
|
|
continue;
|
|
end
|
|
if (str(1)==';')
|
|
continue;
|
|
end
|
|
if (str(1)=='#')
|
|
continue;
|
|
end
|
|
% Check for section
|
|
if (str(1)=='[') && (str(end)==']')
|
|
% This is a section: create a structure
|
|
curSection = ini.getUniqueVarname(str(2:end-1));
|
|
obj.content.(curSection) = [];
|
|
else
|
|
% This is not a section: create structure entry
|
|
[curMember,curValue] = strtok(str,'=');
|
|
curValue = ini.trimValue(curValue);
|
|
curMember = ini.getUniqueVarname(curMember);
|
|
% We now have the field name and the corresponding value as strings.
|
|
% Convert the value to a numeric value if possible.
|
|
[tmp,flag] = str2num(curValue);
|
|
if flag
|
|
curValue = tmp;
|
|
end
|
|
% Add this structure to the current section
|
|
if ~isempty(curSection)
|
|
obj.content.(curSection).(curMember) = curValue;
|
|
else
|
|
obj.content.(curMember) = curValue;
|
|
end
|
|
end
|
|
end
|
|
obj.NumSection = numel(fieldnames(obj.content));
|
|
end
|
|
function resetPublicProperties(obj)
|
|
obj.File = [];
|
|
obj.FileSize = [];
|
|
obj.IOMode = [];
|
|
obj.NumSection = [];
|
|
obj.Verbosity = [];
|
|
end
|
|
function resetPrivateProperties(obj)
|
|
obj.fileBeg = [];
|
|
obj.fileEnd = [];
|
|
obj.ioflag = [];
|
|
obj.content = [];
|
|
end
|
|
end
|
|
%% ------------------------------------------------------------------------%%
|
|
%% PRIVATE STATIC METHODS %%
|
|
%% ------------------------------------------------------------------------%%
|
|
methods(Access=private,Static)
|
|
function str = trimValue(str)
|
|
str = strtrim(str);
|
|
if strcmpi(str(1),'=')
|
|
str(1)=[];
|
|
end
|
|
str = strtrim(str);
|
|
end
|
|
function varname = getUniqueVarname(varname)
|
|
%tmp = matlab.lang.makeValidName(varname);
|
|
%varname = matlab.lang.makeUniqueStrings(tmp,who,namelengthmax);
|
|
varname = strrep(varname,'-','_');
|
|
varname = genvarname(varname);
|
|
end
|
|
end
|
|
end
|