Skip to content

Commit 4a9eabd

Browse files
committed
[bug] allow jdict to set key names matching member names
1 parent dcf4046 commit 4a9eabd

2 files changed

Lines changed: 47 additions & 37 deletions

File tree

jdict.m

Lines changed: 34 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -164,26 +164,26 @@
164164
schema % JSON Schema for validation (struct), set via .setschema(), retrieve via .getschema()
165165
end
166166
properties (Access = private)
167-
flags % additional options, will be passed to jsonlab utility functions such as savejson/loadjson
168-
currentpath % internal variable tracking the current path when lookup embedded data at current depth
167+
flags__ % additional options, will be passed to jsonlab utility functions such as savejson/loadjson
168+
currentpath__ % internal variable tracking the current path when lookup embedded data at current depth
169169
end
170170
methods
171171

172172
% constructor: initialize a jdict object
173173
function obj = jdict(val, varargin)
174-
obj.flags = struct('builtinjson', 0);
174+
obj.flags__ = struct('builtinjson', 0);
175175
obj.attr = containers.Map();
176176
obj.schema = [];
177-
obj.currentpath = char(36);
177+
obj.currentpath__ = char(36);
178178
if (nargin >= 1)
179179
if (~isempty(varargin))
180180
allflags = [varargin(1:2:end); varargin(2:2:end)];
181-
obj.flags = struct(allflags{:});
182-
if (isfield(obj.flags, 'attr'))
183-
obj.attr = obj.flags.attr;
181+
obj.flags__ = struct(allflags{:});
182+
if (isfield(obj.flags__, 'attr'))
183+
obj.attr = obj.flags__.attr;
184184
end
185-
if (isfield(obj.flags, 'schema'))
186-
obj.schema = obj.flags.schema;
185+
if (isfield(obj.flags__, 'schema'))
186+
obj.schema = obj.flags__.schema;
187187
end
188188
end
189189
if (ischar(val) && ~isempty(regexpi(val, '^https*://', 'once')))
@@ -198,8 +198,8 @@
198198
obj.data = val.data;
199199
obj.attr = val.attr;
200200
obj.schema = val.schema;
201-
obj.currentpath = val.currentpath;
202-
obj.flags = val.flags;
201+
obj.currentpath__ = val.currentpath__;
202+
obj.flags__ = val.flags__;
203203
else
204204
obj.data = val;
205205
end
@@ -225,13 +225,13 @@
225225
% handle {} indexing for attributes
226226
if (oplen == 1 && strcmp(idxkey(1).type, '{}'))
227227
if (iscell(idxkey(1).subs) && length(idxkey(1).subs) == 1 && ischar(idxkey(1).subs{1}))
228-
varargout{1} = obj.getattr(obj.currentpath, idxkey(1).subs{1});
228+
varargout{1} = obj.getattr(obj.currentpath__, idxkey(1).subs{1});
229229
return
230230
end
231231
end
232232

233233
val = obj.data;
234-
trackpath = obj.currentpath;
234+
trackpath = obj.currentpath__;
235235

236236
if (oplen == 1 && strcmp(idxkey(1).type, '()') && isempty(idxkey(1).subs))
237237
varargout{1} = val;
@@ -254,7 +254,7 @@
254254

255255
if (strcmp(idx.type, '.') && isnumeric(idx.subs))
256256
val = val(idx.subs);
257-
elseif ((strcmp(idx.type, '()') || strcmp(idx.type, '.')) && ischar(idx.subs) && ismember(idx.subs, {'tojson', 'fromjson', 'v', 'isKey', 'keys', 'len', 'size', 'setattr', 'getattr', 'setschema', 'getschema', 'validate', 'attr2schema'}) && i < oplen)
257+
elseif ((strcmp(idx.type, '()') || strcmp(idx.type, '.')) && ischar(idx.subs) && ismember(idx.subs, {'tojson', 'fromjson', 'v', 'isKey', 'keys', 'len', 'size', 'setattr', 'getattr', 'setschema', 'getschema', 'validate', 'attr2schema'}) && i < oplen && strcmp(idxkey(i + 1).type, '()'))
258258
if (strcmp(idx.subs, 'v'))
259259
if (iscell(val) && strcmp(idxkey(i + 1).type, '()'))
260260
idxkey(i + 1).type = '{}';
@@ -263,7 +263,7 @@
263263
tempobj = jdict(val);
264264
tempobj.attr = obj.attr;
265265
tempobj.schema = obj.schema;
266-
tempobj.currentpath = trackpath;
266+
tempobj.currentpath__ = trackpath;
267267
val = v(tempobj, idxkey(i + 1));
268268
elseif (isa(val, 'jdict'))
269269
val = val.data;
@@ -272,7 +272,7 @@
272272
tempobj = jdict(val);
273273
tempobj.attr = obj.attr;
274274
tempobj.schema = obj.schema;
275-
tempobj.currentpath = trackpath;
275+
tempobj.currentpath__ = trackpath;
276276
if (exist('OCTAVE_VERSION', 'builtin') ~= 0 && regexp(OCTAVE_VERSION, '^5\.'))
277277
val = membercall_(tempobj, idx.subs, idxkey(i + 1).subs{:});
278278
else
@@ -292,12 +292,9 @@
292292
tempobj = jdict(val);
293293
tempobj.attr = obj.attr;
294294
tempobj.schema = obj.schema;
295-
tempobj.currentpath = trackpath;
295+
tempobj.currentpath__ = trackpath;
296296
val = tempobj;
297297
end
298-
elseif (strcmp(idx.type, '.') && ischar(idx.subs) && strcmp(idx.subs, 'v') && oplen == 1)
299-
i = i + 1;
300-
continue
301298
elseif ((strcmp(idx.type, '.') && ischar(idx.subs)) || (iscell(idx.subs) && ~isempty(idx.subs{1})))
302299
onekey = idx.subs;
303300
if (iscell(onekey))
@@ -323,7 +320,7 @@
323320
newobj = jdict(val);
324321
newobj.attr = obj.attr;
325322
newobj.schema = obj.schema;
326-
newobj.currentpath = trackpath;
323+
newobj.currentpath__ = trackpath;
327324
val = newobj;
328325
i = i + 2;
329326
continue
@@ -384,7 +381,7 @@
384381
end
385382
end
386383
newobj.schema = obj.schema;
387-
newobj.currentpath = char(36);
384+
newobj.currentpath__ = char(36);
388385
val = newobj;
389386
end
390387
varargout{1} = val;
@@ -401,7 +398,7 @@
401398
if (iscell(idxkey(1).subs) && ~isempty(idxkey(1).subs))
402399
attrn = idxkey(1).subs{1};
403400
if (ischar(attrn))
404-
obj.setattr(obj.currentpath, attrn, otherobj);
401+
obj.setattr(obj.currentpath__, attrn, otherobj);
405402
return
406403
end
407404
end
@@ -413,7 +410,7 @@
413410
attrn = idxkey(oplen).subs{1};
414411
if (ischar(attrn))
415412
% Build the path by navigating through keys
416-
temppath = obj.currentpath;
413+
temppath = obj.currentpath__;
417414
for i = 1:oplen - 1
418415
idx = idxkey(i);
419416
if (strcmp(idx.type, '.') || strcmp(idx.type, '()'))
@@ -445,7 +442,7 @@
445442
if (strcmp(idxkey(oplen - 1).type, '.') && ischar(idxkey(oplen - 1).subs))
446443
dimname = idxkey(oplen - 1).subs;
447444
% build path to the data
448-
temppath = obj.currentpath;
445+
temppath = obj.currentpath__;
449446
for i = 1:oplen - 2
450447
idx = idxkey(i);
451448
if (strcmp(idx.type, '.') || strcmp(idx.type, '()'))
@@ -503,7 +500,7 @@
503500
for i = 1:oplen
504501
idx = idxkey(i);
505502
if (strcmp(idx.type, '.'))
506-
if (ischar(idx.subs) && strcmp(idx.subs, 'v'))
503+
if (ischar(idx.subs) && strcmp(idx.subs, 'v') && i < oplen && strcmp(idxkey(i + 1).type, '()'))
507504
opcell{i + 1} = opcell{i};
508505
if (i < oplen && iscell(opcell{i}))
509506
idxkey(i + 1).type = '{}';
@@ -563,7 +560,7 @@
563560
idx.type = '()';
564561
end
565562

566-
if (ischar(idx.subs) && strcmp(idx.subs, 'v'))
563+
if (ischar(idx.subs) && strcmp(idx.subs, 'v') && i < oplen && ismember(idxkey(i + 1).type, {'()', '{}'}))
567564
opcell{i} = opcell{i + 1};
568565
continue
569566
end
@@ -692,7 +689,7 @@
692689
% internal: call member functions or external functions
693690
function varargout = call_(obj, func, varargin)
694691
% interface to external functions and dependencies
695-
if (~obj.flags.builtinjson)
692+
if (~obj.flags__.builtinjson)
696693
if (~exist('loadjson', 'file'))
697694
error('you must first install jsonlab (https://github.com/NeuroJSON/jsonlab) or set "BuildinJSON" flag to 1');
698695
end
@@ -718,7 +715,7 @@
718715
if (nargin == 3)
719716
attrvalue = attrname;
720717
attrname = jsonpath;
721-
jsonpath = obj.currentpath;
718+
jsonpath = obj.currentpath__;
722719
end
723720
if (~isKey(obj.attr, jsonpath))
724721
obj.attr(jsonpath) = containers.Map();
@@ -733,17 +730,17 @@
733730
function val = getattr(obj, jsonpath, attrname)
734731
val = [];
735732
if (nargin == 1)
736-
if (~isKey(obj.attr, obj.currentpath) && strcmp(obj.currentpath, char(36)))
733+
if (~isKey(obj.attr, obj.currentpath__) && strcmp(obj.currentpath__, char(36)))
737734
val = keys(obj.attr); % list root-level attr keys
738-
elseif (isKey(obj.attr, obj.currentpath))
739-
val = keys(obj.attr(obj.currentpath));
735+
elseif (isKey(obj.attr, obj.currentpath__))
736+
val = keys(obj.attr(obj.currentpath__));
740737
end
741738
return
742739
end
743740
if (nargin == 2)
744741
if (~isempty(jsonpath) && jsonpath(1) ~= char(36))
745742
attrname = jsonpath;
746-
jsonpath = obj.currentpath;
743+
jsonpath = obj.currentpath__;
747744
else
748745
attrname = '';
749746
end
@@ -829,7 +826,7 @@
829826
schema = struct;
830827

831828
% Add title/description at root
832-
if strcmp(obj.currentpath, char(36))
829+
if strcmp(obj.currentpath__, char(36))
833830
if ~isempty(schematitle)
834831
schema.('title') = schematitle;
835832
end
@@ -840,7 +837,7 @@
840837

841838
% Get all attribute paths
842839
allpaths = keys(obj.attr);
843-
basepath = obj.currentpath;
840+
basepath = obj.currentpath__;
844841
baselen = length(basepath);
845842

846843
% Extract schema attributes at current path
@@ -909,7 +906,7 @@
909906
% Recursively build child schema
910907
tempobj = jdict();
911908
tempobj.attr = obj.attr;
912-
tempobj.currentpath = childpath;
909+
tempobj.currentpath__ = childpath;
913910
objproperties.(propname) = attr2schema(tempobj);
914911
end
915912
schema.('properties') = objproperties;
@@ -919,7 +916,7 @@
919916
if ~isfield(schema, 'type')
920917
if ~isempty(childpaths)
921918
schema.('type') = 'object';
922-
elseif strcmp(obj.currentpath, char(36))
919+
elseif strcmp(obj.currentpath__, char(36))
923920
schema.('type') = 'object';
924921
end
925922
end

test/run_jsonlab_test.m

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,19 @@ function run_jsonlab_test(tests)
12721272
test_jsonlab('key with dots', @savejson, jd.('data').('key.with" dots'), '"dotvalue"', 'compact', 1);
12731273
end
12741274

1275+
% =======================================================================
1276+
% Built-in key names
1277+
% =======================================================================
1278+
jd = jdict();
1279+
jd.v = struct('k', 1);
1280+
jd.attr = [1, 2, 3];
1281+
jd.flags__ = 'flags__value';
1282+
jd.tojson = 'tojson_value';
1283+
test_jsonlab('key with dots', @savejson, {jd.v, jd.v.v(), jd.v.k, jd.attr.v(2), jd.flags__, jd.tojson.tojson()}, '[{"k":1},{"k":1},1,2,"flags__value","\"tojson_value\""]', 'compact', 1);
1284+
jd.v.k = 10;
1285+
jd.v.k{'dims'} = {'count'};
1286+
test_jsonlab('key with dots', @savejson, jd.v.k{'dims'}, '["count"]', 'compact', 1);
1287+
12751288
% =======================================================================
12761289
% Mixed nested structures
12771290
% =======================================================================

0 commit comments

Comments
 (0)