From 46bbfa92db3b543cba28118cbddedf44a135545d Mon Sep 17 00:00:00 2001 From: Qianqian Fang <fangqq@gmail.com> Date: Sun, 13 Mar 2022 23:25:51 -0400 Subject: [PATCH] support empty name, which is valid in JSON, fix #79 --- decodevarname.m | 4 ++++ loadbj.m | 2 +- loadjson.m | 4 ++-- savebj.m | 14 +++----------- savejson.m | 37 +++++++++++++++---------------------- test/run_jsonlab_test.m | 4 ++++ 6 files changed, 29 insertions(+), 36 deletions(-) diff --git a/decodevarname.m b/decodevarname.m index 66298d2..f1ab141 100644 --- a/decodevarname.m +++ b/decodevarname.m @@ -46,6 +46,10 @@ if(isunpack) h2u=@hex2unicode; newname=regexprep(name,'(^x|_){1}0x([0-9a-fA-F]+)_','${h2u($2)}'); else + if(isunpack && strcmp(name,'x0x0_')) + newname=''; + return; + end pos=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','start'); pend=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','end'); if(isempty(pos)) diff --git a/loadbj.m b/loadbj.m index 86ffa60..79bed88 100644 --- a/loadbj.m +++ b/loadbj.m @@ -493,7 +493,7 @@ function [object, pos, mmap] = parse_object(inputstr, pos, varargin) [str, pos] = parse_name(inputstr, pos, varargin{:}); end if isempty(str) - error_pos('Name of value at position %d cannot be empty', inputstr, pos); + str='x0x0_'; % empty name is valid in BJData/UBJSON, decodevarname('x0x0_') restores '\0' end if(nargout>2) varargin{1}.jsonpath_=[origpath,'.',str]; diff --git a/loadjson.m b/loadjson.m index 1ee4c12..e6ace03 100644 --- a/loadjson.m +++ b/loadjson.m @@ -576,8 +576,8 @@ function [object, pos, index_esc, mmap] = parse_object(inputstr, pos, esc, index if cc ~= '}' while 1 [str, pos, index_esc] = parseStr(inputstr, pos, esc, index_esc, varargin{:}); - if isempty(str) - pos=error_pos('Name of value at position %d cannot be empty',inputstr,pos); + if isempty(str) && ~usemap + str='x0x0_'; % empty name is valid in JSON, decodevarname('x0x0_') restores '\0' end [pos, w1, w2]=parse_char(inputstr, pos, ':'); if(nargout>3) diff --git a/savebj.m b/savebj.m index 28f7bb3..8493c50 100644 --- a/savebj.m +++ b/savebj.m @@ -477,17 +477,11 @@ if(~strcmp(Omarker{1},'{')) else om0=Omarker{1}; end -len=prod(dim); -forcearray= (len>1 || (varargin{1}.singletarray==1 && level>0)); if(~isempty(name)) - if(forcearray) - txt=[N_(decodevarname(name,varargin{:}),varargin{:}) om0]; - end + txt=[N_(decodevarname(name,varargin{:}),varargin{:}) om0]; else - if(forcearray) - txt=om0; - end + txt=om0; end for i=1:dim(1) if(~isempty(names{i})) @@ -495,9 +489,7 @@ for i=1:dim(1) level+(dim(1)>1),varargin{:})]; end end -if(forcearray) - txt=[txt Omarker{2}]; -end +txt=[txt Omarker{2}]; %%------------------------------------------------------------------------- function txt=str2ubjson(name,item,level,varargin) diff --git a/savejson.m b/savejson.m index 7be8352..8a21418 100644 --- a/savejson.m +++ b/savejson.m @@ -470,14 +470,12 @@ if(~strcmp(item.KeyType,'char')) return; end -len=prod(dim); -forcearray= (len>1 || (varargin{1}.singletarray==1 && level>0)); ws=varargin{1}.whitespaces_; padding0=repmat(ws.tab,1,level); nl=ws.newline; -if(isempty(item)) - if(~isempty(name)) +if(isempty(item)) + if(~isempty(name)) txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":[]'}; else txt={padding0, '[]'}; @@ -486,30 +484,25 @@ if(isempty(item)) return; end if(~isempty(name)) - if(forcearray) - txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":{', nl}; - end + txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":{', nl}; else - if(forcearray) - txt={padding0, '{', nl}; - end + txt={padding0, '{', nl}; end for i=1:dim(1) - if(~isempty(names{i})) - txt{end+1}=obj2json(names{i},val{i},... - level+(dim(1)>1),varargin{:}); - if(i<length(names)) - txt{end+1}=','; - end - if(i<dim(1)) - txt{end+1}=nl; - end + if(isempty(names{i})) + txt{end+1}=obj2json('x0x0_',val{i},level+(dim(1)>1),varargin{:}); + else + txt{end+1}=obj2json(names{i},val{i},level+(dim(1)>1),varargin{:}); + end + if(i<length(names)) + txt{end+1}=','; + end + if(i<dim(1)) + txt{end+1}=nl; end end -if(forcearray) - txt(end+1:end+3)={nl,padding0,'}'}; -end +txt(end+1:end+3)={nl,padding0,'}'}; txt = sprintf('%s',txt{:}); %%------------------------------------------------------------------------- diff --git a/test/run_jsonlab_test.m b/test/run_jsonlab_test.m index 11a9a97..3d9735e 100644 --- a/test/run_jsonlab_test.m +++ b/test/run_jsonlab_test.m @@ -49,6 +49,8 @@ if(ismember('js',tests)) 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); + test_jsonlab('empty name with map',@savejson,loadjson('{"":""}','usemap',1),'{"":""}','compact',1); 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); @@ -182,6 +184,8 @@ if(ismember('bj',tests)) 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); + test_jsonlab('empty name with map',@savebj,loadbj(['{U' 0 'U' 2 '}'],'usemap',1),'{U<0>U<2>}','debug',1); 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); -- GitLab