📄 inifile.m
字号:
[keys,sections,subsections] = readallkeys(fileName);
varargout(1) = {keys};
varargout(2) = {sections};
varargout(3) = {subsections};
return
%----------------------------
% READS key-value pairs out
%----------------------------
elseif (strcmpi(operation,'read'))
result = cell(m,1);
if n >= 4
conversionOp = keys(:,4); % conversion operation: 'i', 'd', or 's' ('') - for each key to be read
else
conversionOp = cellstrings(m,1);
end
if n < 5
defaultValues = cellstrings(m,1);
else
defaultValues = keys(:,5);
end
readsett = defaultValues;
keysIn = keys(:,1:3);
[secsExist,subsecsExist,keysExist,readValues,so,eo] = findkeys(fileName,keysIn);
ind = find(keysExist);
% For those keys that exist but have empty values, replace them with
% the default values
if ~isempty(ind)
ind_empty = zeros(size(ind));
for kk = 1:size(ind,1)
ind_empty(kk) = isempty(readValues{ind(kk)});
end
ind(find(ind_empty)) = [];
readsett(ind) = readValues(ind);
end
% Now, go through all the keys and do the conversion if the conversion
% char is given
for ii=1:m
if ~isempty(conversionOp{ii}) & ~strcmpi(conversionOp{ii},'s')
if strcmpi(conversionOp{ii},'i') | strcmpi(conversionOp{ii},'d')
if ~isnumeric(readsett{ii})
readsett{ii} = str2num(readsett{ii});
end
if strcmpi(conversionOp{ii},'i')
readsett{ii} = round(readsett{ii});
end
if isempty(readsett{ii})
result{ii} = [num2str(ii) '-th key ' keysIn{ii,3} 'or given defaultValue could not be converted using ''' conversionOp{ii} ''' conversion'];
end
else
error(['Invalid conversion char given: ' conversionOp{ii}]);
end
end
end
varargout(1) = {readsett};
varargout(2) = {result};
return
%----------------------------
% WRITES key-value pairs to an existing or non-existing
% file (file can even be empty)
%----------------------------
elseif (strcmpi(operation,'write'))
if m < 1
error('At least one key is needed when writing keys');
end
if ~exist(fileName)
inifile(fileName,'new');
end
for ii=1:m % go through ALL the keys and convert them to strings
keys{ii,4} = n2s(keys{ii,4});
end
writekeys(fileName,keys,style);
return
%----------------------------
% DELETES key-value pairs out
%----------------------------
elseif (strcmpi(operation,'deletekeys'))
deletekeys(fileName,keys);
else
error('Unknown operation for INIFILE.');
end
%--------------------------------------------------
%%%%%%%%%%%%% SUBFUNCTIONS SECTION %%%%%%%%%%%%%%%%
%--------------------------------------------------
%------------------------------------
function [secsExist,subSecsExist,keysExist,values,startOffsets,endOffsets] = findkeys(fileName,keysIn)
% This function parses ini file for keys as given by keysIn. keysIn is a cell
% array of strings having 3 columns; section, subsection and key in each row.
% section and/or subsection can be empty (root section or root subsection)
% but the key can not be empty. The startOffsets and endOffsets are start and
% end bytes that each key occuppies, respectively. If any of the keys doesn't exist,
% startOffset and endOffset for this key are the same. A special case is
% when the key that doesn't exist also corresponds to a non-existing
% section and non-existing subsection. In such a case, the startOffset and
% endOffset have values of -1.
nKeys = size(keysIn,1); % number of keys
nKeysLocated = 0; % number of keys located
secsExist = zeros(nKeys,1); % if section exists (and is non-empty)
subSecsExist = zeros(nKeys,1); % if subsection...
keysExist = zeros(nKeys,1); % if key that we are looking for exists
keysLocated = keysExist; % if the key's position (existing or non-existing) is LOCATED
values = cellstrings(nKeys,1); % read values of keys (strings)
startOffsets = -ones(nKeys,1); % start byte-position of the keys
endOffsets = -ones(nKeys,1); % end byte-position of the keys
keyInd = find(strcmpi(keysIn(:,1),'')); % key indices having [] section (root section)
line = [];
lineN = 0; % line number
currSection = '';
currSubSection = '';
fh = fopen(fileName,'r');
if fh == -1
error(['File: ''' fileName ''' does not exist or can not be opened.']);
end
try
%--- Searching for the keys - their values and start and end locations in bytes
while 1
pos1 = ftell(fh);
line = fgetl(fh);
if line == -1 % end of file, exit
line = [];
break
end
lineN = lineN + 1;
[status,readValue,readKey] = processiniline(line);
if (status == 1) % (new) section found
% Keys that were found as belonging to any previous section
% are now assumed as located (because another
% section is found here which could even be a repeated one)
keyInd = find( ~keysLocated & strcmpi(keysIn(:,1),currSection) );
if length(keyInd)
keysLocated(keyInd) = 1;
nKeysLocated = nKeysLocated + length(keyInd);
end
currSection = readValue;
currSubSection = '';
% Indices to non-located keys belonging to current section
keyInd = find( ~keysLocated & strcmpi(keysIn(:,1),currSection) );
if ~isempty(keyInd)
secsExist(keyInd) = 1;
end
pos2 = ftell(fh);
startOffsets(keyInd) = pos2+1;
endOffsets(keyInd) = pos2+1;
elseif (status == 2) % (new) subsection found
% Keys that were found as belonging to any PREVIOUS section
% and/or subsection are now assumed as located (because another
% subsection is found here which could even be a repeated one)
keyInd = find( ~keysLocated & strcmpi(keysIn(:,1),currSection) & ~keysLocated & strcmpi(keysIn(:,2),currSubSection));
if length(keyInd)
keysLocated(keyInd) = 1;
nKeysLocated = nKeysLocated + length(keyInd);
end
currSubSection = readValue;
% Indices to non-located keys belonging to current section and subsection at the same time
keyInd = find( ~keysLocated & strcmpi(keysIn(:,1),currSection) & ~keysLocated & strcmpi(keysIn(:,2),currSubSection));
if ~isempty(keyInd)
subSecsExist(keyInd) = 1;
end
pos2 = ftell(fh);
startOffsets(keyInd) = pos2+1;
endOffsets(keyInd) = pos2+1;
elseif (status == 3) % key found
if isempty(keyInd)
continue % no keys from 'keys' - from section-subsection par currently in
end
currKey = readValue;
pos2 = ftell(fh); % the last-byte position of the read key - the total sum of chars read so far
for ii=1:length(keyInd)
if strcmpi( keysIn(keyInd(ii),3),readKey ) & ~keysLocated(keyInd(ii))
keysExist(keyInd(ii)) = 1;
startOffsets(keyInd(ii)) = pos1+1;
endOffsets(keyInd(ii)) = pos2;
values{keyInd(ii)} = currKey;
keysLocated(keyInd(ii)) = 1;
nKeysLocated = nKeysLocated + 1;
else
if ~keysLocated(keyInd(ii))
startOffsets(keyInd(ii)) = pos2+1;
endOffsets(keyInd(ii)) = pos2+1;
end
end
end
if nKeysLocated >= nKeys % if all the keys are located stop the searching
break
end
else % general text found (even empty line(s))
if (status == -1)
error(['unknown string found at line ' num2str(lineN)]);
end
end
%--- End of searching
end
fclose(fh);
catch
fclose(fh);
error(['Error parsing the file for keys: ' fileName ': ' lasterr]);
end
%------------------------------------
%------------------------------------
function writekeys(fileName,keys,style)
% Writes keys to the section and subsection pair
% If any of the keys doesn't exist, a new key is added to
% the end of the section-subsection pair otherwise the key is updated (changed).
% Keys is a 4-column cell array of strings.
global NL_CHAR;
RETURN = sprintf('\r');
NEWLINE = sprintf('\n');
[m,n] = size(keys);
if n < 4
error('Keys to be written are given in an invalid format.');
end
% Get keys position first using findkeys
keysIn = keys;
[secsExist,subSecsExist,keysExist,readValues,so,eo] = findkeys(fileName,keys(:,1:3));
% Read the whole file's contents out
fh = fopen(fileName,'r');
if fh == -1
error(['File: ''' fileName ''' does not exist or can not be opened.']);
end
try
dataout = fread(fh,'char=>char')';
catch
fclose(fh);
error(lasterr);
end
fclose(fh);
%--- Rewriting the file -> writing the refined contents
fh = fopen(fileName,'w');
if fh == -1
error(['File: ''' fileName ''' does not exist or can not be opened.']);
end
try
tab1 = [];
if strcmpi(style,'tabbed')
tab1 = sprintf('\t');
end
% Proper sorting of keys is cruical at this point in order to avoid
% inproper key-writing.
% Find keys with -1 offsets - keys with non-existing section AND
% subsection - keys that will be added to the end of the file
fs = length(dataout); % file size in bytes
nAddedKeys = 0;
ind = find(so==-1);
if ~isempty(ind)
so(ind) = (fs+10); % make sure these keys will come to the end when sorting
eo(ind) = (fs+10);
nAddedKeys = length(ind);
end
% Sort keys according to start- and end-offsets
[dummy,ind] = sort(so,1);
so = so(ind);
eo = eo(ind);
keysIn = keysIn(ind,:);
keysExist = keysExist(ind);
secsExist = secsExist(ind);
subSecsExist = subSecsExist(ind);
readValues = readValues(ind);
values = keysIn(:,4);
% Find keys with equal start offset (so) and additionally sort them
% (locally). These are non-existing keys, including the ones whose
% section and subsection will also be added.
nKeys = size(so,1);
fullInd = 1:nKeys;
ii = 1;
while ii < nKeys
ind = find(so==so(ii));
if ~isempty(ind) && length(ind) > 1
n = length(ind);
from = ind(1);
to = ind(end);
tmpKeys = keysIn( ind,: );
[tmpKeys,ind2] = sortrows( lower(tmpKeys) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -