www.gusucode.com > bigdata 工具箱 matlab源码程序 > bigdata/@tall/validateType.m
function varargout = validateType(varargin) %validateType Possibly deferred argument type validation % [TX1,TX2,...] = validateType(TX1,TX2,...,METHOD,VALIDTYPES,ARGIDXS) % validates that each of TX1, TX2, ... is one of the types VALIDTYPES. ARGIDXS % describes the positions of TX1,TX2 in the original call to METHOD - i.e. a % numeric vector. If possible, the validation is done immediately; otherwise, % the validation is done lazily. % % Note that if the required type is a type that must be known at the client % (aka a "strong" type) the validation is always performed immediately. % Copyright 2016 The MathWorks, Inc. % This prevents this frame and anything below it being added to the gather % error stack. frameMarker = matlab.bigdata.internal.InternalStackFrame(); %#ok<NASGU> dataArgs = varargin(1:end-3); methodName = varargin{end-2}; types = varargin{end-1}; argIdxs = varargin{end}; assert(numel(argIdxs) == numel(dataArgs) && ... ischar(methodName) && isrow(methodName) && ... iscellstr(types) && isnumeric(argIdxs), ... 'Invalid inputs to validateType.'); % Forbidden types start with "~" isForbiddenType = strncmp('~', types, 1); forbiddenTypes = types(isForbiddenType); forbiddenTypes = strrep(forbiddenTypes, '~', ''); allowedTypes = types(~isForbiddenType); msgArgsFcn = @(idx) {'MATLAB:bigdata:array:InvalidArgumentType', idx, ... upper(methodName), strjoin(allowedTypes, ' ')}; forbiddenMsgArgsFcn = @(idx) {'MATLAB:bigdata:array:UnsupportedArgumentType', idx, ... upper(methodName), strjoin(forbiddenTypes, ' ')}; % It's a mistake not to capture all the outputs since they might be modified. nData = numel(dataArgs); nargoutchk(nData, nData); varargout = cell(1, nData); for idx = 1:nData try varargout{idx} = iValidateArg(dataArgs{idx}, allowedTypes, forbiddenTypes, ... msgArgsFcn(argIdxs(idx)), forbiddenMsgArgsFcn(argIdxs(idx))); catch err throwAsCaller(err); end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function arg = iValidateArg(arg, allowedTypes, forbiddenTypes, msgArgs, forbiddenMsgArgs) adaptor = matlab.bigdata.internal.adaptors.getAdaptor(arg); argClass = adaptor.Class; classIsKnown = ~isempty(argClass); strongTypes = matlab.bigdata.internal.adaptors.getStrongTypes(); % First we can check if the type is known that it isn't a forbidden % type. Forbidden types must all be known at the client. assert(all(ismember(forbiddenTypes, strongTypes))); if classIsKnown && ismember(argClass, forbiddenTypes) error(message(forbiddenMsgArgs{:})); end if isempty(allowedTypes) % any type is permitted return end % If all of the allowed types are those that must be known up front, then we can % perform the check fully at the client. classMustBeKnown = all(ismember(allowedTypes, strongTypes)); if (classMustBeKnown || classIsKnown) && ~iIsCorrectClass(argClass, allowedTypes) error(message(msgArgs{:})); else % Class need not be known up front, must perform a lazy validation. if istall(arg) && ( ~classIsKnown || strcmp(argClass, 'cell') ) arg = lazyValidate(arg, {@(x) iIsCorrectType(x, allowedTypes), ... msgArgs{:}}); %#ok<CCAT> must use braces to concatenate function_handle else assert(classIsKnown, 'Class should be known for non-tall argument.'); end end end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% function ok = iIsCorrectType(x, validTypes) actualClass = class(x); ok = ismember(actualClass, validTypes) || ... (ismember('numeric', validTypes) && isnumeric(x)) || ... (ismember('cellstr', validTypes) && iscellstr(x)) || ... (ismember('integer', validTypes) && isinteger(x)) || ... (ismember('float', validTypes) && isfloat(x)); end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % In this case, we only have the class name of the argument, so we are forced to % use less attractive means of validating 'numeric' and 'cellstr'. function ok = iIsCorrectClass(actualClass, validTypes) integerTypes = {'int8', 'int16', 'int32', 'int64', ... 'uint8', 'uint16', 'uint32', 'uint64'}; floatTypes = {'single', 'double'}; if ismember('numeric', validTypes) validTypes = [ validTypes, integerTypes, floatTypes ]; end if ismember('integer', validTypes) validTypes = [ validTypes, integerTypes ]; end if ismember('float', validTypes) validTypes = [ validTypes, floatTypes ]; end if ismember('cellstr', validTypes) validTypes = [ validTypes, { 'cell' } ]; end ok = ismember(actualClass, validTypes); end