0001 function json=saveubjson(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 if(nargin==1)
0081 varname=inputname(1);
0082 obj=rootname;
0083 if(isempty(varname))
0084 varname='root';
0085 end
0086 rootname=varname;
0087 else
0088 varname=inputname(2);
0089 end
0090 if(length(varargin)==1 && ischar(varargin{1}))
0091 opt=struct('filename',varargin{1});
0092 else
0093 opt=varargin2struct(varargin{:});
0094 end
0095 opt.IsOctave=exist('OCTAVE_VERSION','builtin');
0096 if(isfield(opt,'norowbracket'))
0097 warning('Option ''NoRowBracket'' is depreciated, please use ''SingletArray'' and set its value to not(NoRowBracket)');
0098 if(~isfield(opt,'singletarray'))
0099 opt.singletarray=not(opt.norowbracket);
0100 end
0101 end
0102 rootisarray=0;
0103 rootlevel=1;
0104 forceroot=jsonopt('ForceRootName',0,opt);
0105 if((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || ...
0106 iscell(obj) || isobject(obj)) && isempty(rootname) && forceroot==0)
0107 rootisarray=1;
0108 rootlevel=0;
0109 else
0110 if(isempty(rootname))
0111 rootname=varname;
0112 end
0113 end
0114 if((isstruct(obj) || iscell(obj))&& isempty(rootname) && forceroot)
0115 rootname='root';
0116 end
0117 json=obj2ubjson(rootname,obj,rootlevel,opt);
0118 if(~rootisarray)
0119 json=['{' json '}'];
0120 end
0121
0122 jsonp=jsonopt('JSONP','',opt);
0123 if(~isempty(jsonp))
0124 json=[jsonp '(' json ')'];
0125 end
0126
0127
0128 filename=jsonopt('FileName','',opt);
0129 if(~isempty(filename))
0130 fid = fopen(filename, 'wb');
0131 fwrite(fid,json);
0132 fclose(fid);
0133 end
0134
0135
0136 function txt=obj2ubjson(name,item,level,varargin)
0137
0138 if(iscell(item))
0139 txt=cell2ubjson(name,item,level,varargin{:});
0140 elseif(isstruct(item))
0141 txt=struct2ubjson(name,item,level,varargin{:});
0142 elseif(ischar(item))
0143 txt=str2ubjson(name,item,level,varargin{:});
0144 elseif(isobject(item))
0145 txt=matlabobject2ubjson(name,item,level,varargin{:});
0146 else
0147 txt=mat2ubjson(name,item,level,varargin{:});
0148 end
0149
0150
0151 function txt=cell2ubjson(name,item,level,varargin)
0152 txt='';
0153 if(~iscell(item))
0154 error('input is not a cell');
0155 end
0156
0157 dim=size(item);
0158 if(ndims(squeeze(item))>2)
0159 item=reshape(item,dim(1),numel(item)/dim(1));
0160 dim=size(item);
0161 end
0162 bracketlevel=~jsonopt('singletcell',1,varargin{:});
0163 len=numel(item);
0164 if(len>bracketlevel)
0165 if(~isempty(name))
0166 txt=[N_(checkname(name,varargin{:})) '[']; name='';
0167 else
0168 txt='[';
0169 end
0170 elseif(len==0)
0171 if(~isempty(name))
0172 txt=[N_(checkname(name,varargin{:})) 'Z']; name='';
0173 else
0174 txt='Z';
0175 end
0176 end
0177 for j=1:dim(2)
0178 if(dim(1)>1)
0179 txt=[txt '['];
0180 end
0181 for i=1:dim(1)
0182 txt=[txt obj2ubjson(name,item{i,j},level+(len>bracketlevel),varargin{:})];
0183 end
0184 if(dim(1)>1)
0185 txt=[txt ']'];
0186 end
0187 end
0188 if(len>bracketlevel)
0189 txt=[txt ']'];
0190 end
0191
0192
0193 function txt=struct2ubjson(name,item,level,varargin)
0194 txt='';
0195 if(~isstruct(item))
0196 error('input is not a struct');
0197 end
0198 dim=size(item);
0199 if(ndims(squeeze(item))>2)
0200 item=reshape(item,dim(1),numel(item)/dim(1));
0201 dim=size(item);
0202 end
0203 len=numel(item);
0204 forcearray= (len>1 || (jsonopt('SingletArray',0,varargin{:})==1 && level>0));
0205
0206 if(~isempty(name))
0207 if(forcearray)
0208 txt=[N_(checkname(name,varargin{:})) '['];
0209 end
0210 else
0211 if(forcearray)
0212 txt='[';
0213 end
0214 end
0215 for j=1:dim(2)
0216 if(dim(1)>1)
0217 txt=[txt '['];
0218 end
0219 for i=1:dim(1)
0220 names = fieldnames(item(i,j));
0221 if(~isempty(name) && len==1 && ~forcearray)
0222 txt=[txt N_(checkname(name,varargin{:})) '{'];
0223 else
0224 txt=[txt '{'];
0225 end
0226 if(~isempty(names))
0227 for e=1:length(names)
0228 txt=[txt obj2ubjson(names{e},item(i,j).(names{e}),...
0229 level+(dim(1)>1)+1+forcearray,varargin{:})];
0230 end
0231 end
0232 txt=[txt '}'];
0233 end
0234 if(dim(1)>1)
0235 txt=[txt ']'];
0236 end
0237 end
0238 if(forcearray)
0239 txt=[txt ']'];
0240 end
0241
0242
0243 function txt=str2ubjson(name,item,level,varargin)
0244 txt='';
0245 if(~ischar(item))
0246 error('input is not a string');
0247 end
0248 item=reshape(item, max(size(item),[1 0]));
0249 len=size(item,1);
0250
0251 if(~isempty(name))
0252 if(len>1)
0253 txt=[N_(checkname(name,varargin{:})) '['];
0254 end
0255 else
0256 if(len>1)
0257 txt='[';
0258 end
0259 end
0260 for e=1:len
0261 val=item(e,:);
0262 if(len==1)
0263 obj=[N_(checkname(name,varargin{:})) '' '',S_(val),''];
0264 if(isempty(name))
0265 obj=['',S_(val),''];
0266 end
0267 txt=[txt,'',obj];
0268 else
0269 txt=[txt,'',['',S_(val),'']];
0270 end
0271 end
0272 if(len>1)
0273 txt=[txt ']'];
0274 end
0275
0276
0277 function txt=mat2ubjson(name,item,level,varargin)
0278 if(~isnumeric(item) && ~islogical(item))
0279 error('input is not an array');
0280 end
0281
0282 if(length(size(item))>2 || issparse(item) || ~isreal(item) || ...
0283 (isempty(item) && any(size(item))) ||jsonopt('ArrayToStruct',0,varargin{:}))
0284 cid=I_(uint32(max(size(item))));
0285 if(isempty(name))
0286 txt=['{' N_('_ArrayType_'),S_(class(item)),N_('_ArraySize_'),I_a(size(item),cid(1)) ];
0287 else
0288 if(isempty(item))
0289 txt=[N_(checkname(name,varargin{:})),'Z'];
0290 return;
0291 else
0292 txt=[N_(checkname(name,varargin{:})),'{',N_('_ArrayType_'),S_(class(item)),N_('_ArraySize_'),I_a(size(item),cid(1))];
0293 end
0294 end
0295 else
0296 if(isempty(name))
0297 txt=matdata2ubjson(item,level+1,varargin{:});
0298 else
0299 if(numel(item)==1 && jsonopt('SingletArray',0,varargin{:})==0)
0300 numtxt=regexprep(regexprep(matdata2ubjson(item,level+1,varargin{:}),'^\[',''),']','');
0301 txt=[N_(checkname(name,varargin{:})) numtxt];
0302 else
0303 txt=[N_(checkname(name,varargin{:})),matdata2ubjson(item,level+1,varargin{:})];
0304 end
0305 end
0306 return;
0307 end
0308 if(issparse(item))
0309 [ix,iy]=find(item);
0310 data=full(item(find(item)));
0311 if(~isreal(item))
0312 data=[real(data(:)),imag(data(:))];
0313 if(size(item,1)==1)
0314
0315
0316 data=data';
0317 end
0318 txt=[txt,N_('_ArrayIsComplex_'),'T'];
0319 end
0320 txt=[txt,N_('_ArrayIsSparse_'),'T'];
0321 if(size(item,1)==1)
0322
0323 txt=[txt,N_('_ArrayData_'),...
0324 matdata2ubjson([iy(:),data'],level+2,varargin{:})];
0325 elseif(size(item,2)==1)
0326
0327 txt=[txt,N_('_ArrayData_'),...
0328 matdata2ubjson([ix,data],level+2,varargin{:})];
0329 else
0330
0331 txt=[txt,N_('_ArrayData_'),...
0332 matdata2ubjson([ix,iy,data],level+2,varargin{:})];
0333 end
0334 else
0335 if(isreal(item))
0336 txt=[txt,N_('_ArrayData_'),...
0337 matdata2ubjson(item(:)',level+2,varargin{:})];
0338 else
0339 txt=[txt,N_('_ArrayIsComplex_'),'T'];
0340 txt=[txt,N_('_ArrayData_'),...
0341 matdata2ubjson([real(item(:)) imag(item(:))],level+2,varargin{:})];
0342 end
0343 end
0344 txt=[txt,'}'];
0345
0346
0347 function txt=matlabobject2ubjson(name,item,level,varargin)
0348 st = struct();
0349 if numel(item) > 0
0350
0351
0352
0353 propertynames = properties(item);
0354 for p = 1:numel(propertynames)
0355 for o = numel(item):-1:1
0356 st(o).(propertynames{p}) = item(o).(propertynames{p});
0357 end
0358 end
0359 end
0360 txt=struct2ubjson(name,st,level,varargin{:});
0361
0362
0363 function txt=matdata2ubjson(mat,level,varargin)
0364 if(isempty(mat))
0365 txt='Z';
0366 return;
0367 end
0368 type='';
0369 hasnegtive=(mat<0);
0370 if(isa(mat,'integer') || isinteger(mat) || (isfloat(mat) && all(mod(mat(:),1) == 0)))
0371 if(isempty(hasnegtive))
0372 if(max(mat(:))<=2^8)
0373 type='U';
0374 end
0375 end
0376 if(isempty(type))
0377
0378 id= histc(abs(max(mat(:))),[0 2^7 2^15 2^31 2^63]);
0379 if(isempty(id~=0))
0380 error('high-precision data is not yet supported');
0381 end
0382 key='iIlL';
0383 type=key(id~=0);
0384 end
0385 txt=[I_a(mat(:),type,size(mat))];
0386 elseif(islogical(mat))
0387 logicalval='FT';
0388 if(numel(mat)==1)
0389 txt=logicalval(mat+1);
0390 else
0391 txt=['[$U#' I_a(size(mat),'l') typecast(swapbytes(uint8(mat(:)')),'uint8')];
0392 end
0393 else
0394 if(numel(mat)==1)
0395 txt=['[' D_(mat) ']'];
0396 else
0397 txt=D_a(mat(:),'D',size(mat));
0398 end
0399 end
0400
0401
0402
0403
0404
0405
0406 if(any(isinf(mat(:))))
0407 txt=regexprep(txt,'([-+]*)Inf',jsonopt('Inf','"$1_Inf_"',varargin{:}));
0408 end
0409 if(any(isnan(mat(:))))
0410 txt=regexprep(txt,'NaN',jsonopt('NaN','"_NaN_"',varargin{:}));
0411 end
0412
0413
0414 function newname=checkname(name,varargin)
0415 isunpack=jsonopt('UnpackHex',1,varargin{:});
0416 newname=name;
0417 if(isempty(regexp(name,'0x([0-9a-fA-F]+)_','once')))
0418 return
0419 end
0420 if(isunpack)
0421 isoct=jsonopt('IsOctave',0,varargin{:});
0422 if(~isoct)
0423 newname=regexprep(name,'(^x|_){1}0x([0-9a-fA-F]+)_','${native2unicode(hex2dec($2))}');
0424 else
0425 pos=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','start');
0426 pend=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','end');
0427 if(isempty(pos))
0428 return;
0429 end
0430 str0=name;
0431 pos0=[0 pend(:)' length(name)];
0432 newname='';
0433 for i=1:length(pos)
0434 newname=[newname str0(pos0(i)+1:pos(i)-1) char(hex2dec(str0(pos(i)+3:pend(i)-1)))];
0435 end
0436 if(pos(end)~=length(name))
0437 newname=[newname str0(pos0(end-1)+1:pos0(end))];
0438 end
0439 end
0440 end
0441
0442 function val=N_(str)
0443 val=[I_(int32(length(str))) str];
0444
0445 function val=S_(str)
0446 if(length(str)==1)
0447 val=['C' str];
0448 else
0449 val=['S' I_(int32(length(str))) str];
0450 end
0451
0452 function val=I_(num)
0453 if(~isinteger(num))
0454 error('input is not an integer');
0455 end
0456 if(num>=0 && num<255)
0457 val=['U' data2byte(swapbytes(cast(num,'uint8')),'uint8')];
0458 return;
0459 end
0460 key='iIlL';
0461 cid={'int8','int16','int32','int64'};
0462 for i=1:4
0463 if((num>0 && num<2^(i*8-1)) || (num<0 && num>=-2^(i*8-1)))
0464 val=[key(i) data2byte(swapbytes(cast(num,cid{i})),'uint8')];
0465 return;
0466 end
0467 end
0468 error('unsupported integer');
0469
0470
0471 function val=D_(num)
0472 if(~isfloat(num))
0473 error('input is not a float');
0474 end
0475
0476 if(isa(num,'single'))
0477 val=['d' data2byte(swapbytes(num),'uint8')];
0478 else
0479 val=['D' data2byte(swapbytes(num),'uint8')];
0480 end
0481
0482 function data=I_a(num,type,dim,format)
0483 id=find(ismember('iUIlL',type));
0484
0485 if(id==0)
0486 error('unsupported integer array');
0487 end
0488
0489
0490
0491 if(id==1)
0492 data=data2byte(swapbytes(int8(num)),'uint8');
0493 blen=1;
0494 elseif(id==2)
0495 data=data2byte(swapbytes(uint8(num)),'uint8');
0496 blen=1;
0497 elseif(id==3)
0498 data=data2byte(swapbytes(int16(num)),'uint8');
0499 blen=2;
0500 elseif(id==4)
0501 data=data2byte(swapbytes(int32(num)),'uint8');
0502 blen=4;
0503 elseif(id==5)
0504 data=data2byte(swapbytes(int64(num)),'uint8');
0505 blen=8;
0506 end
0507
0508 if(nargin>=3 && length(dim)>=2 && prod(dim)~=dim(2))
0509 format='opt';
0510 end
0511 if((nargin<4 || strcmp(format,'opt')) && numel(num)>1)
0512 if(nargin>=3 && (length(dim)==1 || (length(dim)>=2 && prod(dim)~=dim(2))))
0513 cid=I_(uint32(max(dim)));
0514 data=['$' type '#' I_a(dim,cid(1)) data(:)'];
0515 else
0516 data=['$' type '#' I_(int32(numel(data)/blen)) data(:)'];
0517 end
0518 data=['[' data(:)'];
0519 else
0520 data=reshape(data,blen,numel(data)/blen);
0521 data(2:blen+1,:)=data;
0522 data(1,:)=type;
0523 data=data(:)';
0524 data=['[' data(:)' ']'];
0525 end
0526
0527 function data=D_a(num,type,dim,format)
0528 id=find(ismember('dD',type));
0529
0530 if(id==0)
0531 error('unsupported float array');
0532 end
0533
0534 if(id==1)
0535 data=data2byte(swapbytes(single(num)),'uint8');
0536 elseif(id==2)
0537 data=data2byte(swapbytes(double(num)),'uint8');
0538 end
0539
0540 if(nargin>=3 && length(dim)>=2 && prod(dim)~=dim(2))
0541 format='opt';
0542 end
0543 if((nargin<4 || strcmp(format,'opt')) && numel(num)>1)
0544 if(nargin>=3 && (length(dim)==1 || (length(dim)>=2 && prod(dim)~=dim(2))))
0545 cid=I_(uint32(max(dim)));
0546 data=['$' type '#' I_a(dim,cid(1)) data(:)'];
0547 else
0548 data=['$' type '#' I_(int32(numel(data)/(id*4))) data(:)'];
0549 end
0550 data=['[' data];
0551 else
0552 data=reshape(data,(id*4),length(data)/(id*4));
0553 data(2:(id*4+1),:)=data;
0554 data(1,:)=type;
0555 data=data(:)';
0556 data=['[' data(:)' ']'];
0557 end
0558
0559 function bytes=data2byte(varargin)
0560 bytes=typecast(varargin{:});
0561 bytes=char(bytes(:)');