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

📄 read_structure.m

📁 这是一个关于MATLAB的函数
💻 M
字号:
function resp = read_structure(st,args)
% READ Read values stored in the location pointed to the STRUCTURE object ST.
% 
% 	O = READ(st) - reads the numeric values of each STRUCTURE member in ST. This returns a Matlab
%     structure having the member names as fields.
%     
% 	O = READ(st,val,member) - reads the numeric value of the STRUCTURE member specified by MEMBER.
%     
% 	O = READ(st,val,member,varargin) - reads the numeric value of the STRUCTURE member specified by MEMBER,
% 	where VARARGIN are extra READ options. See READ options of MEMBER.
% 
% 	O = READ(st,index,val,member) - reads the numeric value of the member of the STRUCTURE element INDEX.
%     
% 	O = READ(st,index,val,member,varargin) - reads the numeric value of the member of the STRUCTURE 
%     element INDEX, where VARARGIN are extra READ options. See READ options of MEMBER.
%
%   The output O is not in Matlab structure format when reading a particular member value.
% 
%   Copyright 2002 The MathWorks, Inc.

error(nargchk(2,2,nargin));
if ~ishandle(st),
    error('First parameter must be a STRUCTURE handle ');
end

index     = [1:prod(st.size)];
membidx   = [1:length(st.membname)];
nargs = length(args) + 1;

if nargs==1 | (nargs==2 & isempty(args{1})),
    next = 1;
    all_index = 1;
    descr = 'structure';
    % Create an array of structures
    emptySt = struct([]);
    emptySt(prod(st.size)).('dummy') = [];
    if length(st.size)==1,  emptySt = reshape(emptySt,1,st.size);
    else                    emptySt = reshape(emptySt,st.size); 
    end
    SendWarning(st,{'largestruct','mangle'});
    
elseif nargs>=2,
    % If 2nd argument is index, READ(st,1,...) or READ(st,1,'memb',...)
    if isnumeric(args{1}) & ~isempty(args{1}),
        index = round(args{1});
        if any(index<=0) | any(index>st.size)
            error(['Invalid STRUCTURE index: ' num2str(args{1})] );
        end
        if length(args)==1, % read one index only
            next = 1;
            all_index = 0;
            descr = 'indexed_structure';
            emptySt = CreateEmptyStruct(st);
            resp = emptySt;
            SendWarning(st,{'mangle'});
        else
            next = 2;
            if nargs>2
                membidx = strmatch(args{2},st.membname,'exact');
                next = 3;
            end
            all_index = 0;
            descr = 'indexed_member';
        end
    % If 2nd argument is struct member, READ(st,'memb',...)
	elseif isempty(args{1}) | (ischar(args{1}) & strmatch(args{1},st.membname,'exact')), 
        if isempty(args{1})
            args = {args{2}};
        end
        membidx = strmatch(args{1},st.membname,'exact');
        next = 2;
        all_index = 1;
        descr = 'all_members';
        resp = CreateArrayForAllElementOutput(st,membidx);
    else
        error('Invalid input: Second input must be a STRUCTURE index or member name');
    end
end

stOrigAddr = st.address; % original address of object
membobjlist = cell(1,membidx(end)); % create a cell array of member objects - index corresponds to member order (1-based)
for i=membidx, membobjlist{i} = my_getmember(st,i);  end
memboffset = st.member.containerobj_memboffset; % get all member offsets


i=1;
if strcmp(descr,'structure'), % separate loop - for faster read operation
    warning off backtrace;
    for idx=index,
		temp = struct([]);
		for memid=membidx,
            % sname = st.member.containerobj_membname{memid};
            sname = st.member.containerobj_mangledmembname{memid};
            % adjust member address
            membtemp = membobjlist{memid};
            membtemp.address = [stOrigAddr(1)+memboffset(memid)+st.storageunitspervalue*(idx-1), membtemp.address(2)];
            % call regular READ on each member
            temp(1).(sname) = read(membtemp);
        end
        resp(i) = temp;
        i = i+1;
	end
    warning on backtrace;
    
else
    % Compute linear memory index from index and array-order info
	if strcmp(descr,'indexed_structure') | strcmp(descr,'indexed_member'),
        index = ComputeLinearIndex(st,index);
    end

    warning off backtrace;
	for idx=index,
		temp = struct([]);
		for memid=membidx,
            % sname = st.member.containerobj_membname{memid};
            sname = st.member.containerobj_mangledmembname{memid};
            
            % adjust member address
            membtemp = membobjlist{memid};
            membtemp.address = [stOrigAddr(1)+memboffset(memid)+st.storageunitspervalue*(idx-1), membtemp.address(2)];
            % call regular READ on each member
            if strcmp(descr,'indexed_structure') | isempty([args{next:end}]), % or 'structure'
                temp(1).(sname) = read(membtemp);
            else
                % extra arguments
                num_extra_args = length(args{next:end});
                if num_extra_args==1
                    temp(1).(sname) = read(membtemp,args{next});
                elseif num_extra_args==2
                    temp(1).(sname) = read(membtemp,args{next},args{next+1});
                else
                    eval(call_arbitrary_args(num_extra_args));
                end
            end
            
        end
	
		if strcmp(descr,'indexed_structure')
            resp = temp;
		elseif strcmp(descr,'indexed_member')
            resp = temp.(sname);
		elseif strcmp(descr,'all_members')
            if iscell(resp), resp{i} = temp.(sname);
            else             resp(i) = temp.(sname);
            end
        end
        i = i+1;
	end
    warning on;
    warning on backtrace;
end

% Rearrange output data according to array-order property
if strcmp(descr,'all_members') | strcmp(descr,'structure')
	if length(st.size) > 1,  % Non-indexed, arrange according to 'arrayorder' prop
        if strcmp(st.arrayorder,'row-major'),
            resp = resp( GetMatlabIndex(st) );
        end
        resp = reshape(resp,st.size); 
    end
end
ReturnOrignalMemberAddress(st,membidx,stOrigAddr);

%-------------------------------------------
function str = call_arbitrary_args(num_args)
str = 'temp(1).(sname) = read(membtemp,args{next},args{next+1},';
for i=2:num_args-1
    str = horzcat(str,['args{next+' num2str(i) '},']);
end
str(end) = ')';
str = horzcat(str,';');

%-------------------------------------------
function emptySt = CreateEmptyStruct(st)
emptySt = struct([]);
for memb=st.membname
    m_memb = p_manglename(st,memb{1},'off');
    emptySt(1).(m_memb) = [];
end

%-------------------------------------------
function emptySt = CreateEmptyStructFromInfo(m_info)
emptySt = struct([]);
m_names = fieldnames(m_info);
for i = 1:length(m_names)
    memb = m_names{i};
    emptySt(1).(memb) = [];
end

%------------------------------------------
function resp = CreateArrayForAllElementOutput(st,membidx)

membinfo = st.member.containerobj_membinfo;
% m_membname = st.member.containerobj_mangledmembname{membidx};

minfo_membname = fieldnames(membinfo)';
minfo_membname = minfo_membname{membidx};
membtype = membinfo.(minfo_membname).type;

isscalar = length(st.size)==1;

if strcmp(membtype,'char') | strfind(membtype,'enum ')
	if isscalar,    resp = cell(1,st.size);
    else            resp = cell(st.size);
	end        
elseif strfind(membtype,'struct ') | strfind(membtype,'union ')  
    % emptySt = CreateEmptyStructFromInfo(membinfo.(m_membname).members);
    emptySt = struct('dummy',[]);
    emptySt(prod(st.size)).('dummy') = [];
	if isscalar,    resp = reshape(emptySt,1,st.size);
    else            resp = repmat(emptySt,st.size);
	end        
else
	if isscalar,    resp = zeros(1,st.size);
	else            resp = zeros(st.size);
	end        
end

%--------------------------------------------
function dummy = ReturnOrignalMemberAddress(st,membidx,baseAddr)
for membid = membidx
	obj = st.member.(st.member.containerobj_mangledmembname{membid});
	origAddr = [baseAddr(1)+st.member.containerobj_memboffset(membid),baseAddr(2)]; 
	set(obj,'address',origAddr);
end

%--------------------------------------------
function resp = my_getmember1(str,membid,structidx)

resp = str.member.(str.member.containerobj_mangledmembname{membid});
resp.address = [resp.address(1)+str.storageunitspervalue*(structidx-1), resp.address(2)];

%--------------------------------------------
function resp = my_getmember(str,membid)
resp = str.member.(str.member.containerobj_mangledmembname{membid});

%--------------------------------------------
function linearindex = getLinearIndex(str,subs)
try    
    index_shaped = round(reshape(subs,length(str.size),[])');
catch  
    error(['Index Array must be an (N x '  num2str(length(st.size)) ') array of indices' ]);
end
for subscript = index_shaped',
    if any(subscript < 1) | any(subscript' > str.size),
      error(['INDEX has an entry: [' num2str(subscript') '], which exceeds the defined size of object ']);
    end
end
addrange = index2addr(str,index_shaped);
uidata   = read_memoryobj(str,addrange',dtimeout);
uidata   = reshape(uidata,str.storageunitspervalue,[]);
nvalues  = size(uidata);
nvalues  = nvalues(2);

%-----------------------------------------
function linearindex = GetMatlabIndex(nn)
nsize = nn.size;
subsc = [];
totalnumel = prod(nsize);
len = length(nsize);
subsc = p_ind2sub(nn,nsize,[1:totalnumel],'col-major'); % index in a) C if row-major b) Matlab if col-major
linearindex = p_sub2ind(nn,nsize,subsc,'row-major'); % map indices to native Matlab array order
if ~isequal(unique(linearindex),sort(linearindex))
    error('Error generating linear index. Please report this error to MathWorks.');
end

%-----------------------------------------
function linearindex = ComputeLinearIndex(nn,index)
if ~isequal(length(index),length(nn.size)) & length(index)
    error(['Index must be a (1 x '  num2str(length(nn.size)) ') array ' ]);
end
if length(nn.size)>1,
    linearindex = p_sub2ind(nn,nn.size,index,nn.arrayorder);
else
    linearindex = index;
end

%----------------------------------------------
function SendWarning(st,warnlist)
warning on; warning off backtrace;
for i=1:length(warnlist),
    switch warnlist{i}
    case 'largestruct'
		if prod(st.size)*(st.storageunitspervalue)>150,
            warning('You are reading a large structure, this may take a while... ');
        end
    case 'mangle'
        if ~isequal(st.membname,st.member.containerobj_mangledmembname),
            warning('One or more member names on the result has been renamed to become a valid MATLAB structure fieldname ');
		end
    otherwise
    end
end
warning on backtrace;


% [EOF] read_structure.m

 

⌨️ 快捷键说明

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