0001 function json=savejson(rootname,obj,varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
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
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)
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
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)
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
0408
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
0416 txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
0417 matdata2json([iy(:),data'],level+2,varargin{:}), nl);
0418 elseif(size(item,2)==1)
0419
0420 txt=sprintf(dataformat,txt,padding0,'"_ArrayData_": ',...
0421 matdata2json([ix,data],level+2,varargin{:}), nl);
0422 else
0423
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
0442 st = struct();
0443 elseif numel(item) == 1
0444 st = struct();
0445 txt = str2json(name, char(item), level, varargin(:));
0446 return
0447 else
0448
0449
0450
0451 propertynames = properties(item);
0452 for p = 1:numel(propertynames)
0453 for o = numel(item):-1:1
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
0463 st = struct();
0464 else
0465
0466
0467
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
0514 formatstr=['[' repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf('],%s',nl)]];
0515
0516
0517
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
0530
0531
0532
0533
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