Home > vbmeg > external > iso2mesh > savejson.m

savejson

PURPOSE ^

SYNOPSIS ^

function json=savejson(rootname,obj,varargin)

DESCRIPTION ^

 json=savejson(rootname,obj,filename)
    or
 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)
 created on 2011/09/09

 $Id$

 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)

        opt.FileName [''|string]: a file name to save the output JSON data
        opt.FloatFormat ['%.10g'|string]: format to show each numeric element
                         of a 1D/2D array;
        opt.ArrayIndent [1|0]: if 1, output explicit data array with
                         precedent indentation; if 0, no indentation
        opt.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. 
        opt.ParseLogical [0|1]: if this is set to 1, logical array elem
                         will use true/false rather than 1/0.
        opt.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.
        opt.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.
        opt.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.
        opt.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'
        opt.NaN ['"_NaN_"'|string]: a customized regular expression pattern
                         to represent NaN
        opt.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(...);'
        opt.UnpackHex [1|0]: conver the 0x[hex code] output by loadjson 
                         back to the string form
        opt.SaveBinary [0|1]: 1 - save the JSON file in binary mode; 0 - text mode.
        opt.Compact [0|1]: 1- out compact JSON format (remove all newlines and tabs)

        opt can be replaced by a list of ('param',value) pairs. The param 
        string is equivallent 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],... 
               'MeshTetra',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
               'MeshTri',[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)

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function json=savejson(rootname,obj,varargin)
0002 %
0003 % json=savejson(rootname,obj,filename)
0004 %    or
0005 % json=savejson(rootname,obj,opt)
0006 % json=savejson(rootname,obj,'param1',value1,'param2',value2,...)
0007 %
0008 % convert a MATLAB object (cell, struct or array) into a JSON (JavaScript
0009 % Object Notation) string
0010 %
0011 % author: Qianqian Fang (q.fang <at> neu.edu)
0012 % created on 2011/09/09
0013 %
0014 % $Id$
0015 %
0016 % input:
0017 %      rootname: the name of the root-object, when set to '', the root name
0018 %        is ignored, however, when opt.ForceRootName is set to 1 (see below),
0019 %        the MATLAB variable name will be used as the root name.
0020 %      obj: a MATLAB object (array, cell, cell array, struct, struct array,
0021 %      class instance).
0022 %      filename: a string for the file name to save the output JSON data.
0023 %      opt: a struct for additional options, ignore to use default values.
0024 %        opt can have the following fields (first in [.|.] is the default)
0025 %
0026 %        opt.FileName [''|string]: a file name to save the output JSON data
0027 %        opt.FloatFormat ['%.10g'|string]: format to show each numeric element
0028 %                         of a 1D/2D array;
0029 %        opt.ArrayIndent [1|0]: if 1, output explicit data array with
0030 %                         precedent indentation; if 0, no indentation
0031 %        opt.ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D
0032 %                         array in JSON array format; if sets to 1, an
0033 %                         array will be shown as a struct with fields
0034 %                         "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for
0035 %                         sparse arrays, the non-zero elements will be
0036 %                         saved to _ArrayData_ field in triplet-format i.e.
0037 %                         (ix,iy,val) and "_ArrayIsSparse_" will be added
0038 %                         with a value of 1; for a complex array, the
0039 %                         _ArrayData_ array will include two columns
0040 %                         (4 for sparse) to record the real and imaginary
0041 %                         parts, and also "_ArrayIsComplex_":1 is added.
0042 %        opt.ParseLogical [0|1]: if this is set to 1, logical array elem
0043 %                         will use true/false rather than 1/0.
0044 %        opt.SingletArray [0|1]: if this is set to 1, arrays with a single
0045 %                         numerical element will be shown without a square
0046 %                         bracket, unless it is the root object; if 0, square
0047 %                         brackets are forced for any numerical arrays.
0048 %        opt.SingletCell  [1|0]: if 1, always enclose a cell with "[]"
0049 %                         even it has only one element; if 0, brackets
0050 %                         are ignored when a cell has only 1 element.
0051 %        opt.ForceRootName [0|1]: when set to 1 and rootname is empty, savejson
0052 %                         will use the name of the passed obj variable as the
0053 %                         root object name; if obj is an expression and
0054 %                         does not have a name, 'root' will be used; if this
0055 %                         is set to 0 and rootname is empty, the root level
0056 %                         will be merged down to the lower level.
0057 %        opt.Inf ['"$1_Inf_"'|string]: a customized regular expression pattern
0058 %                         to represent +/-Inf. The matched pattern is '([-+]*)Inf'
0059 %                         and $1 represents the sign. For those who want to use
0060 %                         1e999 to represent Inf, they can set opt.Inf to '$11e999'
0061 %        opt.NaN ['"_NaN_"'|string]: a customized regular expression pattern
0062 %                         to represent NaN
0063 %        opt.JSONP [''|string]: to generate a JSONP output (JSON with padding),
0064 %                         for example, if opt.JSONP='foo', the JSON data is
0065 %                         wrapped inside a function call as 'foo(...);'
0066 %        opt.UnpackHex [1|0]: conver the 0x[hex code] output by loadjson
0067 %                         back to the string form
0068 %        opt.SaveBinary [0|1]: 1 - save the JSON file in binary mode; 0 - text mode.
0069 %        opt.Compact [0|1]: 1- out compact JSON format (remove all newlines and tabs)
0070 %
0071 %        opt can be replaced by a list of ('param',value) pairs. The param
0072 %        string is equivallent to a field in opt and is case sensitive.
0073 % output:
0074 %      json: a string in the JSON format (see http://json.org)
0075 %
0076 % examples:
0077 %      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],...
0078 %               'MeshTetra',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
0079 %               'MeshTri',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...
0080 %                          2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...
0081 %               'MeshCreator','FangQ','MeshTitle','T6 Cube',...
0082 %               'SpecialData',[nan, inf, -inf]);
0083 %      savejson('jmesh',jsonmesh)
0084 %      savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g')
0085 %
0086 % license:
0087 %     BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details
0088 %
0089 % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab)
0090 %
0091 
0092 if(nargin==1)
0093    varname=inputname(1);
0094    obj=rootname;
0095    if(isempty(varname)) 
0096       varname='root';
0097    end
0098    rootname=varname;
0099 else
0100    varname=inputname(2);
0101 end
0102 if(length(varargin)==1 && ischar(varargin{1}))
0103    opt=struct('filename',varargin{1});
0104 else
0105    opt=varargin2struct(varargin{:});
0106 end
0107 opt.IsOctave=exist('OCTAVE_VERSION','builtin');
0108 if(isfield(opt,'norowbracket'))
0109     warning('Option ''NoRowBracket'' is depreciated, please use ''SingletArray'' and set its value to not(NoRowBracket)');
0110     if(~isfield(opt,'singletarray'))
0111         opt.singletarray=not(opt.norowbracket);
0112     end
0113 end
0114 rootisarray=0;
0115 rootlevel=1;
0116 forceroot=jsonopt('ForceRootName',0,opt);
0117 if((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || ...
0118         iscell(obj) || isobject(obj)) && isempty(rootname) && forceroot==0)
0119     rootisarray=1;
0120     rootlevel=0;
0121 else
0122     if(isempty(rootname))
0123         rootname=varname;
0124     end
0125 end
0126 if((isstruct(obj) || iscell(obj))&& isempty(rootname) && forceroot)
0127     rootname='root';
0128 end
0129 
0130 whitespaces=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
0131 if(jsonopt('Compact',0,opt)==1)
0132     whitespaces=struct('tab','','newline','','sep',',');
0133 end
0134 if(~isfield(opt,'whitespaces_'))
0135     opt.whitespaces_=whitespaces;
0136 end
0137 
0138 nl=whitespaces.newline;
0139 
0140 json=obj2json(rootname,obj,rootlevel,opt);
0141 if(rootisarray)
0142     json=sprintf('%s%s',json,nl);
0143 else
0144     json=sprintf('{%s%s%s}\n',nl,json,nl);
0145 end
0146 
0147 jsonp=jsonopt('JSONP','',opt);
0148 if(~isempty(jsonp))
0149     json=sprintf('%s(%s);%s',jsonp,json,nl);
0150 end
0151 
0152 % save to a file if FileName is set, suggested by Patrick Rapin
0153 filename=jsonopt('FileName','',opt);
0154 if(~isempty(filename))
0155     if(jsonopt('SaveBinary',0,opt)==1)
0156         fid = fopen(filename, 'wb');
0157         fwrite(fid,json);
0158     else
0159         fid = fopen(filename, 'wt');
0160         fwrite(fid,json,'char');
0161     end
0162     fclose(fid);
0163 end
0164 
0165 %%-------------------------------------------------------------------------
0166 function txt=obj2json(name,item,level,varargin)
0167 
0168 if(iscell(item))
0169     txt=cell2json(name,item,level,varargin{:});
0170 elseif(isstruct(item))
0171     txt=struct2json(name,item,level,varargin{:});
0172 elseif(ischar(item))
0173     txt=str2json(name,item,level,varargin{:});
0174 elseif(isa(item,'string'))
0175     txt=str2json(name,item{:},level,varargin{:});
0176 elseif(isobject(item))
0177     if(~exist('OCTAVE_VERSION','builtin') && istable(item))
0178         txt=matlabtable2json(name,item,level,varargin{:});
0179     else
0180         txt=matlabobject2json(name,item,level,varargin{:});
0181     end
0182 else
0183     txt=mat2json(name,item,level,varargin{:});
0184 end
0185 
0186 %%-------------------------------------------------------------------------
0187 function txt=cell2json(name,item,level,varargin)
0188 txt={};
0189 if(~iscell(item))
0190         error('input is not a cell');
0191 end
0192 
0193 dim=size(item);
0194 if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
0195     item=reshape(item,dim(1),numel(item)/dim(1));
0196     dim=size(item);
0197 end
0198 len=numel(item);
0199 ws=jsonopt('whitespaces_',struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n')),varargin{:});
0200 padding0=repmat(ws.tab,1,level);
0201 padding2=repmat(ws.tab,1,level+1);
0202 nl=ws.newline;
0203 bracketlevel=~jsonopt('singletcell',1,varargin{:});
0204 if(len>bracketlevel)
0205     if(~isempty(name))
0206         txt={padding0, '"', checkname(name,varargin{:}),'": [', nl}; name=''; 
0207     else
0208         txt={padding0, '[', nl};
0209     end
0210 elseif(len==0)
0211     if(~isempty(name))
0212         txt={padding0, '"' checkname(name,varargin{:}) '": []'}; name=''; 
0213     else
0214         txt={padding0, '[]'};
0215     end
0216 end
0217 for i=1:dim(1)
0218     if(dim(1)>1)
0219         txt(end+1:end+3)={padding2,'[',nl};
0220     end
0221     for j=1:dim(2)
0222        txt{end+1}=obj2json(name,item{i,j},level+(dim(1)>1)+(len>bracketlevel),varargin{:});
0223        if(j<dim(2))
0224            txt(end+1:end+2)={',' nl};
0225        end
0226     end
0227     if(dim(1)>1)
0228         txt(end+1:end+3)={nl,padding2,']'};
0229     end
0230     if(i<dim(1))
0231         txt(end+1:end+2)={',' nl};
0232     end
0233     %if(j==dim(2)) txt=sprintf('%s%s',txt,sprintf(',%s',nl)); end
0234 end
0235 if(len>bracketlevel)
0236     txt(end+1:end+3)={nl,padding0,']'};
0237 end
0238 txt = sprintf('%s',txt{:});
0239 
0240 %%-------------------------------------------------------------------------
0241 function txt=struct2json(name,item,level,varargin)
0242 txt={};
0243 if(~isstruct(item))
0244     error('input is not a struct');
0245 end
0246 dim=size(item);
0247 if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now
0248     item=reshape(item,dim(1),numel(item)/dim(1));
0249     dim=size(item);
0250 end
0251 len=numel(item);
0252 forcearray= (len>1 || (jsonopt('SingletArray',0,varargin{:})==1 && level>0));
0253 ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'));
0254 ws=jsonopt('whitespaces_',ws,varargin{:});
0255 padding0=repmat(ws.tab,1,level);
0256 padding2=repmat(ws.tab,1,level+1);
0257 padding1=repmat(ws.tab,1,level+(dim(1)>1)+forcearray);
0258 nl=ws.newline;
0259 
0260 if(isempty(item)) 
0261     if(~isempty(name)) 
0262         txt={padding0, '"', checkname(name,varargin{:}),'": []'};
0263     else
0264         txt={padding0, '[]'};
0265     end
0266     txt = sprintf('%s',txt{:});
0267     return;
0268 end
0269 if(~isempty(name)) 
0270     if(forcearray)
0271         txt={padding0, '"', checkname(name,varargin{:}),'": [', nl};
0272     end
0273 else
0274     if(forcearray)
0275         txt={padding0, '[', nl};
0276     end
0277 end
0278 for j=1:dim(2)
0279   if(dim(1)>1)
0280       txt(end+1:end+3)={padding2,'[',nl};
0281   end
0282   for i=1:dim(1)
0283     names = fieldnames(item(i,j));
0284     if(~isempty(name) && len==1 && ~forcearray)
0285         txt(end+1:end+5)={padding1, '"', checkname(name,varargin{:}),'": {', nl};
0286     else
0287         txt(end+1:end+3)={padding1, '{', nl};
0288     end
0289     if(~isempty(names))
0290       for e=1:length(names)
0291         txt{end+1}=obj2json(names{e},item(i,j).(names{e}),...
0292              level+(dim(1)>1)+1+forcearray,varargin{:});
0293         if(e<length(names))
0294             txt{end+1}=',';
0295         end
0296         txt{end+1}=nl;
0297       end
0298     end
0299     txt(end+1:end+2)={padding1,'}'};
0300     if(i<dim(1))
0301         txt(end+1:end+2)={',' nl};
0302     end
0303   end
0304   if(dim(1)>1)
0305       txt(end+1:end+3)={nl,padding2,']'};
0306   end
0307   if(j<dim(2))
0308       txt(end+1:end+2)={',' nl};
0309   end
0310 end
0311 if(forcearray)
0312     txt(end+1:end+3)={nl,padding0,']'};
0313 end
0314 txt = sprintf('%s',txt{:});
0315 
0316 %%-------------------------------------------------------------------------
0317 function txt=str2json(name,item,level,varargin)
0318 txt={};
0319 if(~ischar(item))
0320         error('input is not a string');
0321 end
0322 item=reshape(item, max(size(item),[1 0]));
0323 len=size(item,1);
0324 ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
0325 ws=jsonopt('whitespaces_',ws,varargin{:});
0326 padding1=repmat(ws.tab,1,level);
0327 padding0=repmat(ws.tab,1,level+1);
0328 nl=ws.newline;
0329 sep=ws.sep;
0330 
0331 if(~isempty(name)) 
0332     if(len>1)
0333         txt={padding1, '"', checkname(name,varargin{:}),'": [', nl};
0334     end
0335 else
0336     if(len>1)
0337         txt={padding1, '[', nl};
0338     end
0339 end
0340 for e=1:len
0341     val=escapejsonstring(item(e,:));
0342     if(len==1)
0343         obj=['"' checkname(name,varargin{:}) '": ' '"',val,'"'];
0344         if(isempty(name))
0345             obj=['"',val,'"'];
0346         end
0347         txt(end+1:end+2)={padding1, obj};
0348     else
0349         txt(end+1:end+4)={padding0,'"',val,'"'};
0350     end
0351     if(e==len)
0352         sep='';
0353     end
0354     txt{end+1}=sep;
0355 end
0356 if(len>1)
0357     txt(end+1:end+3)={nl,padding1,']'};
0358 end
0359 txt = sprintf('%s',txt{:});
0360 
0361 %%-------------------------------------------------------------------------
0362 function txt=mat2json(name,item,level,varargin)
0363 if(~isnumeric(item) && ~islogical(item))
0364         error('input is not an array');
0365 end
0366 ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
0367 ws=jsonopt('whitespaces_',ws,varargin{:});
0368 padding1=repmat(ws.tab,1,level);
0369 padding0=repmat(ws.tab,1,level+1);
0370 nl=ws.newline;
0371 sep=ws.sep;
0372 
0373 if(length(size(item))>2 || issparse(item) || ~isreal(item) || ...
0374    (isempty(item) && any(size(item))) ||jsonopt('ArrayToStruct',0,varargin{:}))
0375     if(isempty(name))
0376         txt=sprintf('%s{%s%s"_ArrayType_": "%s",%s%s"_ArraySize_": %s,%s',...
0377               padding1,nl,padding0,class(item),nl,padding0,regexprep(mat2str(size(item)),'\s+',','),nl);
0378     else
0379         txt=sprintf('%s"%s": {%s%s"_ArrayType_": "%s",%s%s"_ArraySize_": %s,%s',...
0380               padding1,checkname(name,varargin{:}),nl,padding0,class(item),nl,padding0,regexprep(mat2str(size(item)),'\s+',','),nl);
0381     end
0382 else
0383     if(numel(item)==1 && jsonopt('SingletArray',0,varargin{:})==0 && level>0)
0384         numtxt=regexprep(regexprep(matdata2json(item,level+1,varargin{:}),'^\[',''),']','');
0385     else
0386         numtxt=matdata2json(item,level+1,varargin{:});
0387     end
0388     if(isempty(name))
0389         txt=sprintf('%s%s',padding1,numtxt);
0390     else
0391         if(numel(item)==1 && jsonopt('SingletArray',0,varargin{:})==0)
0392                txt=sprintf('%s"%s": %s',padding1,checkname(name,varargin{:}),numtxt);
0393         else
0394             txt=sprintf('%s"%s": %s',padding1,checkname(name,varargin{:}),numtxt);
0395         end
0396     end
0397     return;
0398 end
0399 dataformat='%s%s%s%s%s';
0400 
0401 if(issparse(item))
0402     [ix,iy]=find(item);
0403     data=full(item(find(item)));
0404     if(~isreal(item))
0405        data=[real(data(:)),imag(data(:))];
0406        if(size(item,1)==1)
0407            % Kludge to have data's 'transposedness' match item's.
0408            % (Necessary for complex row vector handling below.)
0409            data=data';
0410        end
0411        txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_": ','1', sep);
0412     end
0413     txt=sprintf(dataformat,txt,padding0,'"_ArrayIsSparse_": ','1', sep);
0414     if(size(item,1)==1)
0415         % Row vector, store only column indices.
0416         txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
0417            matdata2json([iy(:),data'],level+2,varargin{:}), nl);
0418     elseif(size(item,2)==1)
0419         % Column vector, store only row indices.
0420         txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
0421            matdata2json([ix,data],level+2,varargin{:}), nl);
0422     else
0423         % General case, store row and column indices.
0424         txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
0425            matdata2json([ix,iy,data],level+2,varargin{:}), nl);
0426     end
0427 else
0428     if(isreal(item))
0429         txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
0430             matdata2json(item(:)',level+2,varargin{:}), nl);
0431     else
0432         txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_": ','1', sep);
0433         txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
0434             matdata2json([real(item(:)) imag(item(:))],level+2,varargin{:}), nl);
0435     end
0436 end
0437 txt=sprintf('%s%s%s',txt,padding1,'}');
0438 
0439 %%-------------------------------------------------------------------------
0440 function txt=matlabobject2json(name,item,level,varargin)
0441 if numel(item) == 0 %empty object
0442     st = struct();
0443 elseif numel(item) == 1 %
0444     st = struct();
0445     txt = str2json(name, char(item), level, varargin(:));
0446     return
0447 else
0448     % "st = struct(item);" would produce an inmutable warning, because it
0449     % make the protected and private properties visible. Instead we get the
0450     % visible properties
0451     propertynames = properties(item);
0452     for p = 1:numel(propertynames)
0453         for o = numel(item):-1:1 % aray of objects
0454             st(o).(propertynames{p}) = item(o).(propertynames{p});
0455         end
0456     end
0457 end
0458 txt=struct2json(name,st,level,varargin{:});
0459 
0460 %%-------------------------------------------------------------------------
0461 function txt=matlabtable2json(name,item,level,varargin)
0462 if numel(item) == 0 %empty object
0463     st = struct();
0464 else
0465     % "st = struct(item);" would produce an inmutable warning, because it
0466     % make the protected and private properties visible. Instead we get the
0467     % visible properties
0468     st = struct();
0469     propertynames = properties(item);
0470     if(isfield(item.Properties,'RowNames') && ~isempty(item.Properties.RowNames))
0471         rownames=item.Properties.RowNames;
0472         for p = 1:(numel(propertynames)-1)
0473             for j = 1:size(item(:,p),1)
0474                 st.(rownames{j}).(propertynames{p}) = item{j,p};
0475             end
0476         end
0477     else
0478         for p = 1:(numel(propertynames)-1)
0479             for j = 1:size(item(:,p),1)
0480                 st(j).(propertynames{p}) = item{j,p};
0481             end
0482         end
0483     end
0484 end
0485 txt=struct2json(name,st,level,varargin{:});
0486 
0487 %%-------------------------------------------------------------------------
0488 function txt=matdata2json(mat,level,varargin)
0489 
0490 ws=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n'));
0491 ws=jsonopt('whitespaces_',ws,varargin{:});
0492 tab=ws.tab;
0493 nl=ws.newline;
0494 
0495 if(size(mat,1)==1)
0496     pre='';
0497     post='';
0498     level=level-1;
0499 else
0500     pre=sprintf('[%s',nl);
0501     post=sprintf('%s%s]',nl,repmat(tab,1,level-1));
0502 end
0503 
0504 if(isempty(mat))
0505     txt='null';
0506     return;
0507 end
0508 if(isinteger(mat))
0509   floatformat=jsonopt('FloatFormat','%d',varargin{:});
0510 else
0511   floatformat=jsonopt('FloatFormat','%.10g',varargin{:});
0512 end
0513 %if(numel(mat)>1)
0514     formatstr=['[' repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf('],%s',nl)]];
0515 %else
0516 %    formatstr=[repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf(',\n')]];
0517 %end
0518 
0519 if(nargin>=2 && size(mat,1)>1 && jsonopt('ArrayIndent',1,varargin{:})==1)
0520     formatstr=[repmat(tab,1,level) formatstr];
0521 end
0522 
0523 txt=sprintf(formatstr,mat');
0524 txt(end-length(nl):end)=[];
0525 if(islogical(mat) && jsonopt('ParseLogical',0,varargin{:})==1)
0526    txt=regexprep(txt,'1','true');
0527    txt=regexprep(txt,'0','false');
0528 end
0529 %txt=regexprep(mat2str(mat),'\s+',',');
0530 %txt=regexprep(txt,';',sprintf('],\n['));
0531 % if(nargin>=2 && size(mat,1)>1)
0532 %     txt=regexprep(txt,'\[',[repmat(sprintf('\t'),1,level) '[']);
0533 % end
0534 txt=[pre txt post];
0535 if(any(isinf(mat(:))))
0536     txt=regexprep(txt,'([-+]*)Inf',jsonopt('Inf','"$1_Inf_"',varargin{:}));
0537 end
0538 if(any(isnan(mat(:))))
0539     txt=regexprep(txt,'NaN',jsonopt('NaN','"_NaN_"',varargin{:}));
0540 end
0541 
0542 %%-------------------------------------------------------------------------
0543 function newname=checkname(name,varargin)
0544 isunpack=jsonopt('UnpackHex',1,varargin{:});
0545 newname=name;
0546 if(isempty(regexp(name,'0x([0-9a-fA-F]+)_','once')))
0547     return
0548 end
0549 if(isunpack)
0550     isoct=jsonopt('IsOctave',0,varargin{:});
0551     if(~isoct)
0552         newname=regexprep(name,'(^x|_){1}0x([0-9a-fA-F]+)_','${native2unicode(hex2dec($2))}');
0553     else
0554         pos=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','start');
0555         pend=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','end');
0556         if(isempty(pos))
0557             return;
0558         end
0559         str0=name;
0560         pos0=[0 pend(:)' length(name)];
0561         newname='';
0562         for i=1:length(pos)
0563             newname=[newname str0(pos0(i)+1:pos(i)-1) char(hex2dec(str0(pos(i)+3:pend(i)-1)))];
0564         end
0565         if(pos(end)~=length(name))
0566             newname=[newname str0(pos0(end-1)+1:pos0(end))];
0567         end
0568     end
0569 end
0570 
0571 %%-------------------------------------------------------------------------
0572 function newstr=escapejsonstring(str)
0573 newstr=str;
0574 isoct=exist('OCTAVE_VERSION','builtin');
0575 if(isoct)
0576    vv=sscanf(OCTAVE_VERSION,'%f');
0577    if(vv(1)>=3.8)
0578        isoct=0;
0579    end
0580 end
0581 if(isoct)
0582   escapechars={'\\','\"','\/','\a','\f','\n','\r','\t','\v'};
0583   for i=1:length(escapechars);
0584     newstr=regexprep(newstr,escapechars{i},escapechars{i});
0585   end
0586   newstr=regexprep(newstr,'\\\\(u[0-9a-fA-F]{4}[^0-9a-fA-F]*)','\$1');
0587 else
0588   escapechars={'\\','\"','\/','\a','\b','\f','\n','\r','\t','\v'};
0589   for i=1:length(escapechars);
0590     newstr=regexprep(newstr,escapechars{i},regexprep(escapechars{i},'\\','\\\\'));
0591   end
0592   newstr=regexprep(newstr,'\\\\(u[0-9a-fA-F]{4}[^0-9a-fA-F]*)','\\$1');
0593 end

Generated on Mon 22-May-2023 06:53:56 by m2html © 2005