Skip to content

Commit

Permalink
[feat] automatically switch to map object when key length > 63
Browse files Browse the repository at this point in the history
  • Loading branch information
fangq committed Jan 11, 2024
1 parent ee24122 commit ef5b472
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 2 deletions.
26 changes: 25 additions & 1 deletion loadbj.m
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,18 @@
if (nargout > 1 || mmaponly)
mmap{end + 1} = {opt.jsonpath_, pos};
[data{jsoncount}, pos, newmmap] = parse_object(inputstr, pos, opt);
if (pos < 0)
opt.usemap = 1;
[data{jsoncount}, pos, newmmap] = parse_object(inputstr, -pos, opt);
end
mmap{end}{2} = [mmap{end}{2}, pos - mmap{end}{2}];
mmap = [mmap(:); newmmap(:)];
else
[data{jsoncount}, pos] = parse_object(inputstr, pos, opt);
if (pos < 0)
opt.usemap = 1;
[data{jsoncount}, pos] = parse_object(inputstr, -pos, opt);
end
end
case '['
if (nargout > 1 || mmaponly)
Expand Down Expand Up @@ -424,6 +432,10 @@
return
case '{'
[varargout{1:nargout}] = parse_object(inputstr, varargout{2}, varargin{:});
if (varargout{2} < 0)
varargin{1}.usemap = 1;
[varargout{1:nargout}] = parse_object(inputstr, -varargout{2}, varargin{:});
end
return
case {'i', 'U', 'I', 'u', 'l', 'm', 'L', 'M', 'h', 'd', 'D'}
[varargout{1:2}] = parse_number(inputstr, varargout{2}, varargin{:});
Expand Down Expand Up @@ -455,6 +467,7 @@

%% -------------------------------------------------------------------------
function [object, pos, mmap] = parse_object(inputstr, pos, varargin)
oldpos = pos;
if (nargout > 2)
mmap = {};
origpath = varargin{1}.jsonpath_;
Expand Down Expand Up @@ -486,6 +499,11 @@
else
[str, pos] = parse_name(inputstr, pos, varargin{:});
end
if (length(str) > 63)
pos = -oldpos;
object = [];
return
end
if isempty(str)
str = 'x0x0_'; % empty name is valid in BJData/UBJSON, decodevarname('x0x0_') restores '\0'
end
Expand All @@ -502,7 +520,13 @@
if (usemap)
object(str) = val;
else
object.(encodevarname(str, varargin{:})) = val;
str = encodevarname(str, varargin{:});
if (length(str) > 63)
pos = -oldpos;
object = [];
return
end
object.(str) = val;
end
[cc, pos] = next_char(inputstr, pos);
if (count >= 0 && num >= count) || cc == '}'
Expand Down
26 changes: 25 additions & 1 deletion loadjson.m
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,18 @@
if (nargout > 1 || opt.mmaponly)
mmap{end + 1} = {opt.jsonpath_, [pos, 0, w1]};
[data{jsoncount}, pos, index_esc, newmmap] = parse_object(inputstr, pos, esc, index_esc, opt);
if (pos < 0)
opt.usemap = 1;
[data{jsoncount}, pos, index_esc, newmmap] = parse_object(inputstr, -pos, esc, index_esc, opt);
end
mmap{end}{2}(2) = pos - mmap{end}{2}(1);
mmap = [mmap(:); newmmap(:)];
else
[data{jsoncount}, pos, index_esc] = parse_object(inputstr, pos, esc, index_esc, opt);
if (pos < 0)
opt.usemap = 1;
[data{jsoncount}, pos, index_esc] = parse_object(inputstr, -pos, esc, index_esc, opt);
end
end
case '['
if (nargout > 1 || opt.mmaponly)
Expand Down Expand Up @@ -536,6 +544,10 @@
return
case '{'
[varargout{1:nargout}] = parse_object(inputstr, pos, esc, index_esc, varargin{:});
if (varargout{2} < 0)
varargin{1}.usemap = 1;
[varargout{1:nargout}] = parse_object(inputstr, -varargout{2}, esc, index_esc, varargin{:});
end
return
case {'-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
[varargout{1:2}] = parse_number(inputstr, pos, varargin{:});
Expand Down Expand Up @@ -563,6 +575,7 @@

%% -------------------------------------------------------------------------
function [object, pos, index_esc, mmap] = parse_object(inputstr, pos, esc, index_esc, varargin)
oldpos = pos;
if (nargout > 3)
mmap = {};
origpath = varargin{1}.jsonpath_;
Expand All @@ -578,6 +591,11 @@
if cc ~= '}'
while 1
[str, pos, index_esc] = parseStr(inputstr, pos, esc, index_esc, varargin{:});
if (length(str) > 63)
pos = -oldpos;
object = [];
return
end
if isempty(str) && ~usemap
str = 'x0x0_'; % empty name is valid in JSON, decodevarname('x0x0_') restores '\0'
end
Expand All @@ -594,7 +612,13 @@
if (usemap)
object(str) = val;
else
object.(encodevarname(str, varargin{:})) = val;
str = encodevarname(str, varargin{:});
if (length(str) > 63)
pos = -oldpos;
object = [];
return
end
object.(str) = val;
end
[cc, pos] = next_char(inputstr, pos);
if cc == '}'
Expand Down

0 comments on commit ef5b472

Please sign in to comment.