Demo of JSONlab and output

1. example/demo_jsonlab_basic.m
2. output to example/demo_jsonlab_basic.m
3. Unit Testing test/run_jsonlab_test.m
4. Unit Testing test/run_jsonlab_test.m output

1. example/demo_jsonlab_basic.m

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%         Demonstration of Basic Utilities of JSONlab
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

rngstate = rand ('state');
randseed=hex2dec('623F9A9E');
clear data2json json2data

if(exist('isequaln')==0)
    isequaln=@isequal;
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a simple scalar value \n')
fprintf(1,'%%=================================================\n\n')

data2json=pi
savejson('',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  an empty array \n')
fprintf(1,'%%=================================================\n\n')

data2json=[]
savejson('',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  an ampty string \n')
fprintf(1,'%%=================================================\n\n')

data2json=''
savejson('emptystr',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a simple row vector \n')
fprintf(1,'%%=================================================\n\n')

data2json=1:3
savejson('',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a simple column vector \n')
fprintf(1,'%%=================================================\n\n')

data2json=(1:3)'
savejson('',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a string array \n')
fprintf(1,'%%=================================================\n\n')

data2json=['AC';'EG']
savejson('',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a string with escape symbols \n')
fprintf(1,'%%=================================================\n\n')

data2json=sprintf('AB\tCD\none"two')
savejson('str',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a mix-typed cell \n')
fprintf(1,'%%=================================================\n\n')

data2json={'a',true,[2;3]}
savejson('',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a 3-D array in nested array form\n')
fprintf(1,'%%=================================================\n\n')

data2json=reshape(1:(2*4*6),[2,4,6]);
savejson('',data2json,'NestArray',1)
json2data=loadjson(ans,'fastarrayparser',0)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a 3-D array in annotated array form\n')
fprintf(1,'%%=================================================\n\n')

data2json=reshape(1:(2*4*6),[2,4,6]);
savejson('',data2json,'NestArray',0)
json2data=loadjson(ans)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a 4-D array in annotated array form\n')
fprintf(1,'%%=================================================\n\n')

data2json=reshape(1:(2*4*3*2),[2,4,3,2]);
savejson('',data2json,'NestArray',0)  % nestarray for 4-D or above is not working
json2data=loadjson(ans)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a 3-D array in nested array form (JSONLab 1.9)\n')
fprintf(1,'%%=================================================\n\n')

data2json=reshape(1:(2*4*6),[2,4,6]);
savejson('',data2json,'NestArray',1,'FormatVersion',1.8)
json2data=loadjson(ans,'FormatVersion',1.8)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a 3-D array in annotated array form (JSONLab 1.9 or earlier)\n')
fprintf(1,'%%=================================================\n\n')

data2json=reshape(1:(2*4*6),[2,4,6]);
savejson('',data2json,'NestArray',0,'FormatVersion',1.8)
json2data=loadjson(ans,'FormatVersion',1.8)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a complex number\n')
fprintf(1,'%%=================================================\n\n')

data2json=1+2i
savejson('',data2json)
json2data=loadjson(ans) 
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a complex matrix\n')
fprintf(1,'%%=================================================\n\n')

data2json=magic(6);
data2json=data2json(:,1:3)+data2json(:,4:6)*1i
savejson('',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  MATLAB special constants\n')
fprintf(1,'%%=================================================\n\n')

data2json=[NaN Inf -Inf]
savejson('specials',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data.specials,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a real sparse matrix\n')
fprintf(1,'%%=================================================\n\n')

data2json=sprand(10,10,0.1)
savejson('sparse',data2json,'FloatFormat','%.18g')
json2data=loadjson(ans)
if(~isequaln(json2data.sparse,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a complex sparse matrix\n')
fprintf(1,'%%=================================================\n\n')

data2json=sprand(10,10,0.1);
data2json=data2json-data2json*1i
savejson('complex_sparse',data2json,'FloatFormat','%.18g')
json2data=loadjson(ans)
if(~isequaln(json2data.complex_sparse,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  an all-zero sparse matrix\n')
fprintf(1,'%%=================================================\n\n')

data2json=sparse(2,3);
savejson('all_zero_sparse',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data.all_zero_sparse,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  an empty sparse matrix\n')
fprintf(1,'%%=================================================\n\n')

data2json=sparse([]);
savejson('empty_sparse',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data.empty_sparse,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  an empty 0-by-0 real matrix\n')
fprintf(1,'%%=================================================\n\n')

data2json=[];
savejson('empty_0by0_real',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  an empty 0-by-3 real matrix\n')
fprintf(1,'%%=================================================\n\n')

data2json=zeros(0,3);
savejson('empty_0by3_real',data2json)
json2data=loadjson(ans)
if(~isequaln(json2data.empty_0by3_real,data2json))
    warning('conversion does not preserve original data');
end

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a sparse real column vector\n')
fprintf(1,'%%=================================================\n\n')

data2json=sparse([0,3,0,1,4]');
savejson('sparse_column_vector',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a sparse complex column vector\n')
fprintf(1,'%%=================================================\n\n')

data2json=data2json-1i*data2json;
savejson('complex_sparse_column_vector',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a sparse real row vector\n')
fprintf(1,'%%=================================================\n\n')

data2json=sparse([0,3,0,1,4]);
savejson('sparse_row_vector',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a sparse complex row vector\n')
fprintf(1,'%%=================================================\n\n')

data2json=data2json-1i*data2json;
savejson('complex_sparse_row_vector',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a structure\n')
fprintf(1,'%%=================================================\n\n')

data2json=struct('name','Think Different','year',1997,'magic',magic(3),...
                 'misfits',[Inf,NaN],'embedded',struct('left',true,'right',false))
savejson('astruct',data2json,struct('ParseLogical',1))
json2data=loadjson(ans)
class(json2data.astruct.embedded.left)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a structure array\n')
fprintf(1,'%%=================================================\n\n')

data2json=struct('name','Nexus Prime','rank',9);
data2json(2)=struct('name','Sentinel Prime','rank',9);
data2json(3)=struct('name','Optimus Prime','rank',9);
savejson('Supreme Commander',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a cell array\n')
fprintf(1,'%%=================================================\n\n')

data2json=cell(3,1);
data2json{1}=struct('buzz',1.1,'rex',1.2,'bo',1.3,'hamm',2.0,'slink',2.1,'potato',2.2,...
              'woody',3.0,'sarge',3.1,'etch',4.0,'lenny',5.0,'squeeze',6.0,'wheezy',7.0);
data2json{2}=struct('Ubuntu',['Kubuntu';'Xubuntu';'Lubuntu']);
data2json{3}=[10.04,10.10,11.04,11.10]
savejson('debian',data2json,struct('FloatFormat','%.2f'))
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  invalid field-name handling\n')
fprintf(1,'%%=================================================\n\n')

json2data=loadjson('{"ValidName":1, "_InvalidName":2, ":Field:":3, "项目":"绝密"}')

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a function handle\n')
fprintf(1,'%%=================================================\n\n')

data2json=@(x) x+1
savejson('handle',data2json)
json2data=loadjson(ans)

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a 2D cell array\n')
fprintf(1,'%%=================================================\n\n')

data2json={{1,{2,3}},{4,5},{6};{7},{8,9},{10}};
savejson('data2json',data2json)
json2data=loadjson(ans)  % only savejson works for cell arrays, loadjson has issues

fprintf(1,'\n%%=================================================\n')
fprintf(1,'%%  a 2D struct array\n')
fprintf(1,'%%=================================================\n\n')

data2json=repmat(struct('idx',0,'data','structs'),[2,3])
for i=1:6
    data2json(i).idx=i;
end
savejson('data2json',data2json)
json2data=loadjson(ans)


if(exist('datetime'))
    fprintf(1,'\n%%=================================================\n')
    fprintf(1,'%%  datetime object \n')
    fprintf(1,'%%=================================================\n\n')

    data2json=datetime({'8 April 2015','9 May 2015'}, 'InputFormat','d MMMM yyyy')
    savejson('',data2json)
    json2data=loadjson(ans)
end

if(exist('containers.Map'))
    fprintf(1,'\n%%=================================================\n')
    fprintf(1,'%%  a container.Maps object \n')
    fprintf(1,'%%=================================================\n\n')

    data2json=containers.Map({'Andy','William','Om'},{21,21,22})
    savejson('',data2json)
    json2data=loadjson(ans)
end

if(exist('istable'))
    fprintf(1,'\n%%=================================================\n')
    fprintf(1,'%%  a table object \n')
    fprintf(1,'%%=================================================\n\n')

    Names={'Andy','William','Om'}';
    Age=[21,21,22]';
    data2json=table(Names,Age)
    savejson('table',table(Names,Age))
    json2data=loadjson(ans)
end

if(exist('bandwidth'))
    fprintf(1,'\n%%=================================================\n')
    fprintf(1,'%%  use _ArrayShape_ \n')
    fprintf(1,'%%=================================================\n\n')

    lband=2;
    uband=3;
    data2json=spdiags(true(8,lband+uband+1),-uband:lband,5,8);
    data2json=full(double(data2json));
    data2json(data2json~=0)=find(data2json)

    savejson('',data2json,'usearrayshape',1)
    json2data=loadjson(ans,'fullarrayshape',1)
    
    savejson('',tril(data2json),'usearrayshape',1)
    json2data=loadjson(ans,'fullarrayshape',1)
    
    savejson('',triu(data2json+1i*data2json),'usearrayshape',1)
    json2data=loadjson(ans,'fullarrayshape',1)
    
    savejson('',tril(triu(int8(data2json))),'usearrayshape',1)
    json2data=loadjson(ans,'fullarrayshape',1)
    
    savejson('',data2json(:,1:5)+data2json(:,1:5)','usearrayshape',1)
    json2data=loadjson(ans,'fullarrayshape',1)
end

try
    val=zlibencode('test');
    fprintf(1,'\n%%=================================================\n')
    fprintf(1,'%%  a 2-D array in compressed array format\n')
    fprintf(1,'%%=================================================\n\n')

    data2json=eye(10);
    data2json(20,1)=1;
    savejson('',data2json,'Compression','zlib','CompressArraySize',0)  % nestarray for 4-D or above is not working
    json2data=loadjson(ans)
    if(~isequaln(json2data,data2json))
        warning('conversion does not preserve original data');
    end
catch
end

rand ('state',rngstate);

2. output to example/demo_jsonlab_basic.m

%=================================================
%  a simple scalar value 
%=================================================


data2json =

    3.1416


ans =

    '[3.141592654]
     '


json2data =

    3.1416


%=================================================
%  an empty array 
%=================================================


data2json =

     []


ans =

    '[]
     '


json2data =

  0×1 empty cell array


%=================================================
%  an ampty string 
%=================================================


data2json =

  0×0 empty char array


ans =

    '{
     	"emptystr":""
     }
     '


json2data = 

  struct with fields:

    emptystr: [1×0 char]


%=================================================
%  a simple row vector 
%=================================================


data2json =

     1     2     3


ans =

    '[1,2,3]
     '


json2data =

     1     2     3


%=================================================
%  a simple column vector 
%=================================================


data2json =

     1
     2
     3


ans =

    '[
     	[1],
     	[2],
     	[3]
     ]
     '


json2data =

     1
     2
     3


%=================================================
%  a string array 
%=================================================


data2json =

  2×2 char array

    'AC'
    'EG'


ans =

    '[
     	"AC",
     	"EG"
     ]
     '


json2data =

  1×2 cell array

    {'AC'}    {'EG'}


%=================================================
%  a string with escape symbols 
%=================================================


data2json =

    'AB	CD
     one"two'


ans =

    '{
     	"str":"AB\tCD\none\"two"
     }
     '


json2data = 

  struct with fields:

    str: 'AB→CD↵one"two'


%=================================================
%  a mix-typed cell 
%=================================================


data2json =

  1×3 cell array

    {'a'}    {[1]}    {2×1 double}


ans =

    '[
     	"a",
     	true,
     	[
     		[2],
     		[3]
     	]
     ]
     '


json2data =

  1×3 cell array

    {'a'}    {[1]}    {2×1 double}


%=================================================
%  a 3-D array in nested array form
%=================================================


ans =

    '[
     	[
     		[1,9,17,25,33,41],
     		[3,11,19,27,35,43],
     		[5,13,21,29,37,45],
     		[7,15,23,31,39,47]
     	],
     	[
     		[2,10,18,26,34,42],
     		[4,12,20,28,36,44],
     		[6,14,22,30,38,46],
     		[8,16,24,32,40,48]
     	]
     ]
     '


json2data(:,:,1) =

     1     3     5     7
     2     4     6     8


json2data(:,:,2) =

     9    11    13    15
    10    12    14    16


json2data(:,:,3) =

    17    19    21    23
    18    20    22    24


json2data(:,:,4) =

    25    27    29    31
    26    28    30    32


json2data(:,:,5) =

    33    35    37    39
    34    36    38    40


json2data(:,:,6) =

    41    43    45    47
    42    44    46    48


%=================================================
%  a 3-D array in annotated array form
%=================================================


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[2,4,6],
     	"_ArrayData_":[1,9,17,25,33,41,3,11,19,27,35,43,5,13,21,29,37,45,7,15,23,31,39,47,2,10,18,26,34,42,4,12,20,28,36,44,6,14,22,30,38,46,8,16,24,32,40,48]
     }
     '


json2data(:,:,1) =

     1     3     5     7
     2     4     6     8


json2data(:,:,2) =

     9    11    13    15
    10    12    14    16


json2data(:,:,3) =

    17    19    21    23
    18    20    22    24


json2data(:,:,4) =

    25    27    29    31
    26    28    30    32


json2data(:,:,5) =

    33    35    37    39
    34    36    38    40


json2data(:,:,6) =

    41    43    45    47
    42    44    46    48


%=================================================
%  a 4-D array in annotated array form
%=================================================


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[2,4,3,2],
     	"_ArrayData_":[1,25,9,33,17,41,3,27,11,35,19,43,5,29,13,37,21,45,7,31,15,39,23,47,2,26,10,34,18,42,4,28,12,36,20,44,6,30,14,38,22,46,8,32,16,40,24,48]
     }
     '


json2data(:,:,1,1) =

     1     3     5     7
     2     4     6     8


json2data(:,:,2,1) =

     9    11    13    15
    10    12    14    16


json2data(:,:,3,1) =

    17    19    21    23
    18    20    22    24


json2data(:,:,1,2) =

    25    27    29    31
    26    28    30    32


json2data(:,:,2,2) =

    33    35    37    39
    34    36    38    40


json2data(:,:,3,2) =

    41    43    45    47
    42    44    46    48


%=================================================
%  a 3-D array in nested array form (JSONLab 1.9)
%=================================================


ans =

    '[
     	[
     		[1,2],
     		[3,4],
     		[5,6],
     		[7,8]
     	],
     	[
     		[9,10],
     		[11,12],
     		[13,14],
     		[15,16]
     	],
     	[
     		[17,18],
     		[19,20],
     		[21,22],
     		[23,24]
     	],
     	[
     		[25,26],
     		[27,28],
     		[29,30],
     		[31,32]
     	],
     	[
     		[33,34],
     		[35,36],
     		[37,38],
     		[39,40]
     	],
     	[
     		[41,42],
     		[43,44],
     		[45,46],
     		[47,48]
     	]
     ]
     '


json2data(:,:,1) =

     1     3     5     7
     2     4     6     8


json2data(:,:,2) =

     9    11    13    15
    10    12    14    16


json2data(:,:,3) =

    17    19    21    23
    18    20    22    24


json2data(:,:,4) =

    25    27    29    31
    26    28    30    32


json2data(:,:,5) =

    33    35    37    39
    34    36    38    40


json2data(:,:,6) =

    41    43    45    47
    42    44    46    48


%=================================================
%  a 3-D array in annotated array form (JSONLab 1.9 or earlier)
%=================================================


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[2,4,6],
     	"_ArrayData_":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48]
     }
     '


json2data(:,:,1) =

     1     3     5     7
     2     4     6     8


json2data(:,:,2) =

     9    11    13    15
    10    12    14    16


json2data(:,:,3) =

    17    19    21    23
    18    20    22    24


json2data(:,:,4) =

    25    27    29    31
    26    28    30    32


json2data(:,:,5) =

    33    35    37    39
    34    36    38    40


json2data(:,:,6) =

    41    43    45    47
    42    44    46    48


%=================================================
%  a complex number
%=================================================


data2json =

   1.0000 + 2.0000i


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[1,1],
     	"_ArrayIsComplex_":true,
     	"_ArrayData_":[
     		[1],
     		[2]
     	]
     }
     '


json2data =

   1.0000 + 2.0000i


%=================================================
%  a complex matrix
%=================================================


data2json =

  35.0000 +26.0000i   1.0000 +19.0000i   6.0000 +24.0000i
   3.0000 +21.0000i  32.0000 +23.0000i   7.0000 +25.0000i
  31.0000 +22.0000i   9.0000 +27.0000i   2.0000 +20.0000i
   8.0000 +17.0000i  28.0000 +10.0000i  33.0000 +15.0000i
  30.0000 +12.0000i   5.0000 +14.0000i  34.0000 +16.0000i
   4.0000 +13.0000i  36.0000 +18.0000i  29.0000 +11.0000i


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[6,3],
     	"_ArrayIsComplex_":true,
     	"_ArrayData_":[
     		[35,1,6,3,32,7,31,9,2,8,28,33,30,5,34,4,36,29],
     		[26,19,24,21,23,25,22,27,20,17,10,15,12,14,16,13,18,11]
     	]
     }
     '


json2data =

  35.0000 +26.0000i   1.0000 +19.0000i   6.0000 +24.0000i
   3.0000 +21.0000i  32.0000 +23.0000i   7.0000 +25.0000i
  31.0000 +22.0000i   9.0000 +27.0000i   2.0000 +20.0000i
   8.0000 +17.0000i  28.0000 +10.0000i  33.0000 +15.0000i
  30.0000 +12.0000i   5.0000 +14.0000i  34.0000 +16.0000i
   4.0000 +13.0000i  36.0000 +18.0000i  29.0000 +11.0000i


%=================================================
%  MATLAB special constants
%=================================================


data2json =

   NaN   Inf  -Inf


ans =

    '{
     	"specials":["_NaN_","_Inf_","-_Inf_"]
     }
     '


json2data = 

  struct with fields:

    specials: [NaN Inf -Inf]


%=================================================
%  a real sparse matrix
%=================================================


data2json =

  (10,1)       0.0318
   (1,2)       0.7577
   (3,5)       0.3922
   (2,7)       0.7431
   (9,7)       0.7060
  (10,8)       0.2769
  (10,9)       0.0462
   (5,10)      0.6555
   (6,10)      0.1712
  (10,10)      0.0971


ans =

    '{
     	"sparse":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[10,10],
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[
     			[10,1,3,2,9,10,10,5,6,10],
     			[1,2,5,7,7,8,9,10,10,10],
     			[0.031832846377420676,0.757740130578333448,0.392227019534168164,0.743132468124916179,0.706046088019608775,0.276922984960889962,0.0461713906311539413,0.655477890177556644,0.171186687811561766,0.0971317812358475363]
     		]
     	}
     }
     '


json2data = 

  struct with fields:

    sparse: [10×10 double]


%=================================================
%  a complex sparse matrix
%=================================================


data2json =

   (2,2)      0.9597 - 0.9597i
   (8,2)      0.7513 - 0.7513i
   (5,3)      0.5853 - 0.5853i
   (7,5)      0.2238 - 0.2238i
   (9,5)      0.5060 - 0.5060i
   (4,7)      0.3404 - 0.3404i
   (8,7)      0.2551 - 0.2551i
   (1,8)      0.4984 - 0.4984i
  (10,8)      0.6991 - 0.6991i


ans =

    '{
     	"complex_sparse":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[10,10],
     		"_ArrayIsComplex_":true,
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[
     			[2,8,5,7,9,4,8,1,10],
     			[2,2,3,5,5,7,7,8,8],
     			[0.959743958516081075,0.751267059305652851,0.585267750979777346,0.22381193949113698,0.505957051665142377,0.340385726666133204,0.255095115459269106,0.498364051982142953,0.699076722656685967],
     			[-0.959743958516081075,-0.751267059305652851,-0.585267750979777346,-0.22381193949113698,-0.505957051665142377,-0.340385726666133204,-0.255095115459269106,-0.498364051982142953,-0.699076722656685967]
     		]
     	}
     }
     '


json2data = 

  struct with fields:

    complex_sparse: [10×10 double]


%=================================================
%  an all-zero sparse matrix
%=================================================


ans =

    '{
     	"all_zero_sparse":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[2,3],
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[]
     	}
     }
     '


json2data = 

  struct with fields:

    all_zero_sparse: [2×3 double]


%=================================================
%  an empty sparse matrix
%=================================================


ans =

    '{
     	"empty_sparse":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[0,0],
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[]
     	}
     }
     '


json2data = 

  struct with fields:

    empty_sparse: []


%=================================================
%  an empty 0-by-0 real matrix
%=================================================


ans =

    '{
     	"empty_0by0_real":[]
     }
     '


json2data = 

  struct with fields:

    empty_0by0_real: {0×1 cell}


%=================================================
%  an empty 0-by-3 real matrix
%=================================================


ans =

    '{
     	"empty_0by3_real":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[0,3],
     		"_ArrayData_":[]
     	}
     }
     '


json2data = 

  struct with fields:

    empty_0by3_real: [0×3 double]


%=================================================
%  a sparse real column vector
%=================================================


ans =

    '{
     	"sparse_column_vector":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[5,1],
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[
     			[2,4,5],
     			[3,1,4]
     		]
     	}
     }
     '


json2data = 

  struct with fields:

    sparse_column_vector: [5×1 double]


%=================================================
%  a sparse complex column vector
%=================================================


ans =

    '{
     	"complex_sparse_column_vector":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[5,1],
     		"_ArrayIsComplex_":true,
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[
     			[2,4,5],
     			[3,1,4],
     			[-3,-1,-4]
     		]
     	}
     }
     '


json2data = 

  struct with fields:

    complex_sparse_column_vector: [5×1 double]


%=================================================
%  a sparse real row vector
%=================================================


ans =

    '{
     	"sparse_row_vector":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[1,5],
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[
     			[2,4,5],
     			[3,1,4]
     		]
     	}
     }
     '


json2data = 

  struct with fields:

    sparse_row_vector: [0 3 0 1.0000e+00 4.0000e+00]


%=================================================
%  a sparse complex row vector
%=================================================


ans =

    '{
     	"complex_sparse_row_vector":{
     		"_ArrayType_":"double",
     		"_ArraySize_":[1,5],
     		"_ArrayIsComplex_":true,
     		"_ArrayIsSparse_":true,
     		"_ArrayData_":[
     			[2,4,5],
     			[3,1,4],
     			[-3,-1,-4]
     		]
     	}
     }
     '


json2data = 

  struct with fields:

    complex_sparse_row_vector: [1×5 double]


%=================================================
%  a structure
%=================================================


data2json = 

  struct with fields:

        name: 'Think Different'
        year: 1997
       magic: [3×3 double]
     misfits: [Inf NaN]
    embedded: [1×1 struct]


ans =

    '{
     	"astruct":{
     		"name":"Think Different",
     		"year":1997,
     		"magic":[
     			[8,1,6],
     			[3,5,7],
     			[4,9,2]
     		],
     		"misfits":["_Inf_","_NaN_"],
     		"embedded":{
     			"left":true,
     			"right":false
     		}
     	}
     }
     '


json2data = 

  struct with fields:

    astruct: [1×1 struct]


ans =

    'logical'


%=================================================
%  a structure array
%=================================================


ans =

    '{
     	"Supreme Commander":[
     		{
     			"name":"Nexus Prime",
     			"rank":9
     		},
     		{
     			"name":"Sentinel Prime",
     			"rank":9
     		},
     		{
     			"name":"Optimus Prime",
     			"rank":9
     		}
     	]
     }
     '


json2data = 

  struct with fields:

    Supreme_0x20_Commander: {[1×1 struct]  [1×1 struct]  [1×1 struct]}


%=================================================
%  a cell array
%=================================================


data2json =

  3×1 cell array

    {1×1 struct}
    {1×1 struct}
    {1×4 double}


ans =

    '{
     	"debian":[
     		[
     			{
     				"buzz":1.10,
     				"rex":1.20,
     				"bo":1.30,
     				"hamm":2.00,
     				"slink":2.10,
     				"potato":2.20,
     				"woody":3.00,
     				"sarge":3.10,
     				"etch":4.00,
     				"lenny":5.00,
     				"squeeze":6.00,
     				"wheezy":7.00
     			},
     			{
     				"Ubuntu":[
     					"Kubuntu",
     					"Xubuntu",
     					"Lubuntu"
     				]
     			},
     			[10.04,10.10,11.04,11.10]
     		]
     	]
     }
     '


json2data = 

  struct with fields:

    debian: {{1×3 cell}}


%=================================================
%  invalid field-name handling
%=================================================


json2data = 

  struct with fields:

             ValidName: 1
     x0x5F_InvalidName: 2
     x0x3A_Field_0x3A_: 3
    x0x9879__0xE79BAE_: '绝密'


%=================================================
%  a function handle
%=================================================


data2json =

  function_handle with value:

    @(x)x+1


ans =

    '{
     	"handle":{
     		"function":"@(x)x+1",
     		"type":"anonymous",
     		"file":"\/home\/fangq\/space\/git\/Project\/jsonlab\/examples\/demo_jsonlab_basic.m",
     		"workspace":[
     			{
     			}
     		],
     		"within_file_path":""
     	}
     }
     '


json2data = 

  struct with fields:

    handle: [1×1 struct]


%=================================================
%  a 2D cell array
%=================================================


ans =

    '{
     	"data2json":[
     		[
     			[
     				1,
     				[
     					2,
     					3
     				]
     			],
     			[
     				4,
     				5
     			],
     			[
     				6
     			]
     		],
     		[
     			[
     				7
     			],
     			[
     				8,
     				9
     			],
     			[
     				10
     			]
     		]
     	]
     }
     '


json2data = 

  struct with fields:

    data2json: {{1×3 cell}  {1×3 cell}}


%=================================================
%  a 2D struct array
%=================================================


data2json = 

  2×3 struct array with fields:

    idx
    data


ans =

    '{
     	"data2json":[
     		[
     			{
     				"idx":1,
     				"data":"structs"
     			},
     			{
     				"idx":2,
     				"data":"structs"
     			}
     		],
     		[
     			{
     				"idx":3,
     				"data":"structs"
     			},
     			{
     				"idx":4,
     				"data":"structs"
     			}
     		],
     		[
     			{
     				"idx":5,
     				"data":"structs"
     			},
     			{
     				"idx":6,
     				"data":"structs"
     			}
     		]
     	]
     }
     '


json2data = 

  struct with fields:

    data2json: {{1×2 cell}  {1×2 cell}  {1×2 cell}}


%=================================================
%  datetime object 
%=================================================


data2json = 

  1×2 datetime array

   08-Apr-2015   09-May-2015


ans =

    '[
     	{
     		"Format":"dd-MMM-uuuu",
     		"TimeZone":"",
     		"Year":2015,
     		"Month":4,
     		"Day":8,
     		"Hour":0,
     		"Minute":0,
     		"Second":0
     	},
     	{
     		"Format":"dd-MMM-uuuu",
     		"TimeZone":"",
     		"Year":2015,
     		"Month":5,
     		"Day":9,
     		"Hour":0,
     		"Minute":0,
     		"Second":0
     	}
     ]
     '


json2data =

  1×2 cell array

    {1×1 struct}    {1×1 struct}


%=================================================
%  a container.Maps object 
%=================================================


data2json = 

  Map with properties:

        Count: 3
      KeyType: char
    ValueType: double


ans =

    '{
     	"Andy":21,
     	"Om":22,
     	"William":21
     }
     '


json2data = 

  struct with fields:

       Andy: 21
         Om: 22
    William: 21


%=================================================
%  a table object 
%=================================================


data2json =

  3×2 table

       Names       Age
    ___________    ___

    {'Andy'   }    21 
    {'William'}    21 
    {'Om'     }    22 


ans =

    '{
     	"table":{
     		"_TableCols_":[
     			"Names",
     			"Age"
     		],
     		"_TableRows_":[],
     		"_TableRecords_":[
     			[
     				"Andy",
     				21
     			],
     			[
     				"William",
     				21
     			],
     			[
     				"Om",
     				22
     			]
     		]
     	}
     }
     '


json2data = 

  struct with fields:

    table: [3×2 table]


%=================================================
%  use _ArrayShape_ 
%=================================================


data2json =

     1     6    11     0     0     0     0     0
     2     7    12    17     0     0     0     0
     3     8    13    18    23     0     0     0
     4     9    14    19    24    29     0     0
     0    10    15    20    25    30    35     0


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[5,8],
     	"_ArrayZipSize_":[6,5],
     	"_ArrayShape_":[
     		"band",
     		2,
     		3
     	],
     	"_ArrayData_":[11,17,23,29,35,6,12,18,24,30,1,7,13,19,25,0,2,8,14,20,0,0,3,9,15,0,0,0,4,10]
     }
     '


json2data =

     1     6    11     0     0     0     0     0
     2     7    12    17     0     0     0     0
     3     8    13    18    23     0     0     0
     4     9    14    19    24    29     0     0
     0    10    15    20    25    30    35     0


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[5,8],
     	"_ArrayZipSize_":[4,5],
     	"_ArrayShape_":[
     		"lowerband",
     		3
     	],
     	"_ArrayData_":[1,7,13,19,25,0,2,8,14,20,0,0,3,9,15,0,0,0,4,10]
     }
     '


json2data =

     1     0     0     0     0     0     0     0
     2     7     0     0     0     0     0     0
     3     8    13     0     0     0     0     0
     4     9    14    19     0     0     0     0
     0    10    15    20    25     0     0     0


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[5,8],
     	"_ArrayIsComplex_":true,
     	"_ArrayZipSize_":[2,3,5],
     	"_ArrayShape_":[
     		"upperband",
     		2
     	],
     	"_ArrayData_":[11,17,23,29,35,6,12,18,24,30,1,7,13,19,25,11,17,23,29,35,6,12,18,24,30,1,7,13,19,25]
     }
     '


json2data =

  Columns 1 through 6

   1.0000 + 1.0000i   6.0000 + 6.0000i  11.0000 +11.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   7.0000 + 7.0000i  12.0000 +12.0000i  17.0000 +17.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   0.0000 + 0.0000i  13.0000 +13.0000i  18.0000 +18.0000i  23.0000 +23.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i  19.0000 +19.0000i  24.0000 +24.0000i  29.0000 +29.0000i
   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i   0.0000 + 0.0000i  25.0000 +25.0000i  30.0000 +30.0000i

  Columns 7 through 8

   0.0000 + 0.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   0.0000 + 0.0000i
   0.0000 + 0.0000i   0.0000 + 0.0000i
  35.0000 +35.0000i   0.0000 + 0.0000i


ans =

    '{
     	"_ArrayType_":"int8",
     	"_ArraySize_":[5,8],
     	"_ArrayShape_":"diag",
     	"_ArrayData_":[1,7,13,19,25]
     }
     '


json2data =

  5×8 int8 matrix

    1    0    0    0    0    0    0    0
    0    7    0    0    0    0    0    0
    0    0   13    0    0    0    0    0
    0    0    0   19    0    0    0    0
    0    0    0    0   25    0    0    0


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[5,5],
     	"_ArrayZipSize_":[4,5],
     	"_ArrayShape_":[
     		"lowersymmband",
     		3
     	],
     	"_ArrayData_":[2,14,26,38,50,0,8,20,32,44,0,0,14,26,38,0,0,0,4,10]
     }
     '


json2data =

     2     8    14     4     0
     8    14    20    26    10
    14    20    26    32    38
     4    26    32    38    44
     0    10    38    44    50


%=================================================
%  a 2-D array in compressed array format
%=================================================


ans =

    '{
     	"_ArrayType_":"double",
     	"_ArraySize_":[20,10],
     	"_ArrayZipSize_":[1,200],
     	"_ArrayZipType_":"zlib",
     	"_ArrayZipData_":"eJxjYACBD/YMNAGj5o6aO2ruKBgFgwtQL10DAMHODQY=
     "
     }
     '


json2data =

     1     0     0     0     0     0     0     0     0     0
     0     1     0     0     0     0     0     0     0     0
     0     0     1     0     0     0     0     0     0     0
     0     0     0     1     0     0     0     0     0     0
     0     0     0     0     1     0     0     0     0     0
     0     0     0     0     0     1     0     0     0     0
     0     0     0     0     0     0     1     0     0     0
     0     0     0     0     0     0     0     1     0     0
     0     0     0     0     0     0     0     0     1     0
     0     0     0     0     0     0     0     0     0     1
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     0     0     0     0     0     0     0     0     0     0
     1     0     0     0     0     0     0     0     0     0

3. Unit Testing test/run_jsonlab_test.m

function run_jsonlab_test(tests)
%
% run_jsonlab_test
%   or
% run_jsonlab_test(tests)
% run_jsonlab_test({'js','jso','bj','bjo','jmap','bmap','jpath','bugs'})
%
% Unit testing for JSONLab JSON, BJData/UBJSON encoders and decoders
%
% authors:Qianqian Fang (q.fang <at> neu.edu)
% date: 2020/06/08
%
% input:
%      tests: is a cell array of strings, possible elements include
%         'js':  test savejson/loadjson
%         'jso': test savejson/loadjson special options
%         'bj':  test savebj/loadbj
%         'bjo': test savebj/loadbj special options
%         'jmap': test jsonmmap features in loadjson
%         'bmap': test jsonmmap features in loadbj
%         'jpath': test jsonpath
%         'bugs': test specific bug fixes
%
% 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 == 0)
    tests = {'js', 'jso', 'bj', 'bjo', 'jmap', 'bmap', 'jpath', 'bugs'};
end

%%
if (ismember('js', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test JSON functions\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));

    test_jsonlab('single integer', @savejson, 5, '[5]');
    test_jsonlab('single float', @savejson, 3.14, '[3.14]');
    test_jsonlab('nan', @savejson, nan, '["_NaN_"]');
    test_jsonlab('inf', @savejson, inf, '["_Inf_"]');
    test_jsonlab('-inf', @savejson, -inf, '["-_Inf_"]');
    test_jsonlab('large integer', @savejson, uint64(2^64), '[18446744073709551616]');
    test_jsonlab('large negative integer', @savejson, int64(-2^63), '[-9223372036854775808]');
    test_jsonlab('boolean as 01', @savejson, [true, false], '[1,0]', 'compact', 1);
    test_jsonlab('empty array', @savejson, [], '[]');
    test_jsonlab('empty cell', @savejson, {}, '[]');
    test_jsonlab('empty struct', @savejson, struct, '{}', 'compact', 1);
    test_jsonlab('empty struct with fields', @savejson, repmat(struct('a', 1), 0, 1), '[]');
    test_jsonlab('empty string', @savejson, '', '""', 'compact', 1);
    test_jsonlab('string escape', @savejson, sprintf('jdata\n\b\ashall\tprevail\t"\"\\'), '"jdata\n\b\ashall\tprevail\t\"\"\\"');
    if (exist('string'))
        test_jsonlab('string type', @savejson, string(sprintf('jdata\n\b\ashall\tprevail')), '["jdata\n\b\ashall\tprevail"]', 'compact', 1);
        test_jsonlab('string array', @savejson, [string('jdata'), string('shall'), string('prevail')], '["jdata","shall","prevail"]', 'compact', 1);
    end
    test_jsonlab('empty name', @savejson, loadjson('{"":""}'), '{"":""}', 'compact', 1);
    if (exist('containers.Map'))
        test_jsonlab('empty name with map', @savejson, loadjson('{"":""}', 'usemap', 1), '{"":""}', 'compact', 1);
        test_jsonlab('indentation', @savejson, savejson('s', containers.Map({'a', 'b'}, {[], struct('c', 1.1, 'd', struct('e', {1, 2}))})), ...
                     '"{\n\t\"s\":{\n\t\t\"a\":[],\n\t\t\"b\":{\n\t\t\t\"c\":1.1,\n\t\t\t\"d\":[\n\t\t\t\t{\n\t\t\t\t\t\"e\":1\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"e\":2\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t}\n}\n"');
        test_jsonlab('key longer than 63', @savejson, loadjson('{"...........":""}', 'usemap', 0), '{"...........":""}', 'compact', 1);
    end
    test_jsonlab('row vector', @savejson, [1, 2, 3], '[1,2,3]');
    test_jsonlab('column vector', @savejson, [1; 2; 3], '[[1],[2],[3]]', 'compact', 1);
    test_jsonlab('mixed array', @savejson, {'a', 1, 0.9}, '["a",1,0.9]', 'compact', 1);
    test_jsonlab('mixed array from string', @savejson, loadjson('["a",{"c":1}, [2,3]]'), '["a",{"c":1},[2,3]]', 'compact', 1);
    test_jsonlab('char array', @savejson, ['AC'; 'EG'], '["AC","EG"]', 'compact', 1);
    test_jsonlab('maps', @savejson, struct('a', 1, 'b', 'test'), '{"a":1,"b":"test"}', 'compact', 1);
    test_jsonlab('2d array', @savejson, [1, 2, 3; 4, 5, 6], '[[1,2,3],[4,5,6]]', 'compact', 1);
    test_jsonlab('non-uniform 2d array', @savejson, {[1, 2], [3, 4, 5], [6, 7]}, '[[1,2],[3,4,5],[6,7]]', 'compact', 1);
    test_jsonlab('non-uniform array with length multiple of first element', @savejson, {[1, 2], [3, 4, 5, 6], [7, 8]}, '[[1,2],[3,4,5,6],[7,8]]', 'compact', 1);
    test_jsonlab('1d array with flexible white space', @savejson, loadjson(sprintf(' [ +1, \n -2e3 \n , 3.0E+00 ,\r+4e-0] ')), '[1,-2000,3,4]', 'compact', 1);
    test_jsonlab('2d array with flexible white space', @savejson, loadjson(sprintf(' [\r [\n 1 , \r\n  2\n, 3] ,\n[ 4, 5 , \t 6\t]\n] ')), '[[1,2,3],[4,5,6]]', 'compact', 1);
    test_jsonlab('3d (row-major) nested array', @savejson, reshape(1:(2 * 3 * 2), 2, 3, 2), ...
                 '[[[1,7],[3,9],[5,11]],[[2,8],[4,10],[6,12]]]', 'compact', 1, 'nestarray', 1);
    test_jsonlab('3d (column-major) nested array', @savejson, reshape(1:(2 * 3 * 2), 2, 3, 2), ...
                 '[[[1,2],[3,4],[5,6]],[[7,8],[9,10],[11,12]]]', 'compact', 1, 'nestarray', 1, 'formatversion', 1.9);
    test_jsonlab('3d annotated array', @savejson, reshape(int8(1:(2 * 3 * 2)), 2, 3, 2), ...
                 '{"_ArrayType_":"int8","_ArraySize_":[2,3,2],"_ArrayData_":[1,7,3,9,5,11,2,8,4,10,6,12]}', 'compact', 1);
    test_jsonlab('complex number', @savejson, single(2 + 4i), ...
                 '{"_ArrayType_":"single","_ArraySize_":[1,1],"_ArrayIsComplex_":true,"_ArrayData_":[[2],[4]]}', 'compact', 1);
    test_jsonlab('empty sparse matrix', @savejson, sparse(2, 3), ...
                 '{"_ArrayType_":"double","_ArraySize_":[2,3],"_ArrayIsSparse_":true,"_ArrayData_":[]}', 'compact', 1);
    test_jsonlab('real sparse matrix', @savejson, sparse([0, 3, 0, 1, 4]'), ...
                 '{"_ArrayType_":"double","_ArraySize_":[5,1],"_ArrayIsSparse_":true,"_ArrayData_":[[2,4,5],[3,1,4]]}', 'compact', 1);
    test_jsonlab('complex sparse matrix', @savejson, sparse([0, 3i, 0, 1, 4i].'), ...
                 '{"_ArrayType_":"double","_ArraySize_":[5,1],"_ArrayIsComplex_":true,"_ArrayIsSparse_":true,"_ArrayData_":[[2,4,5],[0,1,0],[3,0,4]]}', 'compact', 1);
    test_jsonlab('heterogeneous cell', @savejson, {{1, {2, 3}}, {4, 5}, {6}; {7}, {8, 9}, {10}}, ...
                 '[[[1,[2,3]],[4,5],[6]],[[7],[8,9],[10]]]', 'compact', 1);
    test_jsonlab('struct array', @savejson, repmat(struct('i', 1.1, 'd', 'str'), [1, 2]), ...
                 '[{"i":1.1,"d":"str"},{"i":1.1,"d":"str"}]', 'compact', 1);
    test_jsonlab('encoded fieldnames', @savejson, struct(encodevarname('_i'), 1, encodevarname('i_'), 'str'), ...
                 '{"_i":1,"i_":"str"}', 'compact', 1);
    if (exist('OCTAVE_VERSION', 'builtin') ~= 0)
        test_jsonlab('encoded fieldnames without decoding', @savejson, struct(encodevarname('_i'), 1, encodevarname('i_'), 'str'), ...
                     '{"_i":1,"i_":"str"}', 'compact', 1, 'UnpackHex', 0);
    else
        test_jsonlab('encoded fieldnames without decoding', @savejson, struct(encodevarname('_i'), 1, encodevarname('i_'), 'str'), ...
                     '{"x0x5F_i":1,"i_":"str"}', 'compact', 1, 'UnpackHex', 0);
    end
    if (exist('containers.Map'))
        test_jsonlab('containers.Map with char keys', @savejson, containers.Map({'Andy', '^_^'}, {true, '-_-'}), ...
                     '{"Andy":true,"^_^":"-_-"}', 'compact', 1, 'usemap', 1);
        test_jsonlab('containers.Map with number keys', @savejson, containers.Map({1.1, 1.2}, {true, '-_-'}), ...
                     '{"_MapData_":[[1.1,true],[1.2,"-_-"]]}', 'compact', 1, 'usemap', 1);
    end
    if (exist('dictionary'))
        test_jsonlab('dictionary with string keys', @savejson, dictionary([string('Andy'), string('^_^')], {true, '-_-'}), ...
                     '{"Andy":true,"^_^":"-_-"}', 'compact', 1, 'usemap', 1);
        test_jsonlab('dictionary with cell keys', @savejson, dictionary({'Andy', '^_^'}, {true, '-_-'}), ...
                     '{"_MapData_":[["Andy",true],["^_^","-_-"]]}', 'compact', 1, 'usemap', 1);
        test_jsonlab('dictionary with number keys', @savejson, dictionary({1.1, 1.2}, {true, '-_-'}), ...
                     '{"_MapData_":[[1.1,true],[1.2,"-_-"]]}', 'compact', 1, 'usemap', 1);
    end
    if (exist('istable'))
        test_jsonlab('simple table', @savejson, table({'Andy', '^_^'}, {true, '-_-'}), ...
                     '{"_TableCols_":["Var1","Var2"],"_TableRows_":[],"_TableRecords_":[["Andy","^_^"],[true,"-_-"]]}', 'compact', 1);
    end
    if (exist('bandwidth'))
        lband = 2;
        uband = 1;
        a = double(full(spdiags(true(4, lband + uband + 1), -uband:lband, 3, 4)));
        a(a ~= 0) = find(a);

        test_jsonlab('lower band matrix', @savejson, tril(a), ...
                     '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayZipSize_":[2,3],"_ArrayShape_":["lowerband",1],"_ArrayData_":[1,5,9,0,2,6]}', 'compact', 1, 'usearrayshape', 1);
        test_jsonlab('upper band matrix', @savejson, triu(a), ...
                     '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayZipSize_":[3,3],"_ArrayShape_":["upperband",2],"_ArrayData_":[7,11,0,4,8,12,1,5,9]}', 'compact', 1, 'usearrayshape', 1);
        test_jsonlab('diag matrix', @savejson, tril(triu(a)), ...
                     '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayShape_":"diag","_ArrayData_":[1,5,9]}', 'compact', 1, 'usearrayshape', 1);
        test_jsonlab('band matrix', @savejson, a, ...
                     '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayZipSize_":[4,3],"_ArrayShape_":["band",2,1],"_ArrayData_":[7,11,0,4,8,12,1,5,9,0,2,6]}', 'compact', 1, 'usearrayshape', 1);
        a = a(:, 1:3);
        a = uint8(tril(a) + tril(a)');
        test_jsonlab('symmetric band matrix', @savejson, a, ...
                     '{"_ArrayType_":"uint8","_ArraySize_":[3,3],"_ArrayZipSize_":[2,3],"_ArrayShape_":["lowersymmband",1],"_ArrayData_":[2,10,18,0,2,6]}', 'compact', 1, 'usearrayshape', 1);
        a(a == 0) = 1;
        test_jsonlab('lower triangular matrix', @savejson, tril(a), ...
                     '{"_ArrayType_":"uint8","_ArraySize_":[3,3],"_ArrayShape_":"lower","_ArrayData_":[2,2,10,1,6,18]}', 'compact', 1, 'usearrayshape', 1);
        test_jsonlab('upper triangular matrix', @savejson, triu(a), ...
                     '{"_ArrayType_":"uint8","_ArraySize_":[3,3],"_ArrayShape_":"upper","_ArrayData_":[2,2,1,10,6,18]}', 'compact', 1, 'usearrayshape', 1);
    end
    try
        val = zlibencode('test');
        a = uint8(eye(5));
        a(20, 1) = 1;
        test_jsonlab('zlib/zip compression (level 6)', @savejson, a, ...
                     sprintf('{"_ArrayType_":"uint8","_ArraySize_":[20,5],"_ArrayZipSize_":[1,100],"_ArrayZipType_":"zlib","_ArrayZipData_":"eJxjZAABRhwkxQBsDAACIQAH"}'), ...
                     'compact', 1, 'Compression', 'zlib', 'CompressArraySize', 0);  % nestarray for 4-D or above is not working
        test_jsonlab('gzip compression (level 6)', @savejson, a, ...
                     sprintf('{"_ArrayType_":"uint8","_ArraySize_":[20,5],"_ArrayZipSize_":[1,100],"_ArrayZipType_":"gzip","_ArrayZipData_":"H4sIAAAAAAAAA2NkAAFGHCTFAGwMAF9Xq6VkAAAA"}'), ...
                     'compact', 1, 'Compression', 'gzip', 'CompressArraySize', 0);  % nestarray for 4-D or above is not working
        test_jsonlab('lzma compression (level 5)', @savejson, a, ...
                     sprintf('{"_ArrayType_":"uint8","_ArraySize_":[20,5],"_ArrayZipSize_":[1,100],"_ArrayZipType_":"lzma","_ArrayZipData_":"XQAAEABkAAAAAAAAAAAAgD1IirvlZSEY7DH///taoAA="}'), ...
                     'compact', 1, 'Compression', 'lzma', 'CompressArraySize', 0);  % nestarray for 4-D or above is not working
    catch
    end
end
%%
if (ismember('jso', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test JSON function options\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));

    test_jsonlab('boolean', @savejson, [true, false], '[true,false]', 'compact', 1, 'ParseLogical', 1);
    test_jsonlab('nan option', @savejson, nan, '["_nan_"]', 'NaN', '"_nan_"');
    test_jsonlab('inf option', @savejson, -inf, '["-inf"]', 'Inf', '"$1inf"');
    test_jsonlab('output int format', @savejson, uint8(5), '[  5]', 'IntFormat', '%3d');
    test_jsonlab('output float format', @savejson, pi, '[3.142]', 'FloatFormat', '%5.3f');
    test_jsonlab('remove singlet array', @savejson, {struct('a', 1), 5}, '[{"a":1},5]', 'compact', 1, 'SingletArray', 0);
    test_jsonlab('keep singlet array', @savejson, {struct('a', 1), 5}, '[[{"a":[1]}],[5]]', 'compact', 1, 'SingletArray', 1);
    test_jsonlab('make null object roundtrip', @savejson, loadjson('{"a":null}'), '{"a":null}', 'EmptyArrayAsNull', 1, 'compact', 1);
    test_jsonlab('test no datalink', @savejson, loadjson(savejson('a', struct(encodevarname('_DataLink_'), ...
                                                                              '../examples/example2.json:$.glossary.title'))), '{"a":[{"_DataLink_":"../examples/example2.json:$.glossary.title"}]}', 'compact', 1, 'SingletArray', 1);
    test_jsonlab('test maxlinklevel', @savejson, loadjson(savejson('a', struct(encodevarname('_DataLink_'), ...
                                                                               '../examples/example2.json:$.glossary.title')), 'maxlinklevel', 1), '{"a":"example glossary"}', 'compact', 1, 'SingletArray', 1);
end

%%
if (ismember('bj', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test Binary JSON functions\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));

    test_jsonlab('uint8 integer', @savebj, 2^8 - 1, 'U<255>', 'debug', 1);
    test_jsonlab('uint16 integer', @savebj, 2^8, 'u<256>', 'debug', 1);
    test_jsonlab('int8 integer', @savebj, -2^7, 'i<-128>', 'debug', 1);
    test_jsonlab('int16 integer', @savebj, -2^7 - 1, 'I<-129>', 'debug', 1);
    test_jsonlab('int32 integer', @savebj, -2^15 - 1, 'l<-32769>', 'debug', 1);
    test_jsonlab('uint16 integer', @savebj, 2^16 - 1, 'u<65535>', 'debug', 1);
    test_jsonlab('uint32 integer', @savebj, 2^16, 'm<65536>', 'debug', 1);
    test_jsonlab('uint32 integer', @savebj, 2^32 - 1, 'm<4294967295>', 'debug', 1);
    test_jsonlab('int32 integer', @savebj, -2^31, 'l<-2147483648>', 'debug', 1);
    test_jsonlab('single float', @savebj, 3.14, 'D<3.14>', 'debug', 1);
    test_jsonlab('nan', @savebj, nan, 'D<NaN>', 'debug', 1);
    test_jsonlab('inf', @savebj, inf, 'D<Inf>', 'debug', 1);
    test_jsonlab('-inf', @savebj, -inf, 'D<-Inf>', 'debug', 1);
    test_jsonlab('uint64 integer', @savebj, uint64(2^64), 'M<18446744073709551616>', 'debug', 1);
    test_jsonlab('int64 negative integer', @savebj, int64(-2^63), 'L<-9223372036854775808>', 'debug', 1);
    test_jsonlab('boolean as 01', @savebj, [true, false], '[U<1>U<0>]', 'debug', 1, 'nestarray', 1);
    test_jsonlab('empty array', @savebj, [], 'Z', 'debug', 1);
    test_jsonlab('empty cell', @savebj, {}, 'Z', 'debug', 1);
    test_jsonlab('empty string', @savebj, '', 'SU<0>', 'debug', 1);
    test_jsonlab('skip no-op before marker and after value', @savebj, loadbj(char(['NN[NU' char(5) 'NNNU' char(1) ']'])), '[$U#U<2><5><1>', 'debug', 1);
    test_jsonlab('string escape', @savebj, sprintf('jdata\n\b\ashall\tprevail\t"\"\\'), sprintf('SU<25>jdata\n\b\ashall\tprevail\t\"\"\\'), 'debug', 1);
    if (exist('string') && isa(string('jdata'), 'string'))
        test_jsonlab('string type', @savebj, string(sprintf('jdata\n\b\ashall\tprevail')), sprintf('[SU<21>jdata\n\b\ashall\tprevail]'), 'debug', 1);
        test_jsonlab('string array', @savebj, [string('jdata'); string('shall'); string('prevail')], '[[SU<5>jdataSU<5>shallSU<7>prevail]]', 'debug', 1);
    end
    test_jsonlab('empty name', @savebj, loadbj(['{U' 0 'U' 2 '}']), '{U<0>U<2>}', 'debug', 1);
    if (exist('containers.Map'))
        test_jsonlab('empty name with map', @savebj, loadbj(['{U' 0 'U' 2 '}'], 'usemap', 1), '{U<0>U<2>}', 'debug', 1);
        test_jsonlab('key longer than 63', @savebj, loadbj(['{U' 11 '...........U' 2 '}'], 'usemap', 0), '{U<11>...........U<2>}', 'debug', 1);
    end
    test_jsonlab('row vector', @savebj, [1, 2, 3], '[$U#U<3><1><2><3>', 'debug', 1);
    test_jsonlab('column vector', @savebj, [1; 2; 3], '[$U#[$U#U<2><3><1><1><2><3>', 'debug', 1);
    test_jsonlab('mixed array', @savebj, {'a', 1, 0.9}, '[CaU<1>D<0.9>]', 'debug', 1);
    test_jsonlab('char array', @savebj, ['AC'; 'EG'], '[SU<2>ACSU<2>EG]', 'debug', 1);
    test_jsonlab('maps', @savebj, struct('a', 1, 'b', 'test'), '{U<1>aU<1>U<1>bSU<4>test}', 'debug', 1);
    test_jsonlab('2d array', @savebj, [1, 2, 3; 4, 5, 6], '[$U#[$U#U<2><2><3><1><2><3><4><5><6>', 'debug', 1);
    test_jsonlab('3d (row-major) nested array', @savebj, reshape(1:(2 * 3 * 2), 2, 3, 2), ...
                 '[[[U<1>U<7>][U<3>U<9>][U<5>U<11>]][[U<2>U<8>][U<4>U<10>][U<6>U<12>]]]', 'debug', 1, 'nestarray', 1);
    test_jsonlab('3d (column-major) nested array', @savebj, reshape(1:(2 * 3 * 2), 2, 3, 2), ...
                 '[[[U<1>U<2>][U<3>U<4>][U<5>U<6>]][[U<7>U<8>][U<9>U<10>][U<11>U<12>]]]', 'debug', 1, 'nestarray', 1, 'formatversion', 1.9);
    test_jsonlab('3d annotated array', @savebj, reshape(int8(1:(2 * 3 * 2)), 2, 3, 2), ...
                 '{U<11>_ArrayType_SU<4>int8U<11>_ArraySize_[$U#U<3><2><3><2>U<11>_ArrayData_[$U#U<12><1><7><3><9><5><11><2><8><4><10><6><12>}', 'debug', 1);
    test_jsonlab('complex number', @savebj, single(2 + 4i), ...
                 '{U<11>_ArrayType_SU<6>singleU<11>_ArraySize_[$U#U<2><1><1>U<16>_ArrayIsComplex_TU<11>_ArrayData_[$U#[$U#U<2><2><1><2><4>}', 'debug', 1);
    test_jsonlab('empty sparse matrix', @savebj, sparse(2, 3), ...
                 '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><2><3>U<15>_ArrayIsSparse_TU<11>_ArrayData_Z}', 'debug', 1);
    test_jsonlab('real sparse matrix', @savebj, sparse([0, 3, 0, 1, 4]'), ...
                 '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><5><1>U<15>_ArrayIsSparse_TU<11>_ArrayData_[$U#[$U#U<2><2><3><2><4><5><3><1><4>}', 'debug', 1);
    test_jsonlab('complex sparse matrix', @savebj, sparse([0, 3i, 0, 1, 4i].'), ...
                 '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><5><1>U<16>_ArrayIsComplex_TU<15>_ArrayIsSparse_TU<11>_ArrayData_[$U#[$U#U<2><3><3><2><4><5><0><1><0><3><0><4>}', 'debug', 1);
    test_jsonlab('heterogeneous cell', @savebj, {{1, {2, 3}}, {4, 5}, {6}; {7}, {8, 9}, {10}}, ...
                 '[[[U<1>[U<2>U<3>]][U<4>U<5>][U<6>]][[U<7>][U<8>U<9>][U<10>]]]', 'debug', 1);
    test_jsonlab('struct array', @savebj, repmat(struct('i', 1.1, 'd', 'str'), [1, 2]), ...
                 '[{U<1>iD<1.1>U<1>dSU<3>str}{U<1>iD<1.1>U<1>dSU<3>str}]', 'debug', 1);
    test_jsonlab('encoded fieldnames', @savebj, struct(encodevarname('_i'), 1, encodevarname('i_'), 'str'), ...
                 '{U<2>_iU<1>U<2>i_SU<3>str}', 'debug', 1);
    if (exist('OCTAVE_VERSION', 'builtin') ~= 0)
        test_jsonlab('encoded fieldnames without decoding', @savebj, struct(encodevarname('_i'), 1, encodevarname('i_'), 'str'), ...
                     '{U<2>_iU<1>U<2>i_SU<3>str}', 'debug', 1, 'UnpackHex', 0);
    else
        test_jsonlab('encoded fieldnames without decoding', @savebj, struct(encodevarname('_i'), 1, encodevarname('i_'), 'str'), ...
                     '{U<7>x0x5F_iU<1>U<2>i_SU<3>str}', 'debug', 1, 'UnpackHex', 0);
    end
    if (exist('containers.Map'))
        test_jsonlab('containers.Map with char keys', @savebj, containers.Map({'Andy', '^_^'}, {true, '-_-'}), ...
                     '{U<4>AndyTU<3>^_^SU<3>-_-}', 'debug', 1, 'usemap', 1);
    end
    if (exist('dictionary'))
        test_jsonlab('dictionary with string keys', @savebj, dictionary([string('Andy'), string('^_^')], {true, '-_-'}), ...
                     '{U<4>AndyTU<3>^_^SU<3>-_-}', 'debug', 1, 'usemap', 1);
        test_jsonlab('dictionary with cell keys', @savebj, dictionary({'Andy', '^_^'}, {true, '-_-'}), ...
                     '{U<4>AndyTU<3>^_^SU<3>-_-}', 'debug', 1,  'usemap', 1);
    end
    if (exist('istable'))
        test_jsonlab('simple table', @savebj, table({'Andy', '^_^'}, {true, '-_-'}), ...
                     '{U<11>_TableCols_[SU<4>Var1SU<4>Var2]U<11>_TableRows_ZU<14>_TableRecords_[[SU<4>AndySU<3>^_^][TSU<3>-_-]]}', 'debug', 1);
    end
    if (exist('bandwidth'))
        lband = 2;
        uband = 1;
        a = double(full(spdiags(true(4, lband + uband + 1), -uband:lband, 3, 4)));
        a(a ~= 0) = find(a);

        test_jsonlab('lower band matrix', @savebj, tril(a), ...
                     '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<14>_ArrayZipSize_[$U#U<2><2><3>U<12>_ArrayShape_[SU<9>lowerbandU<1>]U<11>_ArrayData_[$U#U<6><1><5><9><0><2><6>}', 'debug', 1, 'usearrayshape', 1);
        test_jsonlab('upper band matrix', @savebj, triu(a), ...
                     '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<14>_ArrayZipSize_[$U#U<2><3><3>U<12>_ArrayShape_[SU<9>upperbandU<2>]U<11>_ArrayData_[$U#U<9><7><11><0><4><8><12><1><5><9>}', 'debug', 1, 'usearrayshape', 1);
        test_jsonlab('diag matrix', @savebj, tril(triu(a)), ...
                     '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<12>_ArrayShape_SU<4>diagU<11>_ArrayData_[$U#U<3><1><5><9>}', 'debug', 1, 'usearrayshape', 1);
        test_jsonlab('band matrix', @savebj, a, ...
                     '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<14>_ArrayZipSize_[$U#U<2><4><3>U<12>_ArrayShape_[SU<4>bandU<2>U<1>]U<11>_ArrayData_[$U#U<12><7><11><0><4><8><12><1><5><9><0><2><6>}', 'debug', 1, 'usearrayshape', 1);
        a = a(:, 1:3);
        a = uint8(tril(a) + tril(a)');
        test_jsonlab('symmetric band matrix', @savebj, a, ...
                     '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><3><3>U<14>_ArrayZipSize_[$U#U<2><2><3>U<12>_ArrayShape_[SU<13>lowersymmbandU<1>]U<11>_ArrayData_[$U#U<6><2><10><18><0><2><6>}', 'debug', 1, 'usearrayshape', 1);
        a(a == 0) = 1;
        test_jsonlab('lower triangular matrix', @savebj, tril(a), ...
                     '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><3><3>U<12>_ArrayShape_SU<5>lowerU<11>_ArrayData_[$U#U<6><2><2><10><1><6><18>}', 'debug', 1, 'usearrayshape', 1);
        test_jsonlab('upper triangular matrix', @savebj, triu(a), ...
                     '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><3><3>U<12>_ArrayShape_SU<5>upperU<11>_ArrayData_[$U#U<6><2><2><1><10><6><18>}', 'debug', 1, 'usearrayshape', 1);
    end
    try
        val = zlibencode('test');
        a = uint8(eye(5));
        a(20, 1) = 1;
        test_jsonlab('zlib/zip compression (level 6)', @savebj, a, ...
                     '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><20><5>U<14>_ArrayZipSize_[$U#U<2><1><100>U<14>_ArrayZipType_SU<4>zlibU<14>_ArrayZipData_[$U#U<18><120><156><99><100><0><1><70><28><36><197><0><108><12><0><2><33><0><7>}', ...
                     'debug', 1, 'Compression', 'zlib', 'CompressArraySize', 0);  % nestarray for 4-D or above is not working
        test_jsonlab('gzip compression (level 6)', @savebj, a, ...
                     '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><20><5>U<14>_ArrayZipSize_[$U#U<2><1><100>U<14>_ArrayZipType_SU<4>gzipU<14>_ArrayZipData_[$U#U<30><31><139><8><0><0><0><0><0><0><3><99><100><0><1><70><28><36><197><0><108><12><0><95><87><171><165><100><0><0><0>}', ...
                     'debug', 1, 'Compression', 'gzip', 'CompressArraySize', 0);  % nestarray for 4-D or above is not working
        test_jsonlab('lzma compression (level 5)', @savebj, a, ...
                     '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><20><5>U<14>_ArrayZipSize_[$U#U<2><1><100>U<14>_ArrayZipType_SU<4>lzmaU<14>_ArrayZipData_[$U#U<32><93><0><0><16><0><100><0><0><0><0><0><0><0><0><0><128><61><72><138><187><229><101><33><24><236><49><255><255><251><90><160><0>}', ...
                     'debug', 1, 'Compression', 'lzma', 'CompressArraySize', 0);  % nestarray for 4-D or above is not working
    catch
    end
end

%%
if (ismember('bjo', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test Binary JSON function options\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));

    test_jsonlab('remove ubjson optimized array header', @savebj, [1, 2, 3], '[U<1>U<2>U<3>]', 'debug', 1, 'nestarray', 1);
    test_jsonlab('limit to ubjson signed integer', @savebj, 256, 'I<256>', 'debug', 1, 'ubjson', 1);
    test_jsonlab('limit to ubjson integer markers', @savebj, 2^32 - 1, 'L<4294967295>', 'debug', 1, 'ubjson', 1);
    test_jsonlab('H marker for out of bound integer', @savebj, 2^64 - 1, 'HU<20>18446744073709551616', 'debug', 1, 'ubjson', 1);
    test_jsonlab('do not downcast integers to the shortest format', @savebj, int32(5), 'l<5>', 'debug', 1, 'keeptype', 1);
    test_jsonlab('do not downcast integer array to the shortest format', @savebj, int32([5, 6]), '[$l#U<2><5><6>', 'debug', 1, 'keeptype', 1);
    test_jsonlab('test little endian uint32', @savebj, typecast(uint8('abcd'), 'uint32'), 'mabcd', 'endian', 'L');
    test_jsonlab('test big endian uint32', @savebj, typecast(uint8('abcd'), 'uint32'), 'mdcba', 'endian', 'B');
    test_jsonlab('test little endian double', @savebj, typecast(uint8('01234567'), 'double'), 'D01234567', 'endian', 'L');
    test_jsonlab('test big endian double', @savebj, typecast(uint8('01234567'), 'double'), 'D76543210', 'endian', 'B');
    test_jsonlab('test default int endian for savebj', @savebj, typecast(uint8('jd'), 'uint16'), 'ujd');
    test_jsonlab('test default int endian for saveubjson', @saveubjson, typecast(uint8('jd'), 'uint16'), 'Idj');
    test_jsonlab('test default float endian for savebj', @savebj, typecast(uint8('1e05'), 'single'), 'd1e05');
    test_jsonlab('test default float endian for saveubjson', @saveubjson, typecast(uint8('12345678'), 'double'), 'D87654321');
end

%%
if (ismember('jmap', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test JSON mmap\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));

    test_jsonlab('mmap of a 1D numerical array', @savejson, loadjson('[1,2,3]', 'mmaponly', 1), '[["$",[1,7]]]', 'compact', 1);
    test_jsonlab('mmap of a 1D mixed array', @savejson, loadjson('[1,"2",3]', 'mmaponly', 1), '[["$",[1,9]]]', 'compact', 1);
    test_jsonlab('mmap of a 2D array', @savejson, loadjson('[[1,2,3],[4,5,6]]', 'mmaponly', 1), '[["$",[1,17]]]', 'compact', 1);
    test_jsonlab('mmap of concatenated json', @savejson, loadjson('[1,2,3][4,5,6]', 'mmaponly', 1), '[["$",[1,7]],["$1",[8,7]]]', 'compact', 1);
    test_jsonlab('mmap of concatenated json objects', @savejson, loadjson('[1,2,3]{"a":[4,5]}', 'mmaponly', 1), '[["$",[1,7]],["$1",[8,11]],["$1.a",[13,5]]]', 'compact', 1);
    test_jsonlab('mmap of an array with an object', @savejson, loadjson('[1,2,{"a":3}]', 'mmaponly', 1), ...
                 '[["$",[1,13]],["$[0]",[2,1]],["$[1]",[4,1]],["$[2]",[6,7]],["$[2].a",[11,1]]]', 'compact', 1);
    test_jsonlab('mmap of an object', @savejson, loadjson('{"a":1,"b":[2,3]}', 'mmaponly', 1), ...
                 '[["$",[1,17]],["$.a",[6,1]],["$.b",[12,5]]]', 'compact', 1);
    test_jsonlab('mmap of object with white-space', @savejson, loadjson('{"a":1 , "b"  :  [2,3]}', 'mmaponly', 1), ...
                 '[["$",[1,23]],["$.a",[6,1]],["$.b",[18,5,2]]]', 'compact', 1);
    test_jsonlab('mmapinclude option', @savejson, loadjson('[[1,2,3],{"a":[4,5]}]', 'mmaponly', 1, 'mmapinclude', '.a'), ...
                 '[["$[1].a",[15,5]]]', 'compact', 1);
    test_jsonlab('mmapexclude option', @savejson, loadjson('[[1,2,3],{"a":[4,5]}]', 'mmaponly', 1, 'mmapexclude', {'[0]', '[1]', '[2]'}), ...
                 '[["$",[1,21]]]', 'compact', 1);
    test_jsonlab('json with indentation', @savejson, loadjson(savejson({[1, 2, 3], struct('a', [4, 5])}), 'mmaponly', 1, 'mmapinclude', '.a'), ...
                 '[["$[1].a",[22,7]]]', 'compact', 1);
end

%%
if (ismember('bmap', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test Binary JSON mmap\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));

    test_jsonlab('mmap of a 1D numerical array', @savejson, loadbj(savebj([1, 2, 3]), 'mmaponly', 1), '[["$",[1,9]]]', 'compact', 1);
    test_jsonlab('mmap of a 1D mixed array', @savejson, loadbj(savebj({1, '2', 3}), 'mmaponly', 1), '[["$",[1,8]],["$[0]",[2,2]],["$[1]",[4,2]],["$[2]",[6,2]]]', 'compact', 1);
    test_jsonlab('mmap of a 2D array', @savejson, loadbj(savebj([[1, 2, 3], [4, 5, 6]]), 'mmaponly', 1), '[["$",[1,12]]]', 'compact', 1);
    test_jsonlab('mmap of an array with an object', @savejson, loadbj(savebj({1, 2, struct('a', 3)}), 'mmaponly', 1), ...
                 '[["$",[1,13]],["$[0]",[2,2]],["$[1]",[4,2]],["$[2]",[6,7]],["$[2].a",[10,2]]]', 'compact', 1);
    test_jsonlab('mmap of an object', @savejson, loadbj(savebj(struct('a', 1, 'b', [2, 3])), 'mmaponly', 1), ...
                 '[["$",[1,18]],["$.a",[5,2]],["$.b",[10,8]]]', 'compact', 1);
    test_jsonlab('mmapinclude option', @savejson, loadbj(savebj({[1, 2, 3], struct('a', [4, 5])}), 'mmaponly', 1, 'mmapinclude', '.a'), ...
                 '[["$[1].a",[15,8]]]', 'compact', 1);
    test_jsonlab('mmapexclude option', @savejson, loadbj(savebj({[1, 2, 3], struct('a', [4, 5])}), 'mmaponly', 1, 'mmapexclude', {'[0]', '[1]', '[2]'}), ...
                 '[["$",[1,24]]]', 'compact', 1);
    test_jsonlab('test multiple root objects with N padding', @savejson, loadbj([savebj({[1, 2, 3], struct('a', [4, 5])}) 'NNN' savebj(struct('b', [4, 5]))], 'mmaponly', 1, 'mmapinclude', '.b'), ...
                 '[["$1.b",[32,8]]]', 'compact', 1);
end

%%
if (ismember('jpath', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test JSONPath\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));

    testdata = struct('book', struct('title', {'Minch', 'Qui-Gon', 'Ben'}, 'author', {'Yoda', 'Jinn', 'Kenobi'}), 'game', struct('title', 'Mario', 'new', struct('title', 'Minecraft')));
    test_jsonlab('jsonpath of .key', @savejson, jsonpath(testdata, '$.game.title'), '"Mario"', 'compact', 1);
    test_jsonlab('jsonpath of ..key', @savejson, jsonpath(testdata, '$.book..title'), '["Minch","Qui-Gon","Ben"]', 'compact', 1);
    test_jsonlab('jsonpath of ..key cross objects', @savejson, jsonpath(testdata, '$..title'), '["Minch","Qui-Gon","Ben","Mario","Minecraft"]', 'compact', 1);
    test_jsonlab('jsonpath of [index]', @savejson, jsonpath(testdata, '$..title[1]'), '["Qui-Gon"]', 'compact', 1);
    test_jsonlab('jsonpath of [-index]', @savejson, jsonpath(testdata, '$..title[-1]'), '["Minecraft"]', 'compact', 1);
    test_jsonlab('jsonpath of [start:end]', @savejson, jsonpath(testdata, '$..title[0:2]'), '["Minch","Qui-Gon","Ben"]', 'compact', 1);
    test_jsonlab('jsonpath of [:end]', @savejson, jsonpath(testdata, '$..title[:2]'), '["Minch","Qui-Gon","Ben"]', 'compact', 1);
    test_jsonlab('jsonpath of [start:]', @savejson, jsonpath(testdata, '$..title[1:]'), '["Qui-Gon","Ben","Mario","Minecraft"]', 'compact', 1);
    test_jsonlab('jsonpath of [-start:-end]', @savejson, jsonpath(testdata, '$..title[-2:-1]'), '["Mario","Minecraft"]', 'compact', 1);
    test_jsonlab('jsonpath of [-start:]', @savejson, jsonpath(testdata, '$..title[:-3]'), '["Minch","Qui-Gon","Ben"]', 'compact', 1);
    test_jsonlab('jsonpath of [:-end]', @savejson, jsonpath(testdata, '$..title[-1:]'), '["Minecraft"]', 'compact', 1);
    test_jsonlab('jsonpath of object with [index]', @savejson, jsonpath(testdata, '$.book[1]'), '{"title":"Qui-Gon","author":"Jinn"}', 'compact', 1);
    test_jsonlab('jsonpath of element after [index]', @savejson, jsonpath(testdata, '$.book[1:2].author'), '["Jinn","Kenobi"]', 'compact', 1);
    test_jsonlab('jsonpath of [*] and deep scan', @savejson, jsonpath(testdata, '$.book[*]..author'), '["Yoda","Jinn","Kenobi"]', 'compact', 1);
    test_jsonlab('jsonpath of [*] after deep scan', @savejson, jsonpath(testdata, '$.book[*]..author[*]'), '["Yoda","Jinn","Kenobi"]', 'compact', 1);
    test_jsonlab('jsonpath use [] instead of .', @savejson, jsonpath(testdata, '$[book][2][author]'), '"Kenobi"', 'compact', 1);
    test_jsonlab('jsonpath use [] with [start:end]', @savejson, jsonpath(testdata, '$[book][1:2][author]'), '["Jinn","Kenobi"]', 'compact', 1);
    test_jsonlab('jsonpath use . after [start:end]', @savejson, jsonpath(testdata, '$[book][0:1].author'), '["Yoda","Jinn"]', 'compact', 1);
    test_jsonlab('jsonpath use [''*''] and ["*"]', @savejson, jsonpath(testdata, '$["book"][:-2][''author'']'), '["Yoda","Jinn"]', 'compact', 1);
    test_jsonlab('jsonpath use combinations', @savejson, jsonpath(testdata, '$..["book"][:-2].author[*][0]'), '["Yoda"]', 'compact', 1);

    if (exist('containers.Map'))
        testdata = loadjson(savejson('', testdata), 'usemap', 1);
        test_jsonlab('jsonpath use combinations', @savejson, jsonpath(testdata, '$..["book"].author[*][0]'), '["Yoda"]', 'compact', 1);
    end
    if (exist('istable'))
        testdata = struct('book', table({'Minch', 'Qui-Gon', 'Ben'}, {'Yoda', 'Jinn', 'Kenobi'}, 'variablenames', {'title', 'author'}), 'game', struct('title', 'Mario'));
        test_jsonlab('jsonpath use combinations', @savejson, jsonpath(testdata, '$..["book"].author[*][0]'), '["Yoda"]', 'compact', 1);
    end

    testdata = struct('book', struct(encodevarname('_title'), {'Minch', 'Qui-Gon', 'Ben'}, encodevarname(' author.last.name '), {'Yoda', 'Jinn', 'Kenobi'}), encodevarname('game.arcade'), struct('title', 'Mario'));
    test_jsonlab('jsonpath encoded field name in []', @savejson, jsonpath(testdata, '$..["book"][_title][*][0]'), '["Minch"]', 'compact', 1);
    test_jsonlab('jsonpath encoded field name after .', @savejson, jsonpath(testdata, '$..["book"]._title[*][0]'), '["Minch"]', 'compact', 1);
    test_jsonlab('jsonpath encoded field name after ..', @savejson, jsonpath(testdata, '$.._title'), '["Minch","Qui-Gon","Ben"]', 'compact', 1);
    test_jsonlab('jsonpath multiple encoded field name between quotes', @savejson, jsonpath(testdata, '$..["book"]['' author.last.name ''][*][1]'), '["Jinn"]', 'compact', 1);
    test_jsonlab('jsonpath multiple encoded field name between []', @savejson, jsonpath(testdata, '$..["book"][ author.last.name ][*][1]'), '["Jinn"]', 'compact', 1);
    test_jsonlab('jsonpath escape . using \.', @savejson, jsonpath(testdata, '$.game\.arcade'), '{"title":"Mario"}', 'compact', 1);
    test_jsonlab('jsonpath escape . using []', @savejson, jsonpath(testdata, '$.[game.arcade]'), '{"title":"Mario"}', 'compact', 1);
    test_jsonlab('jsonpath scan struct array', @savejson, jsonpath(testdata, '$.book[*]..author[*]'), '[]', 'compact', 1);

    clear testdata;
end

%%
if (ismember('bugs', tests))
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    fprintf('Test bug fixes\n');
    fprintf(sprintf('%s\n', char(ones(1, 79) * 61)));
    test_jsonlab('simplify cell arrays mixing numbers and chars', @savejson, loadjson('[1,0,"-","L",900]'), '[1,0,"-","L",900]', 'compact', 1);
    test_jsonlab('simplify cell arrays with string elements', @savejson, loadjson('["j","s","o","n"]'), '["j","s","o","n"]', 'compact', 1);
end

4. Unit Testing test/run_jsonlab_test.m output

  ===============================================================================
  Test JSON functions
  ===============================================================================
  Testing single integer: ok
  	output:'[5]'
  	loadjson successfully restored the input
  Testing single float: ok
  	output:'[3.14]'
  	loadjson successfully restored the input
  Testing nan: ok
  	output:'["_NaN_"]'
  	loadjson successfully restored the input
  Testing inf: ok
  	output:'["_Inf_"]'
  	loadjson successfully restored the input
  Testing -inf: ok
  	output:'["-_Inf_"]'
  	loadjson successfully restored the input
  Testing large integer: ok
  	output:'[18446744073709551616]'
  Testing large negative integer: ok
  	output:'[-9223372036854775808]'
  	loadjson successfully restored the input
  Testing boolean as 01: ok
  	output:'[1,0]'
  	loadjson successfully restored the input
  Testing empty array: ok
  	output:'[]'
  Testing empty cell: ok
  	output:'[]'
  Testing empty struct: ok
  	output:'{}'
  Testing empty struct with fields: ok
  	output:'[]'
  Testing empty string: ok
  	output:'""'
  Testing string escape: ok
  	loadjson successfully restored the input
  Testing jsonpath use . after [start:end]: ok
  	output:'["Yoda","Jinn"]'
  	loadjson successfully restored the input
  Testing jsonpath use ['*'] and ["*"]: ok
  	output:'["Yoda","Jinn"]'
  	loadjson successfully restored the input
  Testing jsonpath use combinations: ok
  	output:'["Yoda"]'
  	loadjson successfully restored the input
  Testing jsonpath use combinations: ok
  	output:'["Yoda"]'
  	loadjson successfully restored the input
  Testing jsonpath use combinations: ok
  	output:'["Yoda"]'
  	loadjson successfully restored the input
  Testing jsonpath encoded field name in []: ok
  	output:'["Minch"]'
  	loadjson successfully restored the input
  Testing jsonpath encoded field name after .: ok
  	output:'["Minch"]'
  	loadjson successfully restored the input
  Testing jsonpath encoded field name after ..: ok
  	output:'["Minch","Qui-Gon","Ben"]'
  	loadjson successfully restored the input
  Testing jsonpath multiple encoded field name between quotes: ok
  	output:'["Jinn"]'
  	loadjson successfully restored the input
  Testing jsonpath multiple encoded field name between []: ok
  	output:'["Jinn"]'
  	loadjson successfully restored the input
  Testing jsonpath escape . using \.: ok
  	output:'{"title":"Mario"}'
  	loadjson successfully restored the input
  Testing jsonpath escape . using []: ok
  	output:'{"title":"Mario"}'
  	loadjson successfully restored the input
  Testing jsonpath scan struct array: ok
  	output:'[]'
  ===============================================================================
  Test bug fixes
  ===============================================================================
  Testing simplify cell arrays mixing numbers and chars: ok
  	output:'[1,0,"-","L",900]'
  	loadjson successfully restored the input
  Testing simplify cell arrays with string elements: ok
  	output:'["j","s","o","n"]'
  	loadjson successfully restored the input
Powered by Habitat