|
87 | 87 | properties
|
88 | 88 | data
|
89 | 89 | end
|
| 90 | + properties (Access = private) |
| 91 | + flags |
| 92 | + end |
90 | 93 | methods
|
91 | 94 |
|
92 |
| - function obj = jdict(val) |
93 |
| - if (nargin == 1) |
94 |
| - if (ischar(val) && ~isempty(regexp(val, '^https*://', 'once'))) |
| 95 | + function obj = jdict(val, varargin) |
| 96 | + obj.flags = struct('builtinjson', 0); |
| 97 | + if (nargin >= 1) |
| 98 | + if (~isempty(varargin)) |
| 99 | + allflags = [varargin(1:2:end); varargin(2:2:end)]; |
| 100 | + obj.flags = struct(allflags{:}); |
| 101 | + end |
| 102 | + if (ischar(val) && ~isempty(regexpi(val, '^https*://', 'once'))) |
95 | 103 | try
|
96 |
| - obj.data = loadjson(val); |
| 104 | + obj.data = obj.call_('loadjson', val); |
97 | 105 | catch
|
98 | 106 | obj.data = val;
|
99 | 107 | end
|
|
107 | 115 | end
|
108 | 116 | end
|
109 | 117 |
|
110 |
| - % overloading the getter function |
111 | 118 | function val = subsref(obj, idxkey)
|
| 119 | + % overloading the getter function jd.('key').('subkey') |
| 120 | + |
112 | 121 | oplen = length(idxkey);
|
113 | 122 | val = obj.data;
|
114 | 123 | if (oplen == 1 && strcmp(idxkey.type, '()') && isempty(idxkey.subs))
|
|
117 | 126 | i = 1;
|
118 | 127 | while i <= oplen
|
119 | 128 | idx = idxkey(i);
|
120 |
| - % disp({i, savejson(idx)}); |
121 | 129 | if (isempty(idx.subs))
|
122 | 130 | i = i + 1;
|
123 | 131 | continue
|
|
142 | 150 | end
|
143 | 151 | elseif (strcmp(idx.type, '.') && ischar(idx.subs) && strcmp(idx.subs, 'v') && oplen == 1)
|
144 | 152 | i = i + 1;
|
145 |
| - continue; |
| 153 | + continue |
146 | 154 | elseif ((idx.type == '.' && ischar(idx.subs)) || (iscell(idx.subs) && ~isempty(idx.subs{1})))
|
147 | 155 | onekey = idx.subs;
|
148 | 156 | if (iscell(onekey))
|
|
152 | 160 | val = val.data;
|
153 | 161 | end
|
154 | 162 | if (ischar(onekey) && ~isempty(onekey) && onekey(1) == '$')
|
155 |
| - val = jsonpath(val, onekey); |
| 163 | + val = obj.call_('jsonpath', val, onekey); |
156 | 164 | elseif (isstruct(val))
|
157 | 165 | val = val.(onekey);
|
158 | 166 | elseif (isa(val, 'containers.Map') || isa(val, 'dictionary'))
|
|
170 | 178 | end
|
171 | 179 | end
|
172 | 180 |
|
173 |
| - % overloading the setter function, obj.('idxkey')=otherobj |
174 |
| - % expanded from rahnema1's sample at https://stackoverflow.com/a/79030223/4271392 |
175 | 181 | function obj = subsasgn(obj, idxkey, otherobj)
|
| 182 | + % overloading the setter function, obj.('key').('subkey')=otherobj |
| 183 | + % expanded from rahnema1's sample at https://stackoverflow.com/a/79030223/4271392 |
176 | 184 | oplen = length(idxkey);
|
177 | 185 | opcell = cell (1, oplen + 1);
|
178 | 186 | if (isempty(obj.data))
|
179 |
| - obj.data = containers.Map(); |
| 187 | + obj.data = obj.newkey_(); |
180 | 188 | end
|
181 | 189 | opcell{1} = obj.data;
|
182 | 190 |
|
|
196 | 204 | if (ischar(idx.subs))
|
197 | 205 | if (((isa(opcell{i}, 'containers.Map') || isa(opcell{i}, 'dictionary')) && ~isKey(opcell{i}, idx.subs)))
|
198 | 206 | idx.type = '()';
|
199 |
| - opcell{i}(idx.subs) = containers.Map(); |
| 207 | + opcell{i}(idx.subs) = obj.newkey_(); |
200 | 208 | elseif (isstruct(opcell{i}) && ~isfield(opcell{i}, idx.subs))
|
201 |
| - opcell{i}.(idx.subs) = containers.Map(); |
| 209 | + opcell{i}.(idx.subs) = obj.newkey_(); |
202 | 210 | end
|
203 | 211 | end
|
204 | 212 | end
|
205 |
| - if (exist('OCTAVE_VERSION', 'builtin') ~= 0) && (isa(opcell{i}, 'containers.Map') || isa(opcell{i}, 'dictionary')) |
| 213 | + if (isa(opcell{i}, 'containers.Map') || isa(opcell{i}, 'dictionary')) |
206 | 214 | opcell{i + 1} = opcell{i}(idx.subs);
|
207 | 215 | else
|
208 | 216 | opcell{i + 1} = subsref(opcell{i}, idx);
|
|
218 | 226 |
|
219 | 227 | for i = oplen - 1:-1:1
|
220 | 228 | idx = idxkey(i);
|
| 229 | + if (ischar(idx.subs) && strcmp(idx.type, '.') && (isa(opcell{i}, 'containers.Map') || isa(opcell{i}, 'dictionary'))) |
| 230 | + idx.type = '()'; |
| 231 | + end |
| 232 | + |
221 | 233 | if (ischar(idx.subs) && strcmp(idx.subs, 'v'))
|
222 | 234 | opcell{i} = opcell{i + 1};
|
223 | 235 | continue
|
|
239 | 251 | end
|
240 | 252 |
|
241 | 253 | function val = tojson(obj, varargin)
|
242 |
| - val = savejson('', obj.data, 'compact', 1, varargin{:}); |
| 254 | + % printing underlying data to compact-formed JSON string |
| 255 | + val = obj.call_('jsonpath', '', obj.data, 'compact', 1, varargin{:}); |
243 | 256 | end
|
244 | 257 |
|
245 | 258 | function obj = fromjson(obj, fname, varargin)
|
246 |
| - obj.data = loadjd(fname, varargin{:}); |
| 259 | + % loading diverse data files using loadjd interface in jsonlab |
| 260 | + obj.data = obj.call_('loadjd', fname, varargin{:}); |
247 | 261 | end
|
248 | 262 |
|
249 | 263 | function val = keys(obj)
|
| 264 | + % list subfields at the current level |
250 | 265 | if (isstruct(obj.data))
|
251 | 266 | val = fieldnames(obj.data);
|
252 | 267 | elseif (isa(obj.data, 'containers.Map') || isa(obj.data, 'dictionary'))
|
|
257 | 272 | end
|
258 | 273 |
|
259 | 274 | function val = len(obj)
|
| 275 | + % return the number of subfields at the current level |
260 | 276 | val = length(obj.data);
|
261 | 277 | end
|
262 | 278 |
|
|
268 | 284 | end
|
269 | 285 | end
|
270 | 286 |
|
| 287 | + function val = newkey_(obj) |
| 288 | + % insert new key if does not exist |
| 289 | + if (exist('containers.Map')) |
| 290 | + val = containers.Map; |
| 291 | + else |
| 292 | + val = struct; |
| 293 | + end |
| 294 | + end |
| 295 | + |
| 296 | + function varargout = call_(obj, func, varargin) |
| 297 | + % interface to external functions and dependencies |
| 298 | + if (~obj.flags.builtinjson) |
| 299 | + if (~exist('loadjson', 'file')) |
| 300 | + error('you must first install jsonlab (https://github.com/NeuroJSON/jsonlab) or set "BuildinJSON" flag to 1'); |
| 301 | + end |
| 302 | + fhandle = str2func(func); |
| 303 | + [varargout{1:nargout}] = fhandle(varargin{:}); |
| 304 | + else |
| 305 | + if (~exist('jsonencode', 'builtin') && ~strcmp(func, 'jsonpath')) |
| 306 | + error('jsonencode/jsondecode are not available, please install jsonlab (https://github.com/NeuroJSON/jsonlab) and set "BuiltinJSON" flag to 0'); |
| 307 | + end |
| 308 | + switch func |
| 309 | + case 'loadjson' |
| 310 | + [varargout{1:nargout}] = jsondecode(webread(varargin{:})); |
| 311 | + case 'savejson' |
| 312 | + [varargout{1:nargout}] = jsonencode(varargin{:}); |
| 313 | + case 'jsonpath' |
| 314 | + error('please install jsonlab (https://github.com/NeuroJSON/jsonlab) and set "BuiltinJSON" flag to 0'); |
| 315 | + end |
| 316 | + end |
| 317 | + end |
| 318 | + |
271 | 319 | end
|
272 | 320 | end
|
0 commit comments