|
23 | 23 | % member functions: |
24 | 24 | % jd.('cell1').v(i) or jd.('array1').v(2:3) returns specified elements if the element is a cell or array |
25 | 25 | % jd.('key1').('subkey1').v() returns the underlying hierachical data at the specified subkeys |
26 | | -% jd.tojson() convers the underlying data to a JSON string |
27 | | -% jd.tojson('compression', 'zlib', ...) convers the data to a JSON string with savejson() options |
28 | 26 | % jd.keys() returns the sub-key names of the object - if it a struct, dictionary or containers.Map - or 1:length(data) if it is an array |
29 | 27 | % jd.len() returns the length of the sub-keys |
30 | 28 | % jd.size() returns the dimension vector |
|
37 | 35 | % jd.setschema(schema) sets a JSON Schema for validation (struct, JSON string, URL, or file path) |
38 | 36 | % jd.getschema() returns the current schema; jd.getschema('json') returns as JSON string |
39 | 37 | % jd.validate() validates data against schema; [valid, errors] = jd.validate() returns error details |
| 38 | +% jd.tojson() convers the underlying data to a JSON string |
| 39 | +% jd.fromjson(jsonstr) loading data by parsing a json string |
| 40 | +% jd.tobuffer() convers the underlying data to a binary JSON buffer |
| 41 | +% jd.frombuffer(binary) loading data by parsing a binary JSON buffer |
40 | 42 | % |
41 | 43 | % if using matlab, the .v(...) method can be replaced by bare |
42 | 44 | % brackets .(...), but in octave, one must use .v(...) |
|
329 | 331 |
|
330 | 332 | if (strcmp(idx.type, '.') && isnumeric(idx.subs)) |
331 | 333 | val = val(idx.subs); |
332 | | - 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, '()')) |
| 334 | + 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', 'tobuffer', 'frombuffer', 'isfield', 'fieldnames', 'rmfield'}) && i < oplen && strcmp(idxkey(i + 1).type, '()')) |
333 | 335 | if (strcmp(idx.subs, 'v')) |
334 | 336 | if (iscell(val) && strcmp(idxkey(i + 1).type, '()')) |
335 | 337 | idxkey(i + 1).type = '{}'; |
|
348 | 350 | tempobj.attr = obj.attr; |
349 | 351 | tempobj.setschema(obj.schema); |
350 | 352 | tempobj.currentpath__ = trackpath; |
351 | | - if (obj.flags__.isoctave_ && regexp(OCTAVE_VERSION, '^5\.')) |
| 353 | + tempobj.root__ = obj.root__; |
| 354 | + if (obj.flags__.isoctave5_) |
352 | 355 | val = membercall_(tempobj, idx.subs, idxkey(i + 1).subs{:}); |
353 | 356 | else |
354 | 357 | fhandle = str2func(idx.subs); |
355 | 358 | val = fhandle(tempobj, idxkey(i + 1).subs{:}); |
356 | 359 | end |
357 | | - if (i == oplen - 1 && ismember(idx.subs, {'isKey', 'tojson', 'getattr', 'getschema', 'setschema', 'validate', 'attr2schema'})) |
| 360 | + if (i == oplen - 1 && ismember(idx.subs, {'isKey', 'tojson', 'getattr', 'getschema', 'setschema', 'validate', 'attr2schema', 'isfield'})) |
358 | 361 | if (strcmp(idx.subs, 'setschema')) |
359 | 362 | obj.setschema(tempobj.schema); |
360 | 363 | end |
|
867 | 870 | obj.data = opcell{1}; |
868 | 871 | end |
869 | 872 |
|
870 | | - % export data to json, binary JSON, or other over a dozen formats |
| 873 | + % export data to json |
871 | 874 | function val = tojson(obj, varargin) |
872 | 875 | % printing underlying data to compact-formed JSON string |
873 | | - val = obj.call_('savejd', '', obj, 'compact', 1, varargin{:}); |
| 876 | + val = obj.call_('savejson', '', obj, 'compact', 1, varargin{:}); |
874 | 877 | end |
875 | 878 |
|
876 | | - % load data from over a dozen data formats, including json and binary json |
| 879 | + % load data from json |
877 | 880 | function obj = fromjson(obj, fname, varargin) |
878 | | - obj.data = obj.call_('loadjd', fname, varargin{:}); |
| 881 | + obj.data = obj.call_('loadjson', fname, varargin{:}); |
| 882 | + end |
| 883 | + |
| 884 | + % export data to binary JSON buffer |
| 885 | + function val = tobuffer(obj, varargin) |
| 886 | + % printing underlying data to compact-formed JSON string |
| 887 | + val = obj.call_('savebj', '', obj, varargin{:}); |
| 888 | + end |
| 889 | + |
| 890 | + % load data from binary JSON buffer |
| 891 | + function obj = frombuffer(obj, fname, varargin) |
| 892 | + obj.data = obj.call_('loadbj', fname, varargin{:}); |
879 | 893 | end |
880 | 894 |
|
881 | 895 | function val = keys(obj) |
|
909 | 923 | end |
910 | 924 |
|
911 | 925 | % remove specified key or element |
912 | | - function val = rmfield(obj, key) |
913 | | - % list subfields at the current level |
914 | | - if (isstruct(obj.data)) |
915 | | - val = rmfield(obj.data, key); |
916 | | - elseif (ismap_(obj.flags__, obj.data)) |
917 | | - val = remove(obj.data, key); |
918 | | - elseif (iscell(obj.data)) |
919 | | - obj.data = builtin('subsasgn', obj.data, struct('type', '{}', 'subs', {{key}}), []); |
| 926 | + function obj = rmfield(obj, key) |
| 927 | + currentpath = obj.currentpath__; |
| 928 | + root = obj.root__; |
| 929 | + |
| 930 | + % Build path to the key to delete |
| 931 | + escapedkey = esckey_(key); |
| 932 | + if strcmp(currentpath, char(36)) |
| 933 | + targetpath = [char(36) '.' escapedkey]; |
920 | 934 | else |
921 | | - obj.data = builtin('subsasgn', obj.data, struct('type', '()', 'subs', {{key}}), []); |
| 935 | + targetpath = [currentpath '.' escapedkey]; |
922 | 936 | end |
| 937 | + |
| 938 | + % Use jsonpath to delete from root's data |
| 939 | + root.data = obj.call_('jsonpath', root.data, targetpath, jdict([], 'kind', '_deleted_', 'schema', struct('type', 'null'))); |
923 | 940 | end |
924 | 941 |
|
925 | 942 | % return the number of subfields or array length |
|
954 | 971 |
|
955 | 972 | function val = membercall_(obj, method, varargin) |
956 | 973 | switch method |
957 | | - case 'tojson' |
958 | | - val = tojson(obj); |
959 | | - case 'fromjson' |
960 | | - val = fromjson(obj, varargin{:}); |
961 | 974 | case 'v' |
962 | 975 | val = v(obj); |
963 | 976 | case 'isKey' |
|
980 | 993 | val = validate(obj, varargin{:}); |
981 | 994 | case 'attr2schema' |
982 | 995 | val = attr2schema(obj, varargin{:}); |
| 996 | + case 'tojson' |
| 997 | + val = tojson(obj); |
| 998 | + case 'fromjson' |
| 999 | + val = fromjson(obj, varargin{:}); |
| 1000 | + case 'tobuffer' |
| 1001 | + val = tobuffer(obj); |
| 1002 | + case 'frombuffer' |
| 1003 | + val = frombuffer(obj, varargin{:}); |
| 1004 | + case 'fieldnames' |
| 1005 | + val = fieldnames(obj); |
| 1006 | + case 'isfield' |
| 1007 | + val = isfield(obj, varargin{:}); |
| 1008 | + case 'rmfield' |
| 1009 | + val = rmfield(obj, varargin{:}); |
983 | 1010 | end |
984 | 1011 | end |
985 | 1012 |
|
|
1001 | 1028 | [varargout{1:nargout}] = jsondecode(webread(varargin{:})); |
1002 | 1029 | case 'savejson' |
1003 | 1030 | [varargout{1:nargout}] = jsonencode(varargin{:}); |
1004 | | - case 'jsonpath' |
1005 | | - error('please install jsonlab (https://github.com/NeuroJSON/jsonlab) and set "BuiltinJSON" flag to 0'); |
| 1031 | + case {'jsonpath', 'jsonschema'} |
| 1032 | + error('please install jsonlab (https://github.com/NeuroJSON/jsonlab)'); |
1006 | 1033 | end |
1007 | 1034 | end |
1008 | 1035 | end |
|
1319 | 1346 | cachedflags = struct(); |
1320 | 1347 | cachedflags.builtinjson = 0; |
1321 | 1348 | cachedflags.isoctave_ = exist('OCTAVE_VERSION', 'builtin') ~= 0; |
| 1349 | + cachedflags.isoctave5_ = (cachedflags.isoctave_ && regexp(OCTAVE_VERSION, '^5\.')); |
1322 | 1350 | try |
1323 | 1351 | containers.Map(); |
1324 | 1352 | cachedflags.hasmap_ = true; |
|
0 commit comments