Skip to content

Commit ef5b472

Browse files
committed
[feat] automatically switch to map object when key length > 63
1 parent ee24122 commit ef5b472

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

loadbj.m

+25-1
Original file line numberDiff line numberDiff line change
@@ -140,10 +140,18 @@
140140
if (nargout > 1 || mmaponly)
141141
mmap{end + 1} = {opt.jsonpath_, pos};
142142
[data{jsoncount}, pos, newmmap] = parse_object(inputstr, pos, opt);
143+
if (pos < 0)
144+
opt.usemap = 1;
145+
[data{jsoncount}, pos, newmmap] = parse_object(inputstr, -pos, opt);
146+
end
143147
mmap{end}{2} = [mmap{end}{2}, pos - mmap{end}{2}];
144148
mmap = [mmap(:); newmmap(:)];
145149
else
146150
[data{jsoncount}, pos] = parse_object(inputstr, pos, opt);
151+
if (pos < 0)
152+
opt.usemap = 1;
153+
[data{jsoncount}, pos] = parse_object(inputstr, -pos, opt);
154+
end
147155
end
148156
case '['
149157
if (nargout > 1 || mmaponly)
@@ -424,6 +432,10 @@
424432
return
425433
case '{'
426434
[varargout{1:nargout}] = parse_object(inputstr, varargout{2}, varargin{:});
435+
if (varargout{2} < 0)
436+
varargin{1}.usemap = 1;
437+
[varargout{1:nargout}] = parse_object(inputstr, -varargout{2}, varargin{:});
438+
end
427439
return
428440
case {'i', 'U', 'I', 'u', 'l', 'm', 'L', 'M', 'h', 'd', 'D'}
429441
[varargout{1:2}] = parse_number(inputstr, varargout{2}, varargin{:});
@@ -455,6 +467,7 @@
455467

456468
%% -------------------------------------------------------------------------
457469
function [object, pos, mmap] = parse_object(inputstr, pos, varargin)
470+
oldpos = pos;
458471
if (nargout > 2)
459472
mmap = {};
460473
origpath = varargin{1}.jsonpath_;
@@ -486,6 +499,11 @@
486499
else
487500
[str, pos] = parse_name(inputstr, pos, varargin{:});
488501
end
502+
if (length(str) > 63)
503+
pos = -oldpos;
504+
object = [];
505+
return
506+
end
489507
if isempty(str)
490508
str = 'x0x0_'; % empty name is valid in BJData/UBJSON, decodevarname('x0x0_') restores '\0'
491509
end
@@ -502,7 +520,13 @@
502520
if (usemap)
503521
object(str) = val;
504522
else
505-
object.(encodevarname(str, varargin{:})) = val;
523+
str = encodevarname(str, varargin{:});
524+
if (length(str) > 63)
525+
pos = -oldpos;
526+
object = [];
527+
return
528+
end
529+
object.(str) = val;
506530
end
507531
[cc, pos] = next_char(inputstr, pos);
508532
if (count >= 0 && num >= count) || cc == '}'

loadjson.m

+25-1
Original file line numberDiff line numberDiff line change
@@ -232,10 +232,18 @@
232232
if (nargout > 1 || opt.mmaponly)
233233
mmap{end + 1} = {opt.jsonpath_, [pos, 0, w1]};
234234
[data{jsoncount}, pos, index_esc, newmmap] = parse_object(inputstr, pos, esc, index_esc, opt);
235+
if (pos < 0)
236+
opt.usemap = 1;
237+
[data{jsoncount}, pos, index_esc, newmmap] = parse_object(inputstr, -pos, esc, index_esc, opt);
238+
end
235239
mmap{end}{2}(2) = pos - mmap{end}{2}(1);
236240
mmap = [mmap(:); newmmap(:)];
237241
else
238242
[data{jsoncount}, pos, index_esc] = parse_object(inputstr, pos, esc, index_esc, opt);
243+
if (pos < 0)
244+
opt.usemap = 1;
245+
[data{jsoncount}, pos, index_esc] = parse_object(inputstr, -pos, esc, index_esc, opt);
246+
end
239247
end
240248
case '['
241249
if (nargout > 1 || opt.mmaponly)
@@ -536,6 +544,10 @@
536544
return
537545
case '{'
538546
[varargout{1:nargout}] = parse_object(inputstr, pos, esc, index_esc, varargin{:});
547+
if (varargout{2} < 0)
548+
varargin{1}.usemap = 1;
549+
[varargout{1:nargout}] = parse_object(inputstr, -varargout{2}, esc, index_esc, varargin{:});
550+
end
539551
return
540552
case {'-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}
541553
[varargout{1:2}] = parse_number(inputstr, pos, varargin{:});
@@ -563,6 +575,7 @@
563575

564576
%% -------------------------------------------------------------------------
565577
function [object, pos, index_esc, mmap] = parse_object(inputstr, pos, esc, index_esc, varargin)
578+
oldpos = pos;
566579
if (nargout > 3)
567580
mmap = {};
568581
origpath = varargin{1}.jsonpath_;
@@ -578,6 +591,11 @@
578591
if cc ~= '}'
579592
while 1
580593
[str, pos, index_esc] = parseStr(inputstr, pos, esc, index_esc, varargin{:});
594+
if (length(str) > 63)
595+
pos = -oldpos;
596+
object = [];
597+
return
598+
end
581599
if isempty(str) && ~usemap
582600
str = 'x0x0_'; % empty name is valid in JSON, decodevarname('x0x0_') restores '\0'
583601
end
@@ -594,7 +612,13 @@
594612
if (usemap)
595613
object(str) = val;
596614
else
597-
object.(encodevarname(str, varargin{:})) = val;
615+
str = encodevarname(str, varargin{:});
616+
if (length(str) > 63)
617+
pos = -oldpos;
618+
object = [];
619+
return
620+
end
621+
object.(str) = val;
598622
end
599623
[cc, pos] = next_char(inputstr, pos);
600624
if cc == '}'

0 commit comments

Comments
 (0)