代码拉取完成,页面将自动刷新
function output = savejson(rootname, obj, varargin)
%
% json=savejson(obj)
% or
% json=savejson(rootname,obj,filename)
% json=savejson(rootname,obj,opt)
% json=savejson(rootname,obj,'param1',value1,'param2',value2,...)
%
% convert a MATLAB object (cell, struct or array) into a JSON (JavaScript
% Object Notation) string
%
% author: Qianqian Fang (q.fang <at> neu.edu)
% initially created on 2011/09/09
%
% input:
% rootname: the name of the root-object, when set to '', the root name
% is ignored, however, when opt.ForceRootName is set to 1 (see below),
% the MATLAB variable name will be used as the root name.
% obj: a MATLAB object (array, cell, cell array, struct, struct array,
% class instance).
% filename: a string for the file name to save the output JSON data.
% opt: a struct for additional options, ignore to use default values.
% opt can have the following fields (first in [.|.] is the default)
%
% FileName [''|string]: a file name to save the output JSON data
% FloatFormat ['%.16g'|string]: format to show each numeric element
% of a 1D/2D array;
% IntFormat ['%.0f'|string]: format to display integer elements
% of a 1D/2D array;
% ArrayIndent [1|0]: if 1, output explicit data array with
% precedent indentation; if 0, no indentation
% ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D
% array in JSON array format; if sets to 1, an
% array will be shown as a struct with fields
% "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
% sparse arrays, the non-zero elements will be
% saved to _ArrayData_ field in triplet-format i.e.
% (ix,iy,val) and "_ArrayIsSparse_" will be added
% with a value of 1; for a complex array, the
% _ArrayData_ array will include two columns
% (4 for sparse) to record the real and imaginary
% parts, and also "_ArrayIsComplex_":1 is added.
% NestArray [0|1]: If set to 1, use nested array constructs
% to store N-dimensional arrays; if set to 0,
% use the annotated array format defined in the
% JData Specification (Draft 1 or later).
% ParseLogical [0|1]: if this is set to 1, logical array elem
% will use true/false rather than 1/0.
% SingletArray [0|1]: if this is set to 1, arrays with a single
% numerical element will be shown without a square
% bracket, unless it is the root object; if 0, square
% brackets are forced for any numerical arrays.
% SingletCell [1|0]: if 1, always enclose a cell with "[]"
% even it has only one element; if 0, brackets
% are ignored when a cell has only 1 element.
% EmptyArrayAsNull [0|1]: if set to 1, convert an empty array to
% JSON null object; empty cells remain mapped to []
% ForceRootName [0|1]: when set to 1 and rootname is empty, savejson
% will use the name of the passed obj variable as the
% root object name; if obj is an expression and
% does not have a name, 'root' will be used; if this
% is set to 0 and rootname is empty, the root level
% will be merged down to the lower level.
% Inf ['"$1_Inf_"'|string]: a customized regular expression pattern
% to represent +/-Inf. The matched pattern is '([-+]*)Inf'
% and $1 represents the sign. For those who want to use
% 1e999 to represent Inf, they can set opt.Inf to '$11e999'
% NaN ['"_NaN_"'|string]: a customized regular expression pattern
% to represent NaN
% JSONP [''|string]: to generate a JSONP output (JSON with padding),
% for example, if opt.JSONP='foo', the JSON data is
% wrapped inside a function call as 'foo(...);'
% UnpackHex [1|0]: convert the 0x[hex code] output by loadjson
% back to the string form
% SaveBinary [1|0]: 1 - save the JSON file in binary mode; 0 - text mode.
% Compact [0|1]: 1- out compact JSON format (remove all newlines and tabs)
% Compression 'zlib', 'gzip', 'lzma', 'lzip', 'lz4' or 'lz4hc': specify array
% compression method; currently only supports 6 methods. The
% data compression only applicable to numerical arrays
% in 3D or higher dimensions, or when ArrayToStruct
% is 1 for 1D or 2D arrays. If one wants to
% compress a long string, one must convert
% it to uint8 or int8 array first. The compressed
% array uses three extra fields
% "_ArrayZipType_": the opt.Compression value.
% "_ArrayZipSize_": a 1D integer array to
% store the pre-compressed (but post-processed)
% array dimensions, and
% "_ArrayZipData_": the "base64" encoded
% compressed binary array data.
% CompressArraySize [100|int]: only to compress an array if the total
% element count is larger than this number.
% CompressStringSize [inf|int]: only to compress a string if the total
% element count is larger than this number.
% FormatVersion [3|float]: set the JSONLab output version; since
% v2.0, JSONLab uses JData specification Draft 1
% for output format, it is incompatible with all
% previous releases; if old output is desired,
% please set FormatVersion to 1.9 or earlier.
% Encoding ['']: json file encoding. Support all encodings of
% fopen() function
% Append [0|1]: if set to 1, append a new object at the end of the file.
% Endian ['n'|'b','l']: Endianness of the output file ('n': native,
% 'b': big endian, 'l': little-endian)
% PreEncode [1|0]: if set to 1, call jdataencode first to preprocess
% the input data before saving
% BuiltinJSON [0|1]: if set to 1, this function attempts to call
% jsonencode, if presents (MATLAB R2016b or Octave
% 6) first. If jsonencode does not exist or failed,
% this function falls back to the jsonlab savejson
%
% opt can be replaced by a list of ('param',value) pairs. The param
% string is equivalent to a field in opt and is case sensitive.
% output:
% json: a string in the JSON format (see http://json.org)
%
% examples:
% jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],...
% 'MeshElem',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
% 'MeshSurf',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...
% 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...
% 'MeshCreator','FangQ','MeshTitle','T6 Cube',...
% 'SpecialData',[nan, inf, -inf]);
% savejson('jmesh',jsonmesh)
% savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g')
%
% license:
% BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
%
% -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
%
if (nargin == 1)
varname = inputname(1);
obj = rootname;
rootname = varname;
else
varname = inputname(2);
end
if (length(varargin) == 1 && (ischar(varargin{1}) || isa(varargin{1}, 'string')))
opt = struct('filename', varargin{1});
else
opt = varargin2struct(varargin{:});
end
opt.isoctave = isoctavemesh;
opt.compression = jsonopt('Compression', '', opt);
opt.nestarray = jsonopt('NestArray', 0, opt);
opt.compact = jsonopt('Compact', 0, opt);
opt.singletcell = jsonopt('SingletCell', 1, opt);
opt.singletarray = jsonopt('SingletArray', 0, opt);
opt.formatversion = jsonopt('FormatVersion', 3, opt);
opt.compressarraysize = jsonopt('CompressArraySize', 100, opt);
opt.compressstringsize = jsonopt('CompressStringSize', inf, opt);
opt.intformat = jsonopt('IntFormat', '%.0f', opt);
opt.floatformat = jsonopt('FloatFormat', '%.16g', opt);
opt.unpackhex = jsonopt('UnpackHex', 1, opt);
opt.arraytostruct = jsonopt('ArrayToStruct', 0, opt);
opt.parselogical = jsonopt('ParseLogical', 0, opt);
opt.arrayindent = jsonopt('ArrayIndent', 1, opt);
opt.emptyarrayasnull = jsonopt('EmptyArrayAsNull', 0, opt);
opt.inf = jsonopt('Inf', '"$1_Inf_"', opt);
opt.nan = jsonopt('NaN', '"_NaN_"', opt);
opt.num2cell_ = 0;
opt.nosubstruct_ = 0;
if (jsonopt('BuiltinJSON', 0, opt) && exist('jsonencode', 'builtin'))
try
obj = jdataencode(obj, 'Base64', 1, 'AnnotateArray', 1, 'UseArrayZipSize', 1, opt);
if (isempty(rootname))
json = jsonencode(obj);
else
json = jsonencode(struct(rootname, obj));
end
if (isempty(regexp(json, '^[{\[]', 'once')))
json = ['[', json, ']'];
end
return
catch
warning('built-in jsonencode function failed to encode the data, fallback to savejson');
end
end
if (jsonopt('PreEncode', 1, opt))
obj = jdataencode(obj, 'Base64', 1, 'UseArrayZipSize', 0, opt);
end
dozip = opt.compression;
if (~isempty(dozip))
if (~ismember(dozip, {'zlib', 'gzip', 'lzma', 'lzip', 'lz4', 'lz4hc'}) && isempty(regexp(dozip, '^blosc2', 'once')))
error('compression method "%s" is not supported', dozip);
end
if (exist('zmat', 'file') ~= 2 && exist('zmat', 'file') ~= 3)
try
error(javachk('jvm'));
try
base64decode('test');
catch
matlab.net.base64decode('test');
end
catch
error('java-based compression is not supported');
end
end
opt.Compression = dozip;
end
rootisarray = 0;
rootlevel = 1;
forceroot = jsonopt('ForceRootName', 0, opt);
if ((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || ...
iscell(obj) || isobject(obj)) && isempty(rootname) && forceroot == 0)
rootisarray = 1;
rootlevel = 0;
else
if (isempty(rootname))
rootname = varname;
end
end
if (isa(obj, 'containers.Map') && ~strcmp(obj.KeyType, 'char'))
rootisarray = 0;
end
if ((isstruct(obj) || iscell(obj)) && isempty(rootname) && forceroot)
rootname = 'root';
end
whitespaces = struct('tab', sprintf('\t'), 'newline', sprintf('\n'), 'sep', sprintf(',\n'));
if (opt.compact == 1)
whitespaces = struct('tab', '', 'newline', '', 'sep', ',');
end
if (~isfield(opt, 'whitespaces_'))
opt.whitespaces_ = whitespaces;
end
nl = whitespaces.newline;
json = obj2json(rootname, obj, rootlevel, opt);
if (rootisarray)
json = sprintf('%s%s', json, nl);
else
json = sprintf('{%s%s%s}\n', nl, json, nl);
end
jsonp = jsonopt('JSONP', '', opt);
if (~isempty(jsonp))
json = sprintf('%s(%s);%s', jsonp, json, nl);
end
% save to a file if FileName is set, suggested by Patrick Rapin
filename = jsonopt('FileName', '', opt);
if (~isempty(filename))
if (jsonopt('UTF8', 1, opt) && exist('unicode2native', 'builtin'))
json = unicode2native(json);
end
encoding = jsonopt('Encoding', '', opt);
endian = jsonopt('Endian', 'n', opt);
mode = 'w';
if (jsonopt('Append', 0, opt))
mode = 'a';
end
if (jsonopt('SaveBinary', 1, opt) == 1)
if (isempty(encoding))
fid = fopen(filename, [mode 'b'], endian);
else
fid = fopen(filename, [mode 'b'], endian, encoding);
end
fwrite(fid, json);
else
if (isempty(encoding))
fid = fopen(filename, [mode 't'], endian);
else
fid = fopen(filename, [mode 't'], endian, encoding);
end
fwrite(fid, json, 'char');
end
fclose(fid);
end
if (nargout > 0 || isempty(filename))
output = json;
end
%% -------------------------------------------------------------------------
function txt = obj2json(name, item, level, varargin)
if (iscell(item) || isa(item, 'string'))
txt = cell2json(name, item, level, varargin{:});
elseif (isstruct(item))
txt = struct2json(name, item, level, varargin{:});
elseif (isnumeric(item) || islogical(item))
txt = mat2json(name, item, level, varargin{:});
elseif (ischar(item))
if (~isempty(varargin{1}.compression) && numel(item) >= varargin{1}.compressstringsize)
txt = mat2json(name, item, level, varargin{:});
else
txt = str2json(name, item, level, varargin{:});
end
elseif (isa(item, 'function_handle'))
txt = struct2json(name, functions(item), level, varargin{:});
elseif (isa(item, 'containers.Map'))
txt = map2json(name, item, level, varargin{:});
elseif (isa(item, 'categorical'))
txt = cell2json(name, cellstr(item), level, varargin{:});
elseif (isa(item, 'table'))
txt = matlabtable2json(name, item, level, varargin{:});
elseif (isa(item, 'graph') || isa(item, 'digraph'))
txt = struct2json(name, jdataencode(item), level, varargin{:});
elseif (isobject(item))
txt = matlabobject2json(name, item, level, varargin{:});
else
txt = any2json(name, item, level, varargin{:});
end
%% -------------------------------------------------------------------------
function txt = cell2json(name, item, level, varargin)
txt = {};
if (~iscell(item) && ~isa(item, 'string'))
error('input is not a cell or string array');
end
isnum2cell = varargin{1}.num2cell_;
if (isnum2cell)
item = squeeze(item);
if (~isvector(item))
item = permute(item, ndims(item):-1:1);
end
end
dim = size(item);
len = numel(item);
ws = varargin{1}.whitespaces_;
padding0 = repmat(ws.tab, 1, level);
nl = ws.newline;
bracketlevel = ~varargin{1}.singletcell;
if (len > bracketlevel)
if (~isempty(name))
txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[', nl};
name = '';
else
txt = {padding0, '[', nl};
end
elseif (len == 0)
if (~isempty(name))
txt = {padding0, '"' decodevarname(name, varargin{1}.unpackhex) '":[]'};
name = '';
else
txt = {padding0, '[]'};
end
txt = sprintf('%s', txt{:});
return
end
if (size(item, 1) > 1)
item = num2cell(item, 2:ndims(item))';
end
idx = num2cell(1:length(item));
sep = {[',' nl], ''};
txt = [txt{:}, cellfun(@(x, id) [obj2json(name, x, level + (dim(1) > 1) + (len > bracketlevel), varargin{:}), sep{(id == length(item)) + 1}], item, idx, 'UniformOutput', false)];
if (len > bracketlevel)
txt(end + 1:end + 3) = {nl, padding0, ']'};
end
txt = sprintf('%s', txt{:});
%% -------------------------------------------------------------------------
function txt = struct2json(name, item, level, varargin)
txt = {};
if (~isstruct(item))
error('input is not a struct');
end
dim = size(item);
if (ndims(squeeze(item)) > 2) % for 3D or higher dimensions, flatten to 2D for now
item = reshape(item, dim(1), numel(item) / dim(1));
dim = size(item);
end
len = numel(item);
forcearray = (len > 1 || (varargin{1}.singletarray == 1 && level > 0));
ws = varargin{1}.whitespaces_;
padding0 = repmat(ws.tab, 1, level);
padding2 = repmat(ws.tab, 1, level + 1);
padding1 = repmat(ws.tab, 1, level + (dim(1) > 1) + forcearray);
nl = ws.newline;
if (isfield(item, encodevarname('_ArrayType_', varargin{1}.unpackhex)))
varargin{1}.nosubstruct_ = 1;
end
if (isempty(item))
if (~isempty(name))
txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[]'};
else
txt = {padding0, '[]'};
end
txt = sprintf('%s', txt{:});
return
end
if (~isempty(name))
if (forcearray)
txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[', nl};
end
else
if (forcearray)
txt = {padding0, '[', nl};
end
end
for j = 1:dim(2)
if (dim(1) > 1)
txt(end + 1:end + 3) = {padding2, '[', nl};
end
for i = 1:dim(1)
names = fieldnames(item(i, j));
if (~isempty(name) && len == 1 && ~forcearray)
txt(end + 1:end + 5) = {padding1, '"', decodevarname(name, varargin{1}.unpackhex), '":{', nl};
else
txt(end + 1:end + 3) = {padding1, '{', nl};
end
if (~isempty(names))
for e = 1:length(names)
if (varargin{1}.nosubstruct_ && ischar(item(i, j).(names{e})) || ...
strcmp(names{e}, encodevarname('_ByteStream_')))
txt{end + 1} = str2json(names{e}, item(i, j).(names{e}), ...
level + (dim(1) > 1) + 1 + forcearray, varargin{:});
else
txt{end + 1} = obj2json(names{e}, item(i, j).(names{e}), ...
level + (dim(1) > 1) + 1 + forcearray, varargin{:});
end
if (e < length(names))
txt{end + 1} = ',';
end
txt{end + 1} = nl;
end
end
txt(end + 1:end + 2) = {padding1, '}'};
if (i < dim(1))
txt(end + 1:end + 2) = {',' nl};
end
end
if (dim(1) > 1)
txt(end + 1:end + 3) = {nl, padding2, ']'};
end
if (j < dim(2))
txt(end + 1:end + 2) = {',' nl};
end
end
if (forcearray)
txt(end + 1:end + 3) = {nl, padding0, ']'};
end
txt = sprintf('%s', txt{:});
%% -------------------------------------------------------------------------
function txt = map2json(name, item, level, varargin)
txt = {};
if (~isa(item, 'containers.Map'))
error('input is not a containers.Map class');
end
dim = size(item);
names = keys(item);
val = values(item);
if (~strcmp(item.KeyType, 'char'))
mm = cell(1, length(names));
for i = 1:length(names)
mm{i} = {names{i}, val{i}};
end
if (isempty(name))
txt = obj2json('_MapData_', mm, level + 1, varargin{:});
else
temp = struct(name, struct());
if (varargin{1}.isoctave)
temp.(name).('_MapData_') = mm;
else
temp.(name).('x0x5F_MapData_') = mm;
end
txt = obj2json(name, temp.(name), level, varargin{:});
end
return
end
ws = varargin{1}.whitespaces_;
padding0 = repmat(ws.tab, 1, level);
nl = ws.newline;
if (isempty(item))
if (~isempty(name))
txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[]'};
else
txt = {padding0, '[]'};
end
txt = sprintf('%s', txt{:});
return
end
if (~isempty(name))
txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":{', nl};
else
txt = {padding0, '{', nl};
end
for i = 1:dim(1)
if (isempty(names{i}))
txt{end + 1} = obj2json('x0x0_', val{i}, level + 1, varargin{:});
else
txt{end + 1} = obj2json(names{i}, val{i}, level + 1, varargin{:});
end
if (i < length(names))
txt{end + 1} = ',';
end
if (i < dim(1))
txt{end + 1} = nl;
end
end
txt(end + 1:end + 3) = {nl, padding0, '}'};
txt = sprintf('%s', txt{:});
%% -------------------------------------------------------------------------
function txt = str2json(name, item, level, varargin)
txt = {};
if (~ischar(item))
error('input is not a string');
end
item = reshape(item, max(size(item), [1 0]));
len = size(item, 1);
ws = varargin{1}.whitespaces_;
padding1 = repmat(ws.tab, 1, level);
padding0 = repmat(ws.tab, 1, level + 1);
nl = ws.newline;
sep = ws.sep;
if (~isempty(name))
if (len > 1)
txt = {padding1, '"', decodevarname(name, varargin{1}.unpackhex), '":[', nl};
end
else
if (len > 1)
txt = {padding1, '[', nl};
end
end
for e = 1:len
if (strcmp('_ArrayZipData_', decodevarname(name, varargin{1}.unpackhex)) == 0)
val = escapejsonstring(item(e, :), varargin{:});
else
val = item(e, :);
end
if (len == 1)
obj = ['"' decodevarname(name, varargin{1}.unpackhex) '":' '"', val, '"'];
if (isempty(name))
obj = ['"', val, '"'];
end
txt(end + 1:end + 2) = {padding1, obj};
else
txt(end + 1:end + 4) = {padding0, '"', val, '"'};
end
if (e == len)
sep = '';
end
txt{end + 1} = sep;
end
if (len > 1)
txt(end + 1:end + 3) = {nl, padding1, ']'};
end
txt = sprintf('%s', txt{:});
%% -------------------------------------------------------------------------
function txt = mat2json(name, item, level, varargin)
if (~isnumeric(item) && ~islogical(item) && ~ischar(item))
error('input is not an array');
end
opt = varargin{1};
ws = opt.whitespaces_;
padding1 = repmat(ws.tab, 1, level);
padding0 = repmat(ws.tab, 1, level + 1);
nl = ws.newline;
sep = ws.sep;
dozip = opt.compression;
zipsize = opt.compressarraysize;
format = opt.formatversion;
isnest = opt.nestarray;
if (~opt.nosubstruct_ && (((isnest == 0) && length(size(item)) > 2) || issparse(item) || ~isreal(item) || ...
(isempty(item) && any(size(item))) || opt.arraytostruct || (~isempty(dozip) && numel(item) > zipsize)))
if (isempty(name))
txt = sprintf('%s{%s%s"_ArrayType_":"%s",%s%s"_ArraySize_":%s,%s', ...
padding1, nl, padding0, class(item), nl, padding0, regexprep(mat2str(size(item)), '\s+', ','), nl);
else
txt = sprintf('%s"%s":{%s%s"_ArrayType_":"%s",%s%s"_ArraySize_":%s,%s', ...
padding1, decodevarname(name, opt.unpackhex), nl, padding0, class(item), nl, padding0, regexprep(mat2str(size(item)), '\s+', ','), nl);
end
else
numtxt = matdata2json(item, level + 1, varargin{:});
if (isempty(name))
txt = sprintf('%s%s', padding1, numtxt);
else
if (numel(item) == 1 && varargin{1}.singletarray == 0)
txt = sprintf('%s"%s":%s', padding1, decodevarname(name, opt.unpackhex), numtxt);
else
txt = sprintf('%s"%s":%s', padding1, decodevarname(name, opt.unpackhex), numtxt);
end
end
return
end
dataformat = '%s%s%s%s%s';
if (issparse(item))
[ix, iy] = find(item);
data = full(item(find(item)));
if (~isreal(item))
data = [real(data(:)), imag(data(:))];
if (size(item, 1) == 1)
% Kludge to have data's 'transposedness' match item's.
% (Necessary for complex row vector handling below.)
data = data';
end
txt = sprintf(dataformat, txt, padding0, '"_ArrayIsComplex_":', 'true', sep);
end
txt = sprintf(dataformat, txt, padding0, '"_ArrayIsSparse_":', 'true', sep);
if (~isempty(dozip) && numel(data * 2) > zipsize)
if (size(item, 1) == 1)
% Row vector, store only column indices.
fulldata = [iy(:), data'];
elseif (size(item, 2) == 1)
% Column vector, store only row indices.
fulldata = [ix, data];
else
% General case, store row and column indices.
fulldata = [ix, iy, data];
end
txt = sprintf(dataformat, txt, padding0, '"_ArrayZipSize_":', regexprep(mat2str(size(fulldata)), '\s+', ','), sep);
txt = sprintf(dataformat, txt, padding0, '"_ArrayZipType_":"', dozip, ['"' sep]);
compfun = str2func([dozip 'encode']);
txt = sprintf(dataformat, txt, padding0, '"_ArrayZipData_":"', base64encode(compfun(typecast(fulldata(:), 'uint8'))), ['"' nl]);
else
if (size(item, 1) == 1)
% Row vector, store only column indices.
fulldata = [iy(:), data'];
elseif (size(item, 2) == 1)
% Column vector, store only row indices.
fulldata = [ix, data];
else
% General case, store row and column indices.
fulldata = [ix, iy, data];
end
txt = sprintf(dataformat, txt, padding0, '"_ArrayData_":', ...
matdata2json(fulldata', level + 2, varargin{:}), nl);
end
else
if (format > 1.9)
item = permute(item, ndims(item):-1:1);
end
if (~isempty(dozip) && numel(item) > zipsize)
if (isreal(item))
fulldata = item(:)';
if (islogical(fulldata) || ischar(fulldata))
fulldata = uint8(fulldata);
end
else
txt = sprintf(dataformat, txt, padding0, '"_ArrayIsComplex_":', 'true', sep);
fulldata = [real(item(:)) imag(item(:))]';
end
txt = sprintf(dataformat, txt, padding0, '"_ArrayZipSize_":', regexprep(mat2str(size(fulldata)), '\s+', ','), sep);
txt = sprintf(dataformat, txt, padding0, '"_ArrayZipType_":"', dozip, ['"' sep]);
encodeparam = {};
if (~isempty(regexp(dozip, '^blosc2', 'once')))
compfun = @blosc2encode;
encodeparam = {dozip, 'nthread', jsonopt('nthread', 1, opt), 'shuffle', jsonopt('shuffle', 1, opt), 'typesize', jsonopt('typesize', length(typecast(fulldata(1), 'uint8')), opt)};
else
compfun = str2func([dozip 'encode']);
end
txt = sprintf(dataformat, txt, padding0, '"_ArrayZipData_":"', char(base64encode(compfun(typecast(fulldata(:), 'uint8'), encodeparam{:}))), ['"' nl]);
else
if (isreal(item))
txt = sprintf(dataformat, txt, padding0, '"_ArrayData_":', ...
matdata2json(item(:)', level + 2, varargin{:}), nl);
else
txt = sprintf(dataformat, txt, padding0, '"_ArrayIsComplex_":', 'true', sep);
txt = sprintf(dataformat, txt, padding0, '"_ArrayData_":', ...
matdata2json([real(item(:)) imag(item(:))]', level + 2, varargin{:}), nl);
end
end
end
txt = sprintf('%s%s%s', txt, padding1, '}');
%% -------------------------------------------------------------------------
function txt = matlabobject2json(name, item, level, varargin)
try
if numel(item) == 0 % empty object
st = struct();
elseif numel(item) == 1 %
txt = str2json(name, char(item), level, varargin{:});
return
else
propertynames = properties(item);
for p = 1:numel(propertynames)
for o = numel(item):-1:1 % array of objects
st(o).(propertynames{p}) = item(o).(propertynames{p});
end
end
end
txt = struct2json(name, st, level, varargin{:});
catch
txt = any2json(name, item, level, varargin{:});
end
%% -------------------------------------------------------------------------
function txt = matlabtable2json(name, item, level, varargin)
st = containers.Map();
st('_TableRecords_') = table2cell(item);
st('_TableRows_') = item.Properties.RowNames';
st('_TableCols_') = item.Properties.VariableNames;
if (isempty(name))
txt = map2json(name, st, level, varargin{:});
else
temp = struct(name, struct());
temp.(name) = st;
txt = map2json(name, temp.(name), level, varargin{:});
end
%% -------------------------------------------------------------------------
function txt = matdata2json(mat, level, varargin)
ws = varargin{1}.whitespaces_;
tab = ws.tab;
nl = ws.newline;
isnest = varargin{1}.nestarray;
format = varargin{1}.formatversion;
isnum2cell = varargin{1}.num2cell_;
if (~isvector(mat) && isnest == 1)
if (format > 1.9 && isnum2cell == 0)
mat = permute(mat, ndims(mat):-1:1);
end
varargin{1}.num2cell_ = 1;
varargin{1}.singletcell = 0;
txt = cell2json('', num2cell(mat, 1), level - 1, varargin{:});
return
elseif (isvector(mat) && isnum2cell == 1)
mat = mat(:).';
end
if (size(mat, 1) == 1)
pre = '';
post = '';
level = level - 1;
else
pre = sprintf('[%s', nl);
post = sprintf('%s%s]', nl, repmat(tab, 1, level - 1));
end
if (isempty(mat))
if (varargin{1}.emptyarrayasnull)
txt = 'null';
else
txt = '[]';
end
return
end
if (isinteger(mat))
floatformat = varargin{1}.intformat;
else
floatformat = varargin{1}.floatformat;
end
if (numel(mat) == 1 && varargin{1}.singletarray == 0 && level > 0)
formatstr = [repmat([floatformat ','], 1, size(mat, 2) - 1) [floatformat sprintf(',%s', nl)]];
else
formatstr = ['[' repmat([floatformat ','], 1, size(mat, 2) - 1) [floatformat sprintf('],%s', nl)]];
end
if (nargin >= 2 && size(mat, 1) > 1 && varargin{1}.arrayindent == 1)
formatstr = [repmat(tab, 1, level) formatstr];
end
txt = sprintf(formatstr, permute(mat, ndims(mat):-1:1));
txt(end - length(nl):end) = [];
if (islogical(mat) && (numel(mat) == 1 || varargin{1}.parselogical == 1))
txt = regexprep(txt, '1', 'true');
txt = regexprep(txt, '0', 'false');
end
txt = [pre txt post];
if (any(isinf(mat(:))))
txt = regexprep(txt, '([-+]*)Inf', varargin{1}.inf);
end
if (any(isnan(mat(:))))
txt = regexprep(txt, 'NaN', varargin{1}.nan);
end
%% -------------------------------------------------------------------------
function txt = any2json(name, item, level, varargin)
st = containers.Map();
st('_DataInfo_') = struct('MATLABObjectName', name, 'MATLABObjectClass', class(item), 'MATLABObjectSize', size(item));
st('_ByteStream_') = char(base64encode(getByteStreamFromArray(item)));
if (isempty(name))
txt = map2json(name, st, level, varargin{:});
else
temp = struct(name, struct());
temp.(name) = st;
txt = map2json(name, temp.(name), level, varargin{:});
end
%% -------------------------------------------------------------------------
function newstr = escapejsonstring(str, varargin)
newstr = str;
if (isempty(str) || isempty(regexp(str, '\W', 'once')))
return
end
isoct = varargin{1}.isoctave;
if (isoct)
vv = sscanf(OCTAVE_VERSION, '%f');
if (vv(1) >= 3.8)
isoct = 0;
end
end
if (isoct)
escapechars = {'\\', '\"', '\a', '\f', '\n', '\r', '\t', '\v'};
for i = 1:length(escapechars)
newstr = regexprep(newstr, escapechars{i}, escapechars{i});
end
newstr = regexprep(newstr, '\\\\(u[0-9a-fA-F]{4}[^0-9a-fA-F]*)', '\$1');
else
escapechars = {'\\', '\"', '\a', '\b', '\f', '\n', '\r', '\t', '\v'};
esc = {'\\\\', '\\"', '\\a', '\\b', '\\f', '\\n', '\\r', '\\t', '\\v'};
for i = 1:length(escapechars)
newstr = regexprep(newstr, escapechars{i}, esc{i});
end
newstr = regexprep(newstr, '\\\\(u[0-9a-fA-F]{4}[^0-9a-fA-F]*)', '\\$1');
end
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。