Skip to content

Commit d47be45

Browse files
committed
fast bracket matching
1 parent c109b54 commit d47be45

File tree

2 files changed

+36
-22
lines changed

2 files changed

+36
-22
lines changed

fast_match_bracket.m

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function [endpos, maxlevel] = fast_match_bracket(key,pos,startpos,brackets)
2+
if(nargin<4)
3+
brackets='[]';
4+
end
5+
startpos=find( pos >= startpos, 1 );
6+
count = key(startpos:end);
7+
if(length(count)==1 && count==']')
8+
endpos=pos(end);
9+
maxlevel=1;
10+
return;
11+
end
12+
flag=cumsum(count==brackets(1))-cumsum(count==brackets(2))+1;
13+
endpos = find(flag==0,1);
14+
maxlevel=max([1,max(flag(1:endpos))]);
15+
endpos = pos(endpos + startpos-1);

loadjson.m

+21-22
Original file line numberDiff line numberDiff line change
@@ -83,17 +83,16 @@
8383
end
8484

8585
pos = 1; len = length(string); inputstr = string;
86-
arraytoken=find(inputstr=='[' | inputstr==']' | inputstr=='"');
87-
jstr=regexprep(inputstr,'\\\\',' ');
88-
escquote=regexp(jstr,'\\"');
89-
arraytoken=sort([arraytoken escquote]);
86+
arraytokenidx=find(inputstr=='[' | inputstr==']');
87+
arraytoken=inputstr(arraytokenidx);
9088

9189
% String delimiters and escape chars identified to improve speed:
9290
esc = find(inputstr=='"' | inputstr=='\' ); % comparable to: regexp(inputstr, '["\\]');
9391
index_esc = 1;
9492

9593
opt=varargin2struct(varargin{:});
9694
opt.arraytoken_=arraytoken;
95+
opt.arraytokenidx_=arraytokenidx;
9796

9897
if(jsonopt('ShowProgress',0,opt)==1)
9998
opt.progressbar_=waitbar(0,'loading ...');
@@ -159,7 +158,7 @@
159158
if next_char(inputstr) ~= ']'
160159
try
161160
if(jsonopt('FastArrayParser',1,varargin{:})>=1 && arraydepth>=jsonopt('FastArrayParser',1,varargin{:}))
162-
[endpos, maxlevel]=match_bracket(inputstr,pos);
161+
[endpos, maxlevel]=fast_match_bracket(varargin{1}.arraytoken_,varargin{1}.arraytokenidx_,pos);
163162
if(~isempty(endpos))
164163
arraystr=['[' inputstr(pos:endpos)];
165164
arraystr=sscanf_prep(arraystr);
@@ -218,29 +217,30 @@
218217
end
219218
end
220219
end
221-
if(regexp(arraystr,':','once'))
222-
error('One can not use ":" construct inside a JSON array');
223-
end
224-
arraystr=regexprep(arraystr,'\[','{');
225-
arraystr=regexprep(arraystr,'\]','}');
226-
if(jsonopt('ParseStringArray',0,varargin{:})==0)
227-
arraystr=regexprep(arraystr,'\"','''');
228-
end
229-
object=eval(arraystr);
230-
if(iscell(object))
231-
object=cellfun(@unescapejsonstring,object,'UniformOutput',false);
220+
if(isempty(regexp(arraystr,':','once')))
221+
arraystr=regexprep(arraystr,'\[','{');
222+
arraystr=regexprep(arraystr,'\]','}');
223+
if(jsonopt('ParseStringArray',0,varargin{:})==0)
224+
arraystr=regexprep(arraystr,'\"','''');
225+
end
226+
object=eval(arraystr);
227+
if(iscell(object))
228+
object=cellfun(@unescapejsonstring,object,'UniformOutput',false);
229+
end
230+
pos=endpos;
232231
end
233-
pos=endpos;
234232
catch
235-
while 1
233+
end
234+
if(pos~=endpos)
235+
while 1
236236
newopt=varargin2struct(varargin{:},'JSONLAB_ArrayDepth_',arraydepth+1);
237237
val = parse_value(inputstr, esc, newopt);
238238
object{end+1} = val;
239239
if next_char(inputstr) == ']'
240240
break;
241241
end
242242
parse_char(inputstr, ',');
243-
end
243+
end
244244
end
245245
end
246246

@@ -436,15 +436,14 @@ function error_pos(msg, inputstr)
436436
% Invalid characters will be converted to underscores, and the prefix
437437
% "x0x[Hex code]_" will be added if the first character is not a letter.
438438
isoct=exist('OCTAVE_VERSION','builtin');
439-
pos=regexp(str,'^[^A-Za-z]','once');
440-
if(~isempty(pos))
439+
if(~isvarname(str))
441440
if(~isoct && str(1)+0 > 255)
442441
str=regexprep(str,'^([^A-Za-z])','x0x${sprintf(''%X'',unicode2native($1))}_','once');
443442
else
444443
str=sprintf('x0x%X_%s',char(str(1)),str(2:end));
445444
end
446445
end
447-
if(isempty(regexp(str,'[^0-9A-Za-z_]', 'once' )))
446+
if(isvarname(str))
448447
return;
449448
end
450449
if(~isoct)

0 commit comments

Comments
 (0)