pax_global_header00006660000000000000000000000064136714736140014526gustar00rootroot0000000000000052 comment=5a58fafdca239e61be4d7b2270307b2445bb571a jsonlab-2.0/000077500000000000000000000000001367147361400130175ustar00rootroot00000000000000jsonlab-2.0/.gitignore000066400000000000000000000006131367147361400150070ustar00rootroot00000000000000# Created by .ignore support plugin (hsz.mobi) .idea .DS_store Thumbs.db logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pids *.pid *.seed *.pid.lock lib-cov coverage .nyc_output .grunt bower_components .lock-wscript build/Release node_modules/ jspm_packages/ typings/ .npm .eslintcache .node_repl_history *.tgz .yarn-integrity .env *.asv *.m~ *.mex* slprj/ octave-workspace .autosave jsonlab-2.0/AUTHORS.txt000066400000000000000000000057251367147361400147160ustar00rootroot00000000000000The author of "jsonlab" toolbox is Qianqian Fang. Qianqian is currently an Assistant Professor in the Department of Bioengineering, Northeastern University. Address: Qianqian Fang Department of Bioengineering Northeastern University ISEC 206 360 Huntington Ave, Boston, MA 02115, USA Phone[O]: 617-373-3829 URL: http://fanglab.org Email: and The script loadjson.m was built upon previous works (BSD 3-clause license) by - Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713 date: 2009/11/02 - François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393 date: 2009/03/22 - Joel Feenstra: http://www.mathworks.com/matlabcentral/fileexchange/20565 date: 2008/07/03 The data compression/decompression utilities ({zlib,gzip,base64}{encode,decode}.m) were copied from (BSD 2-clause license) - "Byte encoding utilities" by Kota Yamaguchi https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities date: 2013/01/04 The loadmsgpack.m script was modified from - parsemsgpack.m by Bastian Bechtold (BSD 3-clause license) URL: https://github.com/bastibe/matlab-msgpack/blob/master/parsemsgpack.m This toolbox contains patches submitted by the following contributors: - Blake Johnson part of revision 341 - Niclas Borlin various fixes in revision 394, including - loadjson crashes for all-zero sparse matrix. - loadjson crashes for empty sparse matrix. - Non-zero size of 0-by-N and N-by-0 empty matrices is lost after savejson/loadjson. - loadjson crashes for sparse real column vector. - loadjson crashes for sparse complex column vector. - Data is corrupted by savejson for sparse real row vector. - savejson crashes for sparse complex row vector. - Yul Kang patches for svn revision 415. - savejson saves an empty cell array as [] instead of null - loadjson differentiates an empty struct from an empty array - Mykhailo Bratukha (PR#14) Bug fix: File path is wrongly inerpreted as JSON string - Insik Kim (PR#12) Bug fix: Resolving bug that cell type is converted to json with transposed data - Sertan Senturk (PR#10,#11) Feature: Added matlab object saving to savejson and saveubjson - Paul Koprowski (Issue#29) Feature: Added support to save MATLAB tables to json. - Viktor Richter (PR#32) Feature: Use integer format in JSON output - Amirsina Torfi (PR#40) Feature: Reformat README to README.rst - Anton (PR#41) Feature: Added package.json to be able to intall via npm package manager - Paul Koprowski (PR#55) Feature: Added Encoding option to loadjson and savejson. jsonlab-2.0/ChangeLog.txt000066400000000000000000000316371367147361400154210ustar00rootroot00000000000000============================================================================ JSONlab - a toolbox to encode/decode JSON/UBJSON/MessagePack data in MATLAB/Octave ---------------------------------------------------------------------------- JSONlab ChangeLog (key features marked by *): == JSONlab 2.0 (codename: Magnus Prime), FangQ == 2020-06-13 [81feef3] skil no-op markers, update documentation 2020-06-13 [4904155] jload load data to struct, test if loadbj input is buffer, update error msg 2020-06-12 [c334799] change default workspace to caller for jload and jsave 2020-06-10 [c883546] fix keeptype single integer bug 2020-06-09*[ ] created `jdata` and `bjdata` python modules to share data with MATLAB 2020-06-08*[cbde607] add savebj and loadbj to dedicate to loading and saving bjdata 2020-06-08*[e2451e1] add unit testing script, fix issues found in the testing unit 2020-06-06 [a44015f] accelerate fast_match_bracket, drop unicode2native for speed 2020-06-06 [eefccf3] call jsonencode/decode in jsave/jload, parse embedded jdata struct 2020-06-05 [9434103] support Toeplitz matrices, use case-insensitive comparison 2020-06-04 [3119ce4] jdatadecode now handles _ArrayOrder_ 2020-06-04 [89b844c] remove forced root name, update internal test results 2020-06-02*[15ca7ae] add keeptype option to jsave and saveubjson 2020-06-02 [7f2cbc4] make jsave and jload work on octave 2020-06-01*[8829d6b] apply data compression to strings, new datatype char 2020-06-01 [270cbf6] fix loadmsgpack ND array issue 2020-06-01*[919f502] add jsave and jload for portable data sharing,update doc 2020-05-31 [df3a4fa] debug arrayshape related changes and test all demo scripts 2020-05-31*[fc0b285] adding support to _ArrayShape_ to record special matrices 2020-05-15*[d88d454] jsonlab is compatible with matlab R2008 2020-05-13 [86efe89] flag to prevent embedding ND array size specifier 2020-05-07 [a189a50] use more robust integer type testing 2020-05-06*[82f5249] saveubjson now implments BJData spec Draft1,https://github.com/fangq/bjdata 2020-05-03 [34bca22] add prj file to compile a matlab package, close #60 2020-05-03 [82dfdcc] handle empty array in loadmsgpack, fix #63, patch by stfnp 2020-03-08 [7499bd8] Merge pull request #61 from j2L4e/patch-1 2020-02-09*[6984111] add UseMap option to avoid key name conversion 2019-11-16 [e46221a] if _ArraySize_ has a single length, treat as a row vector 2019-11-01 [f2bfb65] fix a uint8 upper bound bug 2019-10-24 [cc4491d] avoid escaping base64 str, avoid double processing preencoded arrayzipdata 2019-10-24 [4dc76ef] make example script compatible with matlab R2010 2019-10-24 [ad8be26] disable underscore escaping in octave,update all tests and outputs 2019-10-24 [d4275c6] reduce jsonopt calls to speed up encoding and decoding 2019-10-23 [82c9e91] fix invalid jdatadecode example 2019-10-23 [398539d] reoptimize for speed 2019-10-22*[650b5ec] enable jdataencode in savejson and saveubjson == JSONlab 1.9.8 (codename: Magnus - beta), FangQ == 2019-10-22*[650b5ec] enable preencode by default for savejson and saveubjson 2019-10-21 [0f870c0] make demos to run with jdataencode, but still have issues 2019-10-21*[874945f] decode graph data, encode non-char-keyed map data 2019-10-18 [11712b7] add any2jd, pass opt to name check, add more options 2019-10-18*[f97de9b] extract name encoding/decoding to separate function, like in easyh5 2019-10-17*[9d0fd4a] rewrite jdataencode 2019-10-15 [23f14d6] minor updates to make msgpack to work on octave 2019-10-14 [04d6c04] update encoding and decoding function help info 2019-09-16*[689cb40] support lz4 and lz4hc compression via zmat v0.9 2019-09-03 [2aa6591] add conditions to use the U marker 2019-08-20 [31eabba] fix table transpose issue for uniform type tables 2019-08-13 [cdb218d] use iso2mesh original function isoctavemesh in place of isoctave 2019-07-18 [6c44724] Add Encoding option to loadjson and savejson 2019-07-11*[06d33aa] update zmat test to support zmat v0.8 mox-the-fox 2019-07-09 [6a4821c] fix 2d array transpose issue, close #54 2019-06-24 [fb5b240] update format for table objects 2019-06-24*[eba4078] saving table objects with new syntax 2019-06-20 [6803542] fix ubjson array output bug 2019-06-18 [69006d5] encode and decode non-string keyed maps 2019-06-14 [bf26892] allow to decode jdata structures loaded from jsonencode from matlab 2019-06-12 [3eb6d56] change ArrayCompression keywords to ArrayZip to be short 2019-06-12*[e5f2ffb] complete saveubjson debug mode, add compression example 2019-06-11 [ebbcfd2] pass formatversion tag to jdatadecode 2019-06-10*[95b2eb0] add jdataencode and jdatadecode 2019-06-10*[f86219d] major update: use row-major for N-D array, incompatible with old JSONLab 2019-06-02 [63ff948] handle nestarray in json and ubjson 2019-06-01 [f421b14] add a modified msgpack decoder based on Bastian Bechtold's transplant project 2019-05-31 [428b47f] fix savemsgpack input test 2019-05-31 [0ff5d47] support table in ubjson,add demo for handles,containers.Map and datetime and tables 2019-05-31*[0c467ee] support lzma and lzip compression decompression via zmat toolbox (http://github.com/fangq/zmat) 2019-05-31 [599ee4c] support categorical data 2019-05-31 [15c4b8d] completely remove global var using nested functions 2019-05-30*[d47be45] fast bracket matching 2019-05-30 [1993a24] recursively processing output 2019-05-30 [d1f7ee8] fix bracket matching, transpose _ArrayData_; convert irregular array to cell 2019-05-24*[0ec2d01] rewriting fastarrayparser, 10x faster for Octave, close #4 with fast bracket matching 2019-05-22*[d8c19b8] add support to MessagePack, close #53, add NestArray option, close #6 2019-05-19*[c87e7d2] support containers.Map == JSONlab 1.9 (codename: Magnus - alpha), FangQ == 2019-05-06 [25ad795] unescape string in loadjson.m 2019-05-04 [2e317c9] explain extra compression fields 2019-05-02 [1b1be65] avoid side effect of removing singletarray 2019-05-02*[8360fd1] support zmat based base64 encoding and decoding 2019-05-01*[c797bb2] integrating zmat, for zlib/gzip data compression 2019-04-29 [70551fe] remove warnings from matlab 2019-04-28 [0d61c4b] complete data compression support, close #52 2019-04-27 [804115b] avoid typecast error 2019-04-27 [c166aa7] change default compressarraysize to 100 2019-04-27*[3322f6f] major new feature: support array compression and decompression 2019-03-13*[9c01046] support saving function handles, close #51 2019-03-13 [a8fde38] add option to parse string array or convert to char, close #50 2019-03-12 [ed2645e] treat string array as cell array in newer matlab 2018-11-18 [c3eb021] allow saving uint64 integers in saveubjson, fix #49 == JSONlab 1.8 (codename: Nominus), FangQ == 2018-07-12 [03a6c25] update documentation, bump version to 1.8, tag Nominus 2018-07-12*[1597106] add patch provided by pjkoprowski to support MATLAB table, add RowNames support, fix #29 2018-07-12 [f16cc57] fix #31, throw an error when : array construct is used 2018-07-12 [956e000] drop octave 3.x support, fix ubjson error in octave 2018-07-12 [e090f0a] fix octave warning for saveubjson 2018-07-12*[34284c7] fix issues #34 #39 #44 and #45, support double-quoted strings 2017-09-06 [474d8c8] Merge pull request #41 from dasantonym/master 2017-08-07*[38b24fb] added package.json to be able to intall via npm package manager, converted readme to utf-8, added basic .gitignore file 2017-07-19 [ae7a5d9] Merge pull request #40 from astorfi/master 2017-07-17 [154ef61] Rename README.txt to README.rst 2017-03-27 [31b5bdc] simplify condition flow in matching_bracket 2017-03-27 [86ef12a] avoid error in matlab 2017a, close #34 2017-02-18 [4a09ac3] Merge pull request #32 from vrichter/master 2017-02-14 [e67d3a3] respect integer types == JSONlab 1.5 (codename: Nominus - alpha), FangQ == 2017/01/02 *use Big-endian format to store floating points (d/D) in saveubjson (Issue #25) 2017/01/02 *speedup parsing large unstructured data by 2x (Issue #9) 2017/01/01 make parsing independent of white space (Issue #30) 2016/08/27 allow to parse array of homogeneous elements (Issue 5) 2016/08/22 permit [] inside file names in savejson 2016/01/06 fix a bug that prevents saving to a file in savejson == JSONlab 1.2 (codename: Optimus - Update 2), FangQ == 2015/12/16 *replacing string concatenation by str cells to gain 2x speed in savejson (Issue#17) 2015/12/11 fix FileName option case bug (SVN rev#495) 2015/12/11 add SingletCell option, add SingletArray to replace NoRowBracket (Issue#15,#8) 2015/11/10 fix bug for inerpreting file names as JSON string - by Mykhailo Bratukha (Pull#14) 2015/10/16 fix bug for cell with transposed data - by Insik Kim (Pull#12) 2015/09/25 support exporting matlab object to JSON - by Sertan Senturk (Pull#10, #11) == JSONlab 1.1 (codename: Optimus - Update 1), FangQ == 2015/05/05 *massively accelerating loadjson for parsing large collection of unstructured small objects 2015/05/05 force array bracket in 1x1 struct to maintain depth (Issue#1) 2015/05/05 parse logicals in loadjson 2015/05/05 make options case insensitive 2015/05/01 reading unicode encoded json files (thanks to Sertan Senturk,Issue#3) 2015/04/30 allow \uXXXX to represent a unicode in a string (Issue#2) 2015/03/30 save a 0x0 solid real empty array as null and handel empty struct array 2015/03/30 properly handle escape characters in a string 2015/01/24 *implement the UBJSON Draft12 new name format 2015/01/13 correct cell array indentation inconsistency == JSONlab 1.0 (codename: Optimus - Final), FangQ == 2015/01/02 polish help info for all major functions, update examples, finalize 1.0 2014/12/19 fix a bug to strictly respect NoRowBracket in savejson == JSONlab 1.0.0-RC2 (codename: Optimus - RC2), FangQ == 2014/11/22 show progress bar in loadjson ('ShowProgress') 2014/11/17 *add Compact option in savejson to output compact JSON format ('Compact') 2014/11/17 add FastArrayParser in loadjson to specify fast parser applicable levels 2014/09/18 *start official github mirror: https://github.com/fangq/jsonlab == JSONlab 1.0.0-RC1 (codename: Optimus - RC1), FangQ == 2014/09/17 fix several compatibility issues when running on octave versions 3.2-3.8 2014/09/17 *support 2D cell and struct arrays in both savejson and saveubjson 2014/08/04 escape special characters in a JSON string 2014/02/16 fix a bug when saving ubjson files == JSONlab 0.9.9 (codename: Optimus - beta), FangQ == 2014/01/22 use binary read and write in saveubjson and loadubjson == JSONlab 0.9.8-1 (codename: Optimus - alpha update 1), FangQ == 2013/10/07 better round-trip conservation for empty arrays and structs (patch submitted by Yul Kang) == JSONlab 0.9.8 (codename: Optimus - alpha), FangQ == 2013/08/23 *universal Binary JSON (UBJSON) support, including both saveubjson and loadubjson == JSONlab 0.9.1 (codename: Rodimus, update 1), FangQ == 2012/12/18 *handling of various empty and sparse matrices (fixes submitted by Niclas Borlin) == JSONlab 0.9.0 (codename: Rodimus), FangQ == 2012/06/17 *new format for an invalid leading char, unpacking hex code in savejson 2012/06/01 support JSONP in savejson 2012/05/25 fix the empty cell bug (reported by Cyril Davin) 2012/04/05 savejson can save to a file (suggested by Patrick Rapin) == JSONlab 0.8.1 (codename: Sentiel, Update 1), FangQ == 2012/02/28 loadjson quotation mark escape bug, see http://bit.ly/yyk1nS 2012/01/25 patch to handle root-less objects, contributed by Blake Johnson == JSONlab 0.8.0 (codename: Sentiel), FangQ == 2012/01/13 *speed up loadjson by 20 fold when parsing large data arrays in matlab 2012/01/11 remove row bracket if an array has 1 element, suggested by Mykel Kochenderfer 2011/12/22 *accept sequence of 'param',value input in savejson and loadjson 2011/11/18 fix struct array bug reported by Mykel Kochenderfer == JSONlab 0.5.1 (codename: Nexus Update 1), FangQ == 2011/10/21 fix a bug in loadjson, previous code does not use any of the acceleration 2011/10/20 loadjson supports JSON collections - concatenated JSON objects == JSONlab 0.5.0 (codename: Nexus), FangQ == 2011/10/16 package and release jsonlab 0.5.0 2011/10/15 *add json demo and regression test, support cpx numbers, fix double quote bug 2011/10/11 *speed up readjson dramatically, interpret _Array* tags, show data in root level 2011/10/10 create jsonlab project, start jsonlab website, add online documentation 2011/10/07 *speed up savejson by 25x using sprintf instead of mat2str, add options support 2011/10/06 *savejson works for structs, cells and arrays 2011/09/09 derive loadjson from JSON parser from MATLAB Central, draft savejson.m jsonlab-2.0/Contents.m000066400000000000000000001710131367147361400147750ustar00rootroot00000000000000% JSONLAB % % Files % base64decode - output = base64decode(input) % base64encode - output = base64encode(input) % decodevarname - newname = decodevarname(name) % encodevarname - newname = encodevarname(name) % fast_match_bracket - [endpos, maxlevel] = fast_match_bracket(key,pos,startpos,brackets) % gzipdecode - output = gzipdecode(input) % gzipencode - output = gzipencode(input) % isoctavemesh - [isoctave verinfo]=isoctavemesh % jdatadecode - newdata=jdatadecode(data,opt,...) % jdataencode - jdata=jdataencode(data) % jsave - jsave(fname,'param1',value1,'param2',value2,...) % jload - vars=jload(fname,'param1',value1,'param2',value2,...) % jsonopt - val=jsonopt(key,default,optstruct) % loadbj - data=loadbj(fname,opt) % loadjson - data=loadjson(fname,opt) % loadmsgpack - PARSEMSGPACK parses a msgpack byte buffer into Matlab data structures % loadubjson - data=loadubjson(fname,opt) % lz4decode - output = lz4decode(input) % lz4encode - output = lz4encode(input) % lz4hcdecode - output = lz4hcdecode(input) % lz4hcencode - output = lz4hcencode(input) % lzipdecode - output = lzipdecode(input) % lzipencode - output = lzipencode(input) % lzmadecode - output = lzmadecode(input) % lzmaencode - output = lzmaencode(input) % match_bracket - [endpos, maxlevel] = match_bracket(str,startpos,brackets) % mergestruct - s=mergestruct(s1,s2) % nestbracket2dim - [dims, maxlevel, count] = nestbracket2dim(str,brackets) % savebj - bjd=savebj(rootname,obj,filename) % savejson - json=savejson(rootname,obj,filename) % savemsgpack - msgpk=savemsgpack(rootname,obj,filename) % saveubjson - json=saveubjson(rootname,obj,filename) % varargin2struct - opt=varargin2struct('param1',value1,'param2',value2,...) % zlibdecode - output = zlibdecode(input) % zlibencode - output = zlibencode(input) %%=== # JData specification === %==== function jdata=jdataencode(data, varargin) ==== % % jdata=jdataencode(data) % or % jdata=jdataencode(data, options) % jdata=jdataencode(data, 'Param1',value1, 'Param2',value2,...) % % Annotate a MATLAB struct or cell array into a JData-compliant data % structure as defined in the JData spec: http://github.com/fangq/jdata. % This encoded form servers as an intermediate format that allows unambiguous % storage, exchange of complex data structures and easy-to-serialize by % json encoders such as savejson and jsonencode (MATLAB R2016b or newer) % % This function implements the JData Specification Draft 3 (Jun. 2020) % see http://github.com/fangq/jdata for details % % % input: % data: a structure (array) or cell (array) to be encoded. % options: (optional) a struct or Param/value pairs for user % specified options (first in [.|.] is the default) % AnnotateArray: [0|1] - if set to 1, convert all 1D/2D matrices % to the annotated JData array format to preserve data types; % N-D (N>2), complex and sparse arrays are encoded using the % annotated format by default. Please set this option to 1 if % you intend to use MATLAB's jsonencode to convert to JSON. % Base64: [0|1] if set to 1, _ArrayZipData_ is assumed to % be encoded with base64 format and need to be % decoded first. This is needed for JSON but not % UBJSON data % Prefix: ['x0x5F'|'x'] for JData files loaded via loadjson/loadubjson, the % default JData keyword prefix is 'x0x5F'; if the % json file is loaded using matlab2018's % jsondecode(), the prefix is 'x'; this function % attempts to automatically determine the prefix; % for octave, the default value is an empty string ''. % UseArrayZipSize: [1|0] if set to 1, _ArrayZipSize_ will be added to % store the "pre-processed" data dimensions, i.e. % the original data stored in _ArrayData_, and then flaten % _ArrayData_ into a row vector using row-major % order; if set to 0, a 2D _ArrayData_ will be used % UseArrayShape: [0|1] if set to 1, a matrix will be tested by % to determine if it is diagonal, triangular, banded or % toeplitz, and use _ArrayShape_ to encode the matrix % MapAsStruct: [0|1] if set to 1, convert containers.Map into % struct; otherwise, keep it as map % Compression: ['zlib'|'gzip','lzma','lz4','lz4hc'] - use zlib method % to compress data array % CompressArraySize: [100|int]: only to compress an array if the % total element count is larger than this number. % FormatVersion [2|float]: set the JSONLab output version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % % example: % jd=jdataencode(struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5))) % % encodedmat=jdataencode(single(magic(5)),'annotatearray',1,'prefix','x') % jdatadecode(jsondecode(jsonencode(encodedmat))) % serialize by jsonencode % jdatadecode(loadjson(savejson('',encodedmat))) % serialize by savejson % % encodedtoeplitz=jdataencode(uint8(toeplitz([1,2,3,4],[1,5,6])),'usearrayshape',1,'prefix','x') % jdatadecode(jsondecode(jsonencode(encodedtoeplitz))) % serialize by jsonencode % jdatadecode(loadjson(savejson('',encodedtoeplitz))) % serialize by savejson % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function newdata=jdatadecode(data,varargin) ==== % % newdata=jdatadecode(data,opt,...) % % Convert all JData object (in the form of a struct array) into an array % (accepts JData objects loaded from either loadjson/loadubjson or % jsondecode for MATLAB R2016b or later) % % This function implements the JData Specification Draft 3 (Jun. 2020) % see http://github.com/fangq/jdata for details % % % input: % data: a struct array. If data contains JData keywords in the first % level children, these fields are parsed and regrouped into a % data object (arrays, trees, graphs etc) based on JData % specification. The JData keywords are % "_ArrayType_", "_ArraySize_", "_ArrayData_" % "_ArrayIsSparse_", "_ArrayIsComplex_", % "_ArrayZipType_", "_ArrayZipSize", "_ArrayZipData_" % opt: (optional) a list of 'Param',value pairs for additional options % The supported options include % Recursive: [1|0] if set to 1, will apply the conversion to % every child; 0 to disable % Base64: [0|1] if set to 1, _ArrayZipData_ is assumed to % be encoded with base64 format and need to be % decoded first. This is needed for JSON but not % UBJSON data % Prefix: ['x0x5F'|'x'] for JData files loaded via loadjson/loadubjson, the % default JData keyword prefix is 'x0x5F'; if the % json file is loaded using matlab2018's % jsondecode(), the prefix is 'x'; this function % attempts to automatically determine the prefix; % for octave, the default value is an empty string ''. % FullArrayShape: [0|1] if set to 1, converting _ArrayShape_ % objects to full matrices, otherwise, stay sparse % FormatVersion: [2|float]: set the JSONLab output version; % since v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1 % % output: % newdata: the covnerted data if the input data does contain a JData % structure; otherwise, the same as the input. % % examples: % obj={[],{'test'},true,struct('sparse',sparse(2,3),'magic',uint8(magic(5)))} % jdata=jdatadecode(jdataencode(obj)) % isequaln(obj,jdata) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %%=== # JSON === %==== function data = loadjson(fname,varargin) ==== % % data=loadjson(fname,opt) % or % data=loadjson(fname,'param1',value1,'param2',value2,...) % % parse a JSON (JavaScript Object Notation) file or string % % created on 2011/09/09, including previous works from % % Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713 % created on 2009/11/02 % François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393 % created on 2009/03/22 % Joel Feenstra: % http://www.mathworks.com/matlabcentral/fileexchange/20565 % created on 2008/07/03 % % input: % fname: input file name; if fname contains "{}" or "[]", fname % will be interpreted as a JSON string % opt: (optional) a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % SimplifyCell [1|0]: if set to 1, loadjson will call cell2mat % for each element of the JSON data, and group % arrays based on the cell2mat rules. % FastArrayParser [1|0 or integer]: if set to 1, use a % speed-optimized array parser when loading an % array object. The fast array parser may % collapse block arrays into a single large % array similar to rules defined in cell2mat; 0 to % use a legacy parser; if set to a larger-than-1 % value, this option will specify the minimum % dimension to enable the fast array parser. For % example, if the input is a 3D array, setting % FastArrayParser to 1 will return a 3D array; % setting to 2 will return a cell array of 2D % arrays; setting to 3 will return to a 2D cell % array of 1D vectors; setting to 4 will return a % 3D cell array. % UseMap [0|1]: if set to 1, loadjson uses a containers.Map to % store map objects; otherwise use a struct object % ShowProgress [0|1]: if set to 1, loadjson displays a progress bar. % ParseStringArray [0|1]: if set to 0, loadjson converts "string arrays" % (introduced in MATLAB R2016b) to char arrays; if set to 1, % loadjson skips this conversion. % FormatVersion [2|float]: set the JSONLab format version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % Encoding ['']: json file encoding. Support all encodings of % fopen() function % ObjectID [0|interger or list]: if set to a positive number, % it returns the specified JSON object by index % in a multi-JSON document; if set to a vector, % it returns a list of specified objects. % JDataDecode [1|0]: if set to 1, call jdatadecode to decode % JData structures defined in the JData % Specification. % % output: % dat: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % % examples: % dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}') % dat=loadjson(['examples' filesep 'example1.json']) % dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',0) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function json=savejson(rootname,obj,varargin) ==== % % json=savejson(obj) % or % json=savejson(rootname,obj,filename) % json=savejson(rootname,obj,opt) % json=savejson(rootname,obj,'param1',value1,'param2',value2,...) % % convert a MATLAB object (cell, struct or array) into a JSON (JavaScript % Object Notation) string % % initially created on 2011/09/09 % % input: % rootname: the name of the root-object, when set to '', the root name % is ignored, however, when opt.ForceRootName is set to 1 (see below), % the MATLAB variable name will be used as the root name. % obj: a MATLAB object (array, cell, cell array, struct, struct array, % class instance). % filename: a string for the file name to save the output JSON data. % opt: a struct for additional options, ignore to use default values. % opt can have the following fields (first in [.|.] is the default) % % FileName [''|string]: a file name to save the output JSON data % FloatFormat ['%.10g'|string]: format to show each numeric element % of a 1D/2D array; % IntFormat ['%.0f'|string]: format to display integer elements % of a 1D/2D array; % ArrayIndent [1|0]: if 1, output explicit data array with % precedent indentation; if 0, no indentation % ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D % array in JSON array format; if sets to 1, an % array will be shown as a struct with fields % "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for % sparse arrays, the non-zero elements will be % saved to _ArrayData_ field in triplet-format i.e. % (ix,iy,val) and "_ArrayIsSparse_" will be added % with a value of 1; for a complex array, the % _ArrayData_ array will include two columns % (4 for sparse) to record the real and imaginary % parts, and also "_ArrayIsComplex_":1 is added. % NestArray [0|1]: If set to 1, use nested array constructs % to store N-dimensional arrays; if set to 0, % use the annotated array format defined in the % JData Specification (Draft 1 or later). % ParseLogical [0|1]: if this is set to 1, logical array elem % will use true/false rather than 1/0. % SingletArray [0|1]: if this is set to 1, arrays with a single % numerical element will be shown without a square % bracket, unless it is the root object; if 0, square % brackets are forced for any numerical arrays. % SingletCell [1|0]: if 1, always enclose a cell with "[]" % even it has only one element; if 0, brackets % are ignored when a cell has only 1 element. % ForceRootName [0|1]: when set to 1 and rootname is empty, savejson % will use the name of the passed obj variable as the % root object name; if obj is an expression and % does not have a name, 'root' will be used; if this % is set to 0 and rootname is empty, the root level % will be merged down to the lower level. % Inf ['"$1_Inf_"'|string]: a customized regular expression pattern % to represent +/-Inf. The matched pattern is '([-+]*)Inf' % and $1 represents the sign. For those who want to use % 1e999 to represent Inf, they can set opt.Inf to '$11e999' % NaN ['"_NaN_"'|string]: a customized regular expression pattern % to represent NaN % JSONP [''|string]: to generate a JSONP output (JSON with padding), % for example, if opt.JSONP='foo', the JSON data is % wrapped inside a function call as 'foo(...);' % UnpackHex [1|0]: conver the 0x[hex code] output by loadjson % back to the string form % SaveBinary [0|1]: 1 - save the JSON file in binary mode; 0 - text mode. % Compact [0|1]: 1- out compact JSON format (remove all newlines and tabs) % Compression 'zlib', 'gzip', 'lzma', 'lzip', 'lz4' or 'lz4hc': specify array % compression method; currently only supports 6 methods. The % data compression only applicable to numerical arrays % in 3D or higher dimensions, or when ArrayToStruct % is 1 for 1D or 2D arrays. If one wants to % compress a long string, one must convert % it to uint8 or int8 array first. The compressed % array uses three extra fields % "_ArrayZipType_": the opt.Compression value. % "_ArrayZipSize_": a 1D interger array to % store the pre-compressed (but post-processed) % array dimensions, and % "_ArrayZipData_": the "base64" encoded % compressed binary array data. % CompressArraySize [100|int]: only to compress an array if the total % element count is larger than this number. % CompressStringSize [400|int]: only to compress a string if the total % element count is larger than this number. % FormatVersion [2|float]: set the JSONLab output version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % Encoding ['']: json file encoding. Support all encodings of % fopen() function % Append [0|1]: if set to 1, append a new object at the end of the file. % Endian ['n'|'b','l']: Endianness of the output file ('n': native, % 'b': big endian, 'l': little-endian) % PreEncode [1|0]: if set to 1, call jdataencode first to preprocess % the input data before saving % % opt can be replaced by a list of ('param',value) pairs. The param % string is equivallent to a field in opt and is case sensitive. % output: % json: a string in the JSON format (see http://json.org) % % examples: % jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... % 'MeshElem',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... % 'MeshSurf',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... % 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... % 'MeshCreator','FangQ','MeshTitle','T6 Cube',... % 'SpecialData',[nan, inf, -inf]); % savejson('jmesh',jsonmesh) % savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g') % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %%=== # BJData === %==== function data = loadbj(fname,varargin) ==== % % data=loadbj(fname,opt) % or % data=loadbj(fname,'param1',value1,'param2',value2,...) % % Parse a Binary JData (BJData v1 Draft-1, defined in https://github.com/OpenJData/bjdata) % file or memory buffer and convert into a MATLAB data structure % % initially created on 2013/08/01 % % input: % fname: input file name, if fname contains "{}" or "[]", fname % will be interpreted as a BJData/UBJSON string % opt: a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % SimplifyCell [1|0]: if set to 1, loadbj will call cell2mat % for each element of the JSON data, and group % arrays based on the cell2mat rules. % IntEndian [B|L]: specify the endianness of the integer fields % in the BJData/UBJSON input data. B - Big-Endian format for % integers (as required in the UBJSON specification); % L - input integer fields are in Little-Endian order. % NameIsString [0|1]: for UBJSON Specification Draft 8 or % earlier versions (JSONLab 1.0 final or earlier), % the "name" tag is treated as a string. To load % these UBJSON data, you need to manually set this % flag to 1. % UseMap [0|1]: if set to 1, loadjson uses a containers.Map to % store map objects; otherwise use a struct object % ObjectID [0|interger or list]: if set to a positive number, % it returns the specified JSON object by index % in a multi-JSON document; if set to a vector, % it returns a list of specified objects. % FormatVersion [2|float]: set the JSONLab format version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % % output: % dat: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % % examples: % obj=struct('string','value','array',[1 2 3]); % ubjdata=savebj('obj',obj); % dat=loadbj(ubjdata) % dat=loadbj(['examples' filesep 'example1.bjd']) % dat=loadbj(['examples' filesep 'example1.bjd'],'SimplifyCell',0) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function json=savebj(rootname,obj,varargin) ==== % % bjd=savebj(obj) % or % bjd=savebj(rootname,obj,filename) % bjd=savebj(rootname,obj,opt) % bjd=savebj(rootname,obj,'param1',value1,'param2',value2,...) % % Convert a MATLAB object (cell, struct, array, table, map, handles ...) % into a Binary JData (BJData v1 Draft-1), Universal Binary JSON (UBJSON, % Draft-12) or a MessagePack binary stream % % initially created on 2013/08/17 % % By default, this function creates BJD-compliant output. The BJD % specification is largely similar to UBJSON, with additional data types % including uint16(u), uint32(m), uint64(M) and half-precision float (h) % % Format specifications: % Binary JData (BJD): https://github.com/fangq/bjdata % UBJSON: https://github.com/ubjson/universal-binary-json % MessagePack: https://github.com/msgpack/msgpack % % input: % rootname: the name of the root-object, when set to '', the root name % is ignored, however, when opt.ForceRootName is set to 1 (see below), % the MATLAB variable name will be used as the root name. % obj: a MATLAB object (array, cell, cell array, struct, struct array, % class instance) % filename: a string for the file name to save the output UBJSON data % opt: a struct for additional options, ignore to use default values. % opt can have the following fields (first in [.|.] is the default) % % FileName [''|string]: a file name to save the output JSON data % ArrayToStruct[0|1]: when set to 0, savebj outputs 1D/2D % array in JSON array format; if sets to 1, an % array will be shown as a struct with fields % "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for % sparse arrays, the non-zero elements will be % saved to "_ArrayData_" field in triplet-format i.e. % (ix,iy,val) and "_ArrayIsSparse_":true will be added % with a value of 1; for a complex array, the % "_ArrayData_" array will include two rows % (4 for sparse) to record the real and imaginary % parts, and also "_ArrayIsComplex_":true is added. % Other annotations include "_ArrayShape_" and % "_ArrayOrder_", "_ArrayZipLevel_" etc. % NestArray [0|1]: If set to 1, use nested array constructs % to store N-dimensional arrays (compatible with % UBJSON specification Draft 12); if set to 0, % use the JData (v0.5) optimized N-D array header; % NestArray is automatically set to 1 when % MessagePack is set to 1 % ParseLogical [1|0]: if this is set to 1, logical array elem % will use true/false rather than 1/0. % SingletArray [0|1]: if this is set to 1, arrays with a single % numerical element will be shown without a square % bracket, unless it is the root object; if 0, square % brackets are forced for any numerical arrays. % SingletCell [1|0]: if 1, always enclose a cell with "[]" % even it has only one element; if 0, brackets % are ignored when a cell has only 1 element. % ForceRootName [0|1]: when set to 1 and rootname is empty, savebj % will use the name of the passed obj variable as the % root object name; if obj is an expression and % does not have a name, 'root' will be used; if this % is set to 0 and rootname is empty, the root level % will be merged down to the lower level. % JSONP [''|string]: to generate a JSONP output (JSON with padding), % for example, if opt.JSON='foo', the JSON data is % wrapped inside a function call as 'foo(...);' % UnpackHex [1|0]: conver the 0x[hex code] output by loadjson % back to the string form % Compression 'zlib', 'gzip', 'lzma', 'lzip', 'lz4' or 'lz4hc': specify array % compression method; currently only supports 6 methods. The % data compression only applicable to numerical arrays % in 3D or higher dimensions, or when ArrayToStruct % is 1 for 1D or 2D arrays. If one wants to % compress a long string, one must convert % it to uint8 or int8 array first. The compressed % array uses three extra fields % "_ArrayZipType_": the opt.Compression value. % "_ArrayZipSize_": a 1D interger array to % store the pre-compressed (but post-processed) % array dimensions, and % "_ArrayZipData_": the binary stream of % the compressed binary array data WITHOUT % 'base64' encoding % CompressArraySize [100|int]: only to compress an array if the total % element count is larger than this number. % CompressStringSize [400|int]: only to compress a string if the total % element count is larger than this number. % MessagePack [0|1]: output MessagePack (https://msgpack.org/) % binary stream instead of BJD/UBJSON % UBJSON [0|1]: 0: (default)-encode data based on BJData Draft 1 % (supports uint16(u)/uint32(m)/uint64(M)/half(h) markers) % 1: encode data based on UBJSON Draft 12 (without % u/m/M/h markers) % FormatVersion [2|float]: set the JSONLab output version; since % v2.0, JSONLab uses JData specification Draft 3 % for output format, it is incompatible with releases % older than v1.9.8; if old output is desired, % please set FormatVersion to 1.9 or earlier. % KeepType [0|1]: if set to 1, use the original data type to store % integers instead of converting to the integer type % of the minimum length without losing accuracy (default) % Debug [0|1]: output binary numbers in <%g> format for debugging % Append [0|1]: if set to 1, append a new object at the end of the file. % Endian ['n'|'b','l']: Endianness of the output file ('n': native, % 'b': big endian, 'l': little-endian) % PreEncode [1|0]: if set to 1, call jdataencode first to preprocess % the input data before saving % % opt can be replaced by a list of ('param',value) pairs. The param % string is equivallent to a field in opt and is case sensitive. % output: % bjd: a binary string in the UBJSON format (see http://ubjson.org) % % examples: % jsonmesh=struct('MeshVertex3',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... % 'MeshTet4',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... % 'MeshTri3',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... % 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... % 'MeshCreator','FangQ','MeshTitle','T6 Cube',... % 'SpecialData',[nan, inf, -inf]); % savebj(jsonmesh) % savebj('',jsonmesh,'meshdata.bjd') % savebj('mesh1',jsonmesh,'FileName','meshdata.msgpk','MessagePack',1) % savebj('',jsonmesh,'ubjson',1) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %%=== # UBJSON === %==== function varargout = loadubjson(varargin) ==== % % data=loadubjson(fname,opt) % or % data=loadubjson(fname,'param1',value1,'param2',value2,...) % % Parse a UBJSON file or string and store the output into a MATLAB variable % % initially created on 2019/06/08 % % This function is an alias to loadbj % % input: % fname: input file name, if fname contains "{}" or "[]", fname % will be interpreted as a UBJSON string % opt: a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. The supported options can be found by typing % "help loadbj". % % output: % data: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % % examples: % obj=struct('string','value','array',[1 2 3]); % ubjdata=saveubjson('obj',obj); % dat=loadubjson(ubjdata) % dat=loadubjson(['examples' filesep 'example1.ubj']) % dat=loadubjson(['examples' filesep 'example1.ubj'],'SimplifyCell',0) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function ubj=saveubjson(rootname,obj,varargin) ==== % % ubj=saveubjson(obj) % or % ubj=saveubjson(rootname,obj,filename) % ubj=saveubjson(rootname,obj,opt) % ubj=saveubjson(rootname,obj,'param1',value1,'param2',value2,...) % % Convert a MATLAB object (cell, struct, array, table, map, handles ...) % into a Universal Binary JSON (UBJSON, Draft 12) or a MessagePack binary stream % % initially created on 2013/08/17 % % Format specifications: % Binary JData (BJData):https://github.com/fangq/bjdata % UBJSON: https://github.com/ubjson/universal-binary-json % MessagePack: https://github.com/msgpack/msgpack % % This function is the same as calling "savebj(...,'ubjson',1)". By , % default this function creates UBJSON-compliant output without the % newly added uint16(u), uint32(m), uint64(M) and half-precision float (h) % data types. % % This function by default still enables an optimized ND-array format for efficient % array storage. To ensure the output compatible to UBJSON Draft-12, one should use % "saveubjson(...,'NestArray',1)" or "savebj(...,'ubjson',1,'NestArray',1)" % % input: % rootname: the name of the root-object, when set to '', the root name % is ignored, however, when opt.ForceRootName is set to 1 (see below), % the MATLAB variable name will be used as the root name. % obj: a MATLAB object (array, cell, cell array, struct, struct array, % class instance) % filename: a string for the file name to save the output UBJSON data % opt: a struct for additional options, ignore to use default values. % opt can have the following fields (first in [.|.] is the default) % % opt can be replaced by a list of ('param',value) pairs. The param % string is equivallent to a field in opt and is case sensitive. % % Please type "help savebj" for details for all supported options. % % output: % json: a binary string in the UBJSON format (see http://ubjson.org) % % examples: % jsonmesh=struct('MeshVertex3',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... % 'MeshTet4',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... % 'MeshTri3',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... % 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... % 'MeshCreator','FangQ','MeshTitle','T6 Cube',... % 'SpecialData',[nan, inf, -inf]); % saveubjson(jsonmesh) % saveubjson('',jsonmesh,'meshdata.ubj') % saveubjson('mesh1',jsonmesh,'FileName','meshdata.msgpk','MessagePack',1) % saveubjson('',jsonmesh,'KeepType',1) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %%=== # MessagePack === %==== function data = loadmsgpack(fname,varargin) ==== % % data = loadmsgpack(fname,varargin) % %LOADMSGPACK parses a msgpack byte buffer into Matlab data structures % LOADMSGPACK(BYTES) % reads BYTES as msgpack data, and creates Matlab data structures % from it. % - strings are converted to strings % - numbers are converted to appropriate numeric values % - true, false are converted to logical 1, 0 % - nil is converted to [] % - arrays are converted to cell arrays % - maps are converted to containers.Map % % (c) 2016 Bastian Bechtold % % license: % BSD 3-clause license or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function msgpk=savemsgpack(rootname,obj,varargin) ==== % % msgpk=savemsgpack(obj) % or % msgpk=savemsgpack(rootname,obj,filename) % msgpk=savemsgpack(rootname,obj,opt) % msgpk=savemsgpack(rootname,obj,'param1',value1,'param2',value2,...) % % convert a MATLAB object (cell, struct, array, table, map, handles ...) % into a MessagePack binary stream % % initially created on 2019/05/20 % % This function is the same as calling savebj(...,'MessagePack',1) % % Please type "help savebj" for details for the supported inputs and outputs. % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %%=== # Workspace === %==== function varargout=jsave(filename, varargin) ==== % % jsave % or % jsave(fname) % varlist=jsave(fname,'param1',value1,'param2',value2,...) % % Store variables in a workspace to a JSON or binary JSON file % % created on 2020/05/31 % % input: % fname: (optional) output file name; if not given, save to 'jamdata.jamm' % if fname has a '.json' or '.jdt' suffix, a text-based % JSON/JData file will be created (slow); if the suffix is '.jamm' or % '.jdb', a Binary JData (https://github.com/fangq/bjdata/) file will be created. % opt: (optional) a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % ws ['caller'|'base']: the name of the workspace in which the % variables are to be saved % vars [{'var1','var2',...}]: cell array of variable names to be saved % matlab [0|1] if set to 1, use matlab's built-in jsonencode to % store encoded data to a json file; output file % must have a suffix of .jdt % % all options for savebj/savejson (depends on file suffix) % can be used to adjust the output unless "'matlab',1" is used % % output: % varlist: a list of variables loaded % % examples: % jsave % save all variables in the 'caller' workspace to jamdata.jamm % jsave('mydat.jamm','vars', {'v1','v2',...}) % save selected variables % jsave('mydat.jamm','compression','lzma') % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout=jload(filename, varargin) ==== % % jload % or % jload(fname) % varlist=jload(fname) % [varlist, header]=jload(fname) % varlist=jload(fname,'param1',value1,'param2',value2,...) % % Load variables from a JSON or binary JSON file to a workspace % % created on 2020/05/31 % % input: % fname: (optional) input file name; if not given, load 'jamdata.jamm' % if fname has a '.json' or '.jdt' suffix, a text-based % JSON/JData file will be expected; if the suffix is '.jamm' or % '.jdb', a Binary JData file will be expected. % opt: (optional) a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % ws ['caller'|'base']: the name of the workspace in which the % variables are to be saved % vars [{'var1','var2',...}]: list of variables to be saved % header [0|1]: if set to 1, return the metadata of the variables % stored in the file % matlab [0|1] if set to 1, use matlab's built-in jsondecode to % parse the json file and then decode the output by % jdatadecode; input file must have a suffix of .jdt % % all options for loadubjson/loadjson (depends on file suffix) % can be used to adjust the parsing options % % output: % varlist: a struct with each subfield a variable stored in the file, % if output is ignored, the variables will be loaded to the % workspace specified by the 'ws' option, which by default % load the variables to the current workspace ('caller') % % examples: % jload % load all variables in jamdata.jamm to the 'caller' workspace % jload mydat.jamm % jload('mydat.jamm','vars', {'v1','v2',...}) % load selected variables % varlist=jload('mydat.jamm','simplifycell',1) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %%=== # Compression and decompression === %==== function varargout = zlibencode(varargin) ==== % % output = zlibencode(input) % or % [output, info] = zlibencode(input) % % Compress a string or numerical array using the ZLIB-compression % % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=zlibencode(eye(10)); % orig=zlibdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = zlibdecode(varargin) ==== % % output = zlibdecode(input) % or % output = zlibdecode(input,info) % % Decompressing a ZLIB-compressed byte-stream to recover the original data % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % % input: % input: a string, int8/uint8 vector or numerical array to store ZLIB-compressed data % info (optional): a struct produced by the zmat/lz4hcencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=zlibencode(eye(10)); % orig=zlibdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = gzipencode(varargin) ==== % % output = gzipencode(input) % or % [output, info] = gzipencode(input) % % Compress a string or numerical array using the GZIP-compression % % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=gzipencode(eye(10)); % orig=gzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = gzipdecode(varargin) ==== % % output = gzipdecode(input) % or % output = gzipdecode(input,info) % % Decompressing a GZIP-compressed byte-stream to recover the original data % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % % input: % input: a string, int8/uint8 vector or numerical array to store the GZIP-compressed data % info (optional): a struct produced by the zmat/lz4hcencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=gzipencode(eye(10)); % orig=gzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lzmaencode(varargin) ==== % % output = lzmaencode(input) % or % [output, info] = lzmaencode(input) % % Compress a string or a numerical array using LZMA-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lzmaencode(eye(10)); % orig=lzmadecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lzmadecode(varargin) ==== % % output = lzmadecode(input) % or % output = lzmadecode(input,info) % % Decompressing an LZMA-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: a string, int8/uint8 vector or numerical array to store LZMA-compressed data % info (optional): a struct produced by the zmat/lzmaencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lzmaencode(eye(10)); % orig=lzmadecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lzipencode(varargin) ==== % % output = lzipencode(input) % or % [output, info] = lzipencode(input) % % Compress a string or a numerical array using LZip-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lzipencode(eye(10)); % orig=lzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lzipdecode(varargin) ==== % % output = lzipdecode(input) % or % output = lzipdecode(input,info) % % Decompressing an Lzip-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: a string, int8/uint8 vector or numerical array to store Lzip-compressed data % info (optional): a struct produced by the zmat/lzipencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lzipencode(eye(10)); % orig=lzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lz4hcencode(varargin) ==== % % output = lz4encode(input) % or % [output, info] = lz4encode(input) % % Compress a string or a numerical array using LZ4-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lz4encode(eye(10)); % orig=lz4decode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lz4decode(varargin) ==== % % output = lz4decode(input) % or % output = lz4decode(input,info) % % Decompressing an LZ4-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: a string, int8/uint8 vector or numerical array to store LZ4-compressed data % info (optional): a struct produced by the zmat/lz4encode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lz4encode(eye(10)); % orig=lz4decode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lz4hcencode(varargin) ==== % % output = lz4hcencode(input) % or % [output, info] = lz4hcencode(input) % % Compress a string or a numerical array using LZ4HC-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lz4hcencode(eye(10)); % orig=lz4hcdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = lz4hcdecode(varargin) ==== % % output = lz4hcdecode(input) % or % output = lz4hcdecode(input,info) % % Decompressing an LZ4HC-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % % input: % input: a string, int8/uint8 vector or numerical array to store LZ4HC-compressed data % info (optional): a struct produced by the zmat/lz4hcencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lz4hcencode(eye(10)); % orig=lz4hcdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function varargout = base64encode(varargin) ==== % % output = base64encode(input) % % Encoding a binary vector or array using Base64 % % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % % input: % input: a base64-encoded string % % output: % output: the decoded binary byte-stream as a uint8 vector % % examples: % bytes=base64encode('Test JSONLab'); % orig=char(base64decode(bytes)) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function output = base64decode(varargin) ==== % % output = base64decode(input) % % Decoding a Base64-encoded byte-stream to recover the original data % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % % input: % input: a base64-encoded string % % output: % output: the decoded binary byte-stream as a uint8 vector % % examples: % bytes=base64encode('Test JSONLab'); % orig=char(base64decode(bytes)) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function str = encodevarname(str,varargin) ==== % % newname = encodevarname(name) % % Encode an invalid variable name using a hex-format for bi-directional % conversions. % This function is sensitive to the default charset % settings in MATLAB, please call feature('DefaultCharacterSet','utf8') % to set the encoding to UTF-8 before calling this function. % % % input: % name: a string, can be either a valid or invalid variable name % % output: % newname: a valid variable name by converting the leading non-ascii % letter into "x0xHH_" and non-ascii letters into "_0xHH_" % format, where HH is the ascii (or Unicode) value of the % character. % % if the encoded variable name CAN NOT be longer than 63, i.e. % the maximum variable name specified by namelengthmax, and % one uses the output of this function as a struct or variable % name, the name will be trucated at 63. Please consider using % the name as a containers.Map key, which does not have such % limit. % % example: % encodevarname('_a') % returns x0x5F_a % encodevarname('a_') % returns a_ as it is a valid variable name % encodevarname('变量') % returns 'x0xE58F98__0xE9878F_' % %==== function newname = decodevarname(name,varargin) ==== % % newname = decodevarname(name) % % Decode a hex-encoded variable name (from encodevarname) and restore % its original form % % This function is sensitive to the default charset % settings in MATLAB, please call feature('DefaultCharacterSet','utf8') % to set the encoding to UTF-8 before calling this function. % % % input: % name: a string output from encodevarname, which converts the leading non-ascii % letter into "x0xHH_" and non-ascii letters into "_0xHH_" % format, where hex key HH stores the ascii (or Unicode) value % of the character. % % output: % newname: the restored original string % % example: % decodevarname('x0x5F_a') % returns _a % decodevarname('a_') % returns a_ as it is a valid variable name % decodevarname('x0xE58F98__0xE9878F_') % returns '变量' % %%=== # Miscellaneous functions === %==== function val=jsonopt(key,default,varargin) ==== % % val=jsonopt(key,default,optstruct) % % setting options based on a struct. The struct can be produced % by varargin2struct from a list of 'param','value' pairs % % % input: % key: a string with which one look up a value from a struct % default: if the key does not exist, return default % optstruct: a struct where each sub-field is a key % % output: % val: if key exists, val=optstruct.key; otherwise val=default % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function s=mergestruct(s1,s2) ==== % % s=mergestruct(s1,s2) % % merge two struct objects into one % % % input: % s1,s2: a struct object, s1 and s2 can not be arrays % % output: % s: the merged struct object. fields in s1 and s2 will be combined in s. % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function opt=varargin2struct(varargin) ==== % % opt=varargin2struct('param1',value1,'param2',value2,...) % or % opt=varargin2struct(...,optstruct,...) % % convert a series of input parameters into a structure % % % input: % 'param', value: the input parameters should be pairs of a string and a value % optstruct: if a parameter is a struct, the fields will be merged to the output struct % % output: % opt: a struct where opt.param1=value1, opt.param2=value2 ... % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function [endpos, maxlevel] = match_bracket(str,startpos,brackets) ==== % % [endpos, maxlevel] = match_bracket(str,startpos,brackets) % % Looking for the position of a closing bracket token in a string % % % input: % str: the full string to be searched % startpos: the index in the string as the start position to search; the % startpos must be at least 1 greater than the opening bracket position % brackets: (optional), a string of length 2, with the first character % being the opening token and the 2nd being the closing token. % if not given, brackets is set to '[]' to find matching square-brackets; % for example, '{}' looks for a matching closing curly-bracket in % the string key(pos(startpos,:end)) % % output: % endpos: if a matching bracket is found, return its position in the original % string % maxlevel: return the depth of the enclosed brackets between the searched pair, % includig the searching pair. For example, the matching closing-bracket % of the 1st square bracket (startpos=2) in '[[[]],[]]' returns a % position of 9, with a maximum depth of 3; searching for the closing % bracket for the 2nd square bracket (startpos=3) returns a position of % 5 and max-depth of 2. % % example: % str='[[ [1,2], 1], 10, [5,10] ]'; % [p1,dep]=match_bracket(str,3) % [p2,dep]=match_bracket(str,2) % [p3,dep]=match_bracket(str,3) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function [endpos, maxlevel] = fast_match_bracket(key,pos,startpos,brackets) ==== % % [endpos, maxlevel] = fast_match_bracket(key,pos,startpos,brackets) % % A fast function to find the position of a closing bracket token in a string % % % input: % key: a preprocessed string containing only relevant opening/closing % bracket characters for accelerating the search. % pos: a 1D integer vector with a length matching the length of key, % recording the corresponding position of each char. in the original string. % startpos: the index in the original string as the start position to search; the % startpos must be at least 1 greater than the opening bracket position % brackets: (optional), a string of length 2, with the first character % being the opening token and the 2nd being the closing token. % if not given, brackets is set to '[]' to find matching square-brackets; % for example, '{}' looks for a matching closing curly-bracket in % the string key(pos(startpos,:end)) % % output: % endpos: if a matching bracket is found, return its position in the original % string % maxlevel: return the depth of the enclosed brackets between the searched pair, % includig the searching pair. For example, the matching closing-bracket % of the 1st square bracket (startpos=2) in '[[[]],[]]' returns a % position of 9, with a maximum depth of 3; searching for the closing % bracket for the 2nd square bracket (startpos=3) returns a position of % 5 and max-depth of 2. % % example: % str='[[ [1,2], 1], 10, [5,10] ]'; % pos=find(str=='[' | str==']') % key=str(pos) % [p1,dep]=fast_match_bracket(key,1:length(key),3) % [p2,dep]=fast_match_bracket(key,pos,2) % [p3,dep]=fast_match_bracket(key,pos,3) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % %==== function [dims, maxlevel, count] = nestbracket2dim(str,brackets) ==== % % [dims, maxlevel, count] = nestbracket2dim(str,brackets) % % Extracting the dimension vector of a JSON string formatted array % by analyzing the pairs of opening/closing bracket tokenss; this function % only returns valid dimension information when the array is an N-D array % % % input: % str: a string-formatted JSON array using square-brackets for enclosing % elements and comma as separators between elements % brackets: (optional), a string of length 2, with the first character % being the opening token and the 2nd being the closing token. % if not given, brackets is set to '[]' to find matching square-brackets; % for example, '{}' looks for a matching closing curly-bracket in % the string key(pos(startpos,:end)) % % output: % dims: the speculated dimension vector with the length matching the maximum % depth of the embedded bracket pairs. When the input string encodes an % N-D array, the dims vector contains all integers; however, returning % an all-integer dims vector does not mean the array is rectangular. % maxlevel: return the depth of the enclosed brackets in the string, i.e. the % length of the dims vector. % count: the relative depth from the level 0 - scanning from the left % to right of the string, an opening token increases the level by 1 % and a closing token decreases the level by 1; a zero indicates % the positions of a matching bracket of the same level. % % example: % str='[[ [1,2,3], [4,2,1]], [ [10,1,0], [2,5,10]] ]'; % an N-D array % [dim,dep]=nestbracket2dim(str) % str='[[ [1,2,3], [4,2,1]], [ [10,1,0], [2,5]] ]'; % an invalid N-D array % [dim,dep]=nestbracket2dim(str) % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % jsonlab-2.0/DESCRIPTION000066400000000000000000000012261367147361400145260ustar00rootroot00000000000000Name: jsonlab Version: 2.0 Date: 2020-13-06 Title: A JSON/UBJSON/MessagePack encoder/decoder for MATLAB/Octave Author: Qianqian Fang Maintainer: Qianqian Fang Description: JSONLab is a free and open-source implementation of a JSON/UBJSON/MessagePack encoder and a decoder in the native MATLAB language. It can be used to convert a MATLAB data structure (array, struct, cell, struct array and cell array) into JSON/UBJSON formatted string, or decode a JSON/UBJSON/MessagePack file into MATLAB data. JSONLab supports both MATLAB and GNU Octave (a free MATLAB clone). URL: http://openjdata.org/jsonlab Categories: JSON jsonlab-2.0/INDEX000066400000000000000000000011051367147361400136060ustar00rootroot00000000000000jsonlab >> JSONLab JSON loadjson savejson UBJSON loadubjson saveubjson MessagePack loadmsgpack savemsgpack JData Workspace jload jsave JData Specificaton jdatadecode jdataencode Compression and Decompression base64decode base64encode gzipdecode gzipencode lz4decode lz4encode lz4hcdecode lz4hcencode lzipdecode lzipencode lzmadecode lzmaencode zlibdecode zlibencode Helper Functions decodevarname encodevarname fast_match_bracket find_matching_paren isoctavemesh jsonopt match_bracket matching_bracket mergestruct nestbracket2dim varargin2struct jsonlab-2.0/LICENSE_BSD.txt000066400000000000000000000032521367147361400153340ustar00rootroot00000000000000Copyright (c) 2011-2020 Qianqian Fang Copyright (c) 2014,2016 Bastian Bechtold Copyright (c) 2012, Kota Yamaguchi Copyright (c) 2009, Nedialko Krouchev Copyright (c) 2009, Franois Glineur Copyright (c) 2008, Joel Feenstra All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jsonlab-2.0/LICENSE_GPLv3.txt000066400000000000000000001067131367147361400156250ustar00rootroot00000000000000=============================================================================== = JSONlab = = An open-source MATLAB/Octave JSON encoder and decoder = =============================================================================== Copyright (C) 2011-2020 Qianqian Fang neu.edu> ------------------------------------------------------------------------------- This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . ------------------------------------------------------------------------ GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . jsonlab-2.0/README.rst000066400000000000000000000650101367147361400145100ustar00rootroot00000000000000.. image:: ./images/jsonlab-banner.png ############################################################################## JSONLab: An open-source MATLAB/Octave JSON encoder and decoder ############################################################################## * Copyright (C) 2011-2020 Qianqian Fang * License: BSD or GNU General Public License version 3 (GPL v3), see License*.txt * Version: 2.0 (Magnus Prime) * JData Specification Version: Draft 3 (http://github.com/fangq/jdata) * URL: http://openjdata.org/jsonlab ################# Table of Contents ################# .. contents:: :local: :depth: 3 ============ What's New ============ JSONLab v2.0 - code named "Magnus Prime" - is a stable release of JSONLab and a new milestone towards a stable, complete reference implementation of the JData Specification (http://openjdata.org) for portable scientific data storage. There have been many major updates added to this release since the previous release v1.9.8 in Oct. 2019. A list of the major changes are summarized below (with key features marked by *), including the support to ``_ArrayShape_`` to efficiently encode special matrices and the addition of ``jsave/jload`` to save and restore variables in MATLAB/Octave like the ``save/load`` commands (experimental): - 2020-06-13 [81feef3] skil no-op markers, update documentation - 2020-06-13 [4904155] jload load data to struct, test if loadbj input is buffer, update error msg - 2020-06-12 [c334799] change default workspace to caller for jload and jsave - 2020-06-10 [c883546] fix keeptype single integer bug - 2020-06-09*[ ] created ``jdata`` and ``bjdata`` python modules to share data with MATLAB - 2020-06-08*[cbde607] add savebj and loadbj to dedicate to loading and saving bjdata - 2020-06-08*[e2451e1] add unit testing script, fix issues found in the testing unit - 2020-06-06 [a44015f] accelerate fast_match_bracket, drop unicode2native for speed - 2020-06-06 [eefccf3] call jsonencode/decode in jsave/jload, parse embedded jdata struct - 2020-06-05 [9434103] support Toeplitz matrices, use case-insensitive comparison - 2020-06-04 [3119ce4] jdatadecode now handles _ArrayOrder_ - 2020-06-04 [89b844c] remove forced root name, update internal test results - 2020-06-02*[15ca7ae] add keeptype option to jsave and saveubjson - 2020-06-02 [7f2cbc4] make jsave and jload work on octave - 2020-06-01*[8829d6b] apply data compression to strings, new datatype char - 2020-06-01 [270cbf6] fix loadmsgpack ND array issue - 2020-06-01*[919f502] add jsave and jload for portable data sharing,update doc - 2020-05-31 [df3a4fa] debug arrayshape related changes and test all demo scripts - 2020-05-31*[fc0b285] adding support to _ArrayShape_ to record special matrices - 2020-05-15*[d88d454] jsonlab is compatible with matlab R2008 - 2020-05-13 [86efe89] flag to prevent embedding ND array size specifier - 2020-05-07 [a189a50] use more robust integer type testing - 2020-05-06*[82f5249] saveubjson now implments BJData spec Draft1,https://github.com/fangq/bjdata - 2020-05-03 [34bca22] add prj file to compile a matlab package, close #60 - 2020-05-03 [82dfdcc] handle empty array in loadmsgpack, fix #63, patch by stfnp - 2020-03-08 [7499bd8] Merge pull request #61 from j2L4e/patch-1 - 2020-02-09*[6984111] add UseMap option to avoid key name conversion - 2019-11-16 [e46221a] if _ArraySize_ has a single length, treat as a row vector - 2019-11-01 [f2bfb65] fix a uint8 upper bound bug - 2019-10-24 [cc4491d] avoid escaping base64 str, avoid double processing preencoded arrayzipdata - 2019-10-24 [4dc76ef] make example script compatible with matlab R2010 - 2019-10-24 [ad8be26] disable underscore escaping in octave,update all tests and outputs - 2019-10-24 [d4275c6] reduce jsonopt calls to speed up encoding and decoding - 2019-10-23 [82c9e91] fix invalid jdatadecode example - 2019-10-23 [398539d] reoptimize for speed - 2019-10-22*[650b5ec] enable jdataencode in savejson and saveubjson Please note that JSONLab v2.0 is now compliant with JData Spec Draft 3; in comparison v1.9.8 is compatible with Draft 2; v1.9 and previous releases are compatible with Draft 1. JSONLab v2.0 can read all data files generated by v1.9.8, but v1.9.8 can not read the new UBJSON markers introduced in v2.0. The newly introduced ``jsave/jload`` functions are in the experimental stage. They generate ``.jamm`` files which are renamed binary-JData/UBJSON files; they can be 50% smaller than ``.mat`` files if using ``jsave(...,'compression','lzma')`` and can be readily opened among a long list of programming environments such as Python, JavaScript and Go. The ``saveubjson/loadubjson`` functions added support to the Binary JData specification (BJData) v1 Draft-1 (https://github.com/fangq/bjdata) and are now renamed as ``savebj/loadbj`` (``saveubjson/loadubjson`` are kept for compatibility purposes as aliases to the new functions). The BJData spec is largely compatible with UBJSON spec Draft 12, with the following differences (we are working with the UBJSON maintainer to merge these two specifications): - BJData adds 4 new numeric data types: ``uint16 [u]``, ``uint32 [m]``, ``uint64 [M]`` and ``float16 [h]`` ('''new in JSONLab v2.0''') - BJData supports an optimized ND array container (supported in JSONLab since 2013) - BJData does not convert ``NaN/Inf/-Inf`` to ``null`` (supported in JSONLab since 2013) To avoid using the new type markers, one should attach ``'UBJSON',1`` in the ``savebj`` command as .. code-block:: matlab savebj('',data,'FileName','myfile.bjd','UBJSON',1); To read data files generated by JSONLab v1.9 or older versions, you need to attach option ``'FormatVersion', 1.9`` in all the ``loadjson/savejson`` function calls. To convert an older file (JSON/UBJSON) to the new format, you should run .. code-block:: matlab data=loadjson('my_old_data_file.json','FormatVersion',1.9) savejson('',data,'FileName','new_file.json') You are strongly encouraged to convert all pre-v1.9.8 generated data files using the new format. ============ Introduction ============ JSONLab is a free and open-source JSON/UBJSON/MessagePack encoder and decoder written in the native MATLAB language. It can be used to convert a MATLAB data structure (array, struct, cell, struct array, cell array, and objects) into JSON/UBJSON/MessagePack formatted strings and files, or to parse a JSON/UBJSON/MessagePack file into MATLAB data structure. JSONLab supports both MATLAB and `GNU Octave `_ (a free MATLAB clone). JSON (`JavaScript Object Notation `_) is a highly portable, human-readable and `"fat-free" `_ text format to represent complex and hierarchical data, widely used for data-exchange in applications. UBJSON (`Universal Binary JSON `_) is a binary JSON format, specifically designed to specifically address the limitations of JSON, permitting the storage of binary data with strongly typed data records, resulting in smaller file sizes and fast encoding and decoding. MessagePack is another binary JSON-like data format widely used in data exchange in web/native applications. It is slightly more compact than UBJSON, but is not directly readable compared to UBJSON. We envision that both JSON and its binary counterparts will play important rules not only for light-weight data storage, but also for storage and interchange of scientific data. It has both the flexibility and generality as in other general-purpose file specifications, such as `HDF5 `_ but has significantly reduced complexity and excellent readability. Towards this goal, we have developed the JData Specification (http://github.com/fangq/jdata) to standardize serializations of complex scientific data structures, such as N-D arrays, sparse/complex-valued arrays, trees, maps, tables and graphs using JSON/binary JSON constructs. The text and binary formatted JData files are syntactically compatible with JSON/UBJSON formats, and can be readily parsed using existing JSON and UBJSON parsers. JSONLab is not just a parser and writer of JSON/UBJSON data files, but one that systematically converts complex scientific data structures into human-readable and universally supported JSON forms using the standardized JData data annotations. ================ Installation ================ The installation of JSONLab is no different from installing any other MATLAB toolbox. You only need to download/unzip the JSONLab package to a folder, and add the folder's path to MATLAB/Octave's path list by using the following command: .. code:: shell addpath('/path/to/jsonlab'); If you want to add this path permanently, you can type ``pathtool``, browse to the JSONLab root folder and add to the list, then click "Save". Then, run ``rehash`` in MATLAB, and type ``which savejson``, if you see an output, that means JSONLab is installed for MATLAB/Octave. If you use MATLAB in a shared environment such as a Linux server, the best way to add path is to type .. code:: shell mkdir ~/matlab/ nano ~/matlab/startup.m and type ``addpath('/path/to/jsonlab')`` in this file, save and quit the editor. MATLAB will execute this file every time it starts. For Octave, the file you need to edit is ``~/.octaverc``, where ``~`` is your home directory. To use the data compression features, please download the ZMat toolbox from https://github.com/fangq/zmat/releases/latest and follow the instruction to install ZMat first. The ZMat toolbox is required when compression is used on MATLAB running in the ``-nojvm`` mode or GNU Octave, or 'lzma/lzip/lz4/lz4hc' compression methods are specified. ZMat can also compress large arrays that MATLAB's Java-based compression API does not support. ---------- Install JSONLab on Fedora 24 or later ---------- JSONLab has been available as an official Fedora package since 2015. You may install it directly using the below command .. code:: shell sudo dnf install octave-jsonlab To enable data compression/decompression, you need to install ``octave-zmat`` using .. code:: shell sudo dnf install octave-zmat ---------- Install JSONLab on Arch Linux ---------- JSONLab is also available on Arch Linux. You may install it using the below command .. code:: shell sudo pikaur -S jsonlab ================ Using JSONLab ================ JSONLab provides a pair of functions, ``loadjson`` -- a JSON parser, and ``savejson`` -- a MATLAB-to-JSON encoder, to read/write the text-based JSON; and two equivallent pairs -- ``loadubjson/saveubjson`` for binary JSON and ``loadmsgpack/savemsgpack`` for MessagePack. The ``load*`` functions for the 3 supported data formats share almost the same input parameter format; similarly for the 3 ``save*`` functions (``savejson/saveubjson/savemsgpack``) These encoders and decoders are capable of processing/sharing almost all data structures supported by MATLAB, thanks to ``jdataencode/jdatadecode`` - a pair of in-memory data converters translating complex data structures to the easy-to-serialized forms according to the JData specifications. The detailed help information can be found in the ``Contents.m`` file. In the below section, we provide a few examples on how to us each of the core functions for encoding/decoding JSON/UBJSON/MessagePack data. ---------- savejson.m ---------- .. code-block:: matlab jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... 'MeshElem',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... 'MeshSurf',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... 'MeshCreator','FangQ','MeshTitle','T6 Cube',... 'SpecialData',[nan, inf, -inf]); savejson(jsonmesh) savejson('jmesh',jsonmesh) savejson('',jsonmesh,'Compact',1) savejson('jmesh',jsonmesh,'outputfile.json') savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g','FileName','outputfile2.json') savejson('cpxrand',eye(5)+1i*magic(5)) savejson('ziparray',eye(10),'Compression','zlib','CompressArraySize',1) savejson('',jsonmesh,'ArrayToStruct',1) savejson('',eye(10),'UseArrayShape',1) ---------- loadjson.m ---------- .. code-block:: matlab loadjson('{}') dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}') dat=loadjson(['examples' filesep 'example1.json']) dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',0) ------------- savebj.m (saveubjson.m as an alias) ------------- .. code-block:: matlab a={single(rand(2)), struct('va',1,'vb','string'), 1+2i}; savebj(a) savebj('rootname',a,'testdata.ubj') savebj('zeros',zeros(100),'Compression','gzip') ------------- loadbj.m (loadubjson.m as an alias) ------------- .. code-block:: matlab obj=struct('string','value','array',single([1 2 3]),'empty',[],'magic',uint8(magic(5))); ubjdata=savebj('obj',obj); dat=loadbj(ubjdata) class(dat.obj.array) isequaln(obj,dat.obj) dat=loadbj(savebj('',eye(10),'Compression','zlib','CompressArraySize',1)) ---------- jdataencode.m ---------- .. code-block:: matlab jd=jdataencode(struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5))) savejson('',jd) ---------- jdatadecode.m ---------- .. code-block:: matlab rawdata=struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5)); jd=jdataencode(rawdata) newjd=jdatadecode(jd) isequaln(newjd,rawdata) --------- examples --------- Under the ``examples`` folder, you can find several scripts to demonstrate the basic utilities of JSONLab. Running the ``demo_jsonlab_basic.m`` script, you will see the conversions from MATLAB data structure to JSON text and backward. In ``jsonlab_selftest.m``, we load complex JSON files downloaded from the Internet and validate the ``loadjson/savejson`` functions for regression testing purposes. Similarly, a ``demo_ubjson_basic.m`` script is provided to test the ``saveubjson`` and ``loadubjson`` functions for various matlab data structures, and ``demo_msgpack_basic.m`` is for testing ``savemsgpack`` and ``loadmsgpack``. Please run these examples and understand how JSONLab works before you use it to process your data. --------- unit testing --------- Under the ``test`` folder, you can find a script to test individual data types and inputs using various encoders and decoders. This unit testing script also serves as a **specification validator** to the JSONLab functions and ensure that the outputs are compliant to the underlying specifications. ================ Using ``jsave/jload`` to share workspace ================ Starting from JSONLab v2.0, we provide a pair of functions, ``jsave/jload`` to store and retrieve variables from the current workspace, similar to the ``save/load`` functions in MATLAB and Octave. The files that ``jsave/jload`` reads/writes is by default a binary JData file with a suffix ``.jamm``. The file size is comparable (can be smaller if use ``lzma`` compression) to ``.mat`` files. This feature is currently experimental. The main benefits of using .jamm file to share matlab variables include * a ``.jamm`` file can be 50% smaller than a ``.mat`` file when using ``jsave(..., "compression","lzma")``; the only drawback is longer saving time. * a ``.jamm`` file can be readily read/opened among many programming environments, including Python, JavaScript, Go, Java etc, where .mat file support is not generally available. Parsers of ``.jamm`` files are largely compatible with UBJSON's parsers available at http://ubjson.org/?page_id=48 * a ``.jamm`` file is quasi-human-readable, one can see the internal data fields even in a command line, for example using ``strings -n 2 file.jamm | astyle``, making the binary data easy to be understood, shared and reused. * ``jsave/jload`` can also use MessagePack and JSON formats as the underlying data storage format, addressing needs from a diverse set of applications. MessagePack parsers are readily available at https://msgpack.org/ ---------- jsave.m ---------- .. code-block:: matlab jsave % save the current workspace to jamdata.jamm jsave mydata.jamm jsave('mydata.jamm','vars',{'var1','var2'}) jsave('mydata.jamm','compression','lzma') jsave('mydata.json','compression','gzip') ---------- jload.m ---------- .. code-block:: matlab jload % load variables from jamdata.jamm to the current workspace jload mydata.jamm % load variables from mydata.jamm vars=jload('mydata.jamm','vars',{'var1','var2'}) % return vars.var1, vars.var2 jload('mydata.jamm','simplifycell',0) jload('mydata.json') ================ Sharing JSONLab created data files in Python ================ Despite the use of portable data annotation defined by the JData Specification, the output JSON files created by JSONLab are 100% JSON compatible (with the exception that long strings may be broken into multiple lines for better readability). Therefore, JSONLab-created JSON files (``.json, .jnii, .jnirs`` etc) can be readily read and written by nearly all existing JSON parsers, including the built-in ``json`` module parser in Python. However, we strongly recommend one to use a lightweight ``jdata`` module, developed by the same author, to perform the extra JData encoding and decoding and convert JSON data directly to convenient Python/Numpy data structures. The ``jdata`` module can also directly read/write UBJSON/Binary JData outputs from JSONLab (``.bjd, .ubj, .bnii, .bnirs, .jamm`` etc). Using binary JData files are exptected to produce much smaller file sizes and faster parsing, while maintainining excellent portability and generality. In short, to conveniently read/write data files created by JSONLab into Python, whether they are JSON based or binary JData/UBJSON based, one just need to download the below two light-weight python modules: * **jdata**: PyPi: https://pypi.org/project/jdata/ ; Github: https://github.com/fangq/pyjdata * **bjdata** PyPi: https://pypi.org/project/bjdata/ ; Github: https://github.com/fangq/pybj To install these modules on Python 2.x, please first check if your system has ``pip`` and ``numpy``, if not, please install it by running (using Ubuntu/Debian as example) .. code-block:: shell sudo apt-get install python-pip python3-pip python-numpy python3-numpy After the installation is done, one can then install the ``jdata`` and ``bjdata`` modules by .. code-block:: shell pip install jdata --user pip install bjdata --user To install these modules for Python 3.x, please replace ``pip`` by ``pip3``. If one prefers to install these modules globally for all users, simply execute the above commands using .. code-block:: shell sudo pip install jdata sudo pip install bjdata The above modules require built-in Python modules ``json`` and NumPy (``numpy``). Once the necessary modules are installed, one can type ``python`` (or ``python3``), and run .. code-block:: python import jdata as jd import numpy as np from collections import OrderedDict data1=jd.loadt('myfile.json',object_pairs_hook=OrderedDict); data2=jd.loadb('myfile.ubj',object_pairs_hook=OrderedDict); data3=jd.loadb('myfile.jamm',object_pairs_hook=OrderedDict); where ``jd.loadt()`` function loads a text-based JSON file, performs JData decoding and converts the enclosed data into Python ``dict``, ``list`` and ``numpy`` objects. Similarly, ``jd.loadb()`` function loads a binary JData/UBJSON file and performs similar conversions. One can directly call ``jd.load()`` to open JSONLab (and derived toolboxes such as **jnifti**: https://github.com/fangq/jnifti or **jsnirfy**: https://github.com/fangq/jsnirfy) generated files based on their respective file suffix. Similarly, the ``jd.savet()``, ``jd.saveb()`` and ``jd.save`` functions can revert the direction and convert a Python/Numpy object into JData encoded data structure and store as text-, binary- and suffix-determined output files, respectively. ======================= Known Issues and TODOs ======================= JSONLab has several known limitations. We are striving to make it more general and robust. Hopefully in a few future releases, the limitations become less. Here are the known issues: * 3D or higher dimensional cell/struct-arrays will be converted to 2D arrays * When processing names containing multi-byte characters, Octave and MATLAB can give different field-names; you can use ``feature('DefaultCharacterSet','latin1')`` in MATLAB to get consistant results * ``savejson`` can only export the properties from MATLAB classes, but not the methods * ``saveubjson`` converts a logical array into a ``uint8`` (``[U]``) array * a special N-D array format, as defined in the JData specification, is implemented in ``saveubjson``. You may use ``saveubjson(...,'NestArray',1)`` to create UBJSON Draft-12 compliant files * ``loadubjson`` can not parse all UBJSON Specification (Draft 12) compliant files, however, it can parse all UBJSON files produced by ``saveubjson``. ========================== Contribution and feedback ========================== JSONLab is an open-source project. This means you can not only use it and modify it as you wish, but also you can contribute your changes back to JSONLab so that everyone else can enjoy the improvement. For anyone who want to contribute, please download JSONLab source code from its source code repositories by using the following command: .. code:: shell git clone https://github.com/fangq/jsonlab.git jsonlab or browsing the github site at https://github.com/fangq/jsonlab Please report any bugs or issues to the below URL: https://github.com/fangq/jsonlab/issues Sometimes, you may find it is necessary to modify JSONLab to achieve your goals, or attempt to modify JSONLab functions to fix a bug that you have encountered. If you are happy with your changes and willing to share those changes to the upstream author, you are recommended to create a pull-request on github. To create a pull-request, you first need to "fork" jsonlab on Github by clicking on the "fork" button on top-right of jsonlab's github page. Once you forked jsonlab to your own directory, you should then implement the changes in your own fork. After thoroughly testing it and you are confident the modification is complete and effective, you can then click on the "New pull request" button, and on the left, select fangq/jsonlab as the "base". Then type in the description of the changes. You are responsible to format the code updates using the same convention (tab-width: 8, indentation: 4 spaces) as the upstream code. We appreciate any suggestions and feedbacks from you. Please use the following mailing list to report any questions you may have regarding JSONLab: https://github.com/fangq/jsonlab/issues (Subscription to the mailing list is needed in order to post messages). ========================== Acknowledgement ========================== --------- loadjson.m --------- The ``loadjson.m`` function was significantly modified from the earlier parsers (BSD 3-clause licensed) written by the below authors * Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713 created on 2009/11/02 * François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393 created on 2009/03/22 * Joel Feenstra: http://www.mathworks.com/matlabcentral/fileexchange/20565 created on 2008/07/03 --------- loadmsgpack.m --------- * Author: Bastian Bechtold * URL: https://github.com/bastibe/matlab-msgpack/blob/master/parsemsgpack.m * License: BSD 3-clause license Copyright (c) 2014,2016 Bastian Bechtold All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------- zlibdecode.m, zlibencode.m, gzipencode.m, gzipdecode.m, base64encode.m, base64decode.m --------- * Author: Kota Yamaguchi * URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities * License: BSD License, see below Copyright (c) 2012, Kota Yamaguchi All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jsonlab-2.0/README.txt000066400000000000000000000645531367147361400145320ustar00rootroot00000000000000=============================================================================== = JSONLab = = An open-source MATLAB/Octave JSON encoder and decoder = =============================================================================== * Copyright (C) 2011-2020 Qianqian Fang * License: BSD or GNU General Public License version 3 (GPL v3), see License*.txt * Version: 2.0 (Magnus Prime) * JData Specification Version: Draft 3 (http://github.com/fangq/jdata) * URL: http://openjdata.org/jsonlab ------------------------------------------------------------------------------- Table of Content: 0. What's New I. Introduction II. Installation III. Using JSONLab IV. Using `jsave/jload` to share workspace V. Sharing JSONLab created data files in Python VI. Known Issues and TODOs VII. Contribution and feedback VIII.Acknowledgement ------------------------------------------------------------------------------- 0. What's New JSONLab v2.0 - code named "Magnus Prime" - is a stable release of JSONLab and a new milestone towards a stable, complete reference implementation of the JData Specification (http://openjdata.org) for portable scientific data storage. There have been many major updates added to this release since the previous release v1.9.8 in Oct. 2019. A list of the major changes are summarized below (with key features marked by *), including the support to `_ArrayShape_` to efficiently encode special matrices and the addition of `jsave/jload` to save and restore variables in MATLAB/Octave like the `save/load` commands (experimental): * 2020-06-13 [81feef3] skil no-op markers, update documentation * 2020-06-13 [4904155] jload load data to struct, test if loadbj input is buffer, update error msg * 2020-06-12 [c334799] change default workspace to caller for jload and jsave * 2020-06-10 [c883546] fix keeptype single integer bug * 2020-06-09*[ ] created `jdata` and `bjdata` python modules to share data with MATLAB * 2020-06-08*[cbde607] add savebj and loadbj to dedicate to loading and saving bjdata * 2020-06-08*[e2451e1] add unit testing script, fix issues found in the testing unit * 2020-06-06 [a44015f] accelerate fast_match_bracket, drop unicode2native for speed * 2020-06-06 [eefccf3] call jsonencode/decode in jsave/jload, parse embedded jdata struct * 2020-06-05 [9434103] support Toeplitz matrices, use case-insensitive comparison * 2020-06-04 [3119ce4] jdatadecode now handles _ArrayOrder_ * 2020-06-04 [89b844c] remove forced root name, update internal test results * 2020-06-02*[15ca7ae] add keeptype option to jsave and saveubjson * 2020-06-02 [7f2cbc4] make jsave and jload work on octave * 2020-06-01*[8829d6b] apply data compression to strings, new datatype char * 2020-06-01 [270cbf6] fix loadmsgpack ND array issue * 2020-06-01*[919f502] add jsave and jload for portable data sharing * 2020-05-31 [df3a4fa] debug arrayshape related changes and test all demo scripts * 2020-05-31*[fc0b285] adding support to _ArrayShape_ to record special matrices * 2020-05-15*[d88d454] jsonlab is compatible with matlab R2008 * 2020-05-13 [86efe89] flag to prevent embedding ND array size specifier * 2020-05-07 [a189a50] use more robust integer type testing * 2020-05-06*[82f5249] saveubjson now implments BJData spec Draft1,https://github.com/fangq/bjdata * 2020-05-03 [34bca22] add prj file to compile a matlab package, close #60 * 2020-05-03 [82dfdcc] handle empty array in loadmsgpack, fix #63, patch by stfnp * 2020-03-08 [7499bd8] Merge pull request #61 from j2L4e/patch-1 * 2020-02-09*[6984111] add UseMap option to avoid key name conversion * 2019-11-16 [e46221a] if _ArraySize_ has a single length, treat as a row vector * 2019-11-01 [f2bfb65] fix a uint8 upper bound bug * 2019-10-24 [cc4491d] avoid escaping base64 str, avoid double processing preencoded arrayzipdata * 2019-10-24 [4dc76ef] make example script compatible with matlab R2010 * 2019-10-24 [ad8be26] disable underscore escaping in octave,update all tests and outputs * 2019-10-24 [d4275c6] reduce jsonopt calls to speed up encoding and decoding * 2019-10-23 [82c9e91] fix invalid jdatadecode example * 2019-10-23 [398539d] reoptimize for speed * 2019-10-22*[650b5ec] enable jdataencode in savejson and saveubjson Please note that JSONLab v2.0 is now compliant with JData Spec Draft 3; in comparison, v1.9.8 is compatible with Draft 2; v1.9 and previous releases are compatible with Draft 1. JSONLab v2.0 can read all data files generated by v1.9.8, but v1.9.8 can not read the new UBJSON markers introduced in v2.0. The newly introduced `jsave/jload` functions are in the experimental stage. They generate `.jamm` files which are renamed binary-JData/UBJSON files; they can be 50% smaller than `.mat` files if using `jsave(...,'compression','lzma')` and can be readily opened among a long list of programming environments such as Python, JavaScript and Go. The `saveubjson/loadubjson` functions added support to the Binary JData specification (BJData) v1 Draft-1 (https://github.com/fangq/bjdata) and are now renamed as `savebj/loadbj` (`saveubjson/loadubjson` are kept for compatibility purposes as aliases to the new functions). The BJData spec is largely compatible with UBJSON spec Draft 12, with the following differences (we are working with the UBJSON maintainer to merge these two specifications): * BJData adds 4 new numeric data types: `uint16 [u]`, `uint32 [m]`, `uint64 [M]` \ and `float16 [h]` ('''new in JSONLab v2.0''') * BJData supports an optimized ND array container (supported in JSONLab since 2013) * BJData does not convert `NaN/Inf/-Inf` to `null` (supported in JSONLab since 2013) To avoid using the new type markers, one should attach `'UBJSON',1` in the `savebj` command as savebj('',data,'FileName','myfile.bjd','UBJSON',1); To read data files generated by JSONLab v1.9 or older versions, you need to attach option `'FormatVersion', 1.9` in all the `loadjson/savejson` function calls. To convert an older file (JSON/UBJSON) to the new format, you should run data=loadjson('my_old_data_file.json','FormatVersion',1.9) savejson('',data,'FileName','new_file.json') You are strongly encouraged to convert all pre-v1.9.8 generated data files using the new format. ------------------------------------------------------------------------------- I. Introduction JSONLab is a free and open-source JSON/UBJSON/MessagePack encoder and decoder written in the native MATLAB language. It can be used to convert a MATLAB data structure (array, struct, cell, struct array, cell array, and objects) into JSON/UBJSON/MessagePack formatted strings and files, or to parse a JSON/UBJSON/MessagePack file into MATLAB data structure. JSONLab supports both MATLAB and [http://www.gnu.org/software/octave GNU Octave] (a free MATLAB clone). JSON ([http://www.json.org/ JavaScript Object Notation]) is a highly portable, human-readable and [http://en.wikipedia.org/wiki/JSON "fat-free"] text format to represent complex and hierarchical data, widely used for data-exchange in applications. UBJSON ([http://ubjson.org/ Universal Binary JSON]) is a binary JSON format, specifically designed to specifically address the limitations of JSON, permitting efficient storage of binary data with strongly typed data records, resulting in smaller file sizes and fast encoding and decoding. MessagePack is another binary JSON-like data format widely used in data exchange in web/native applications. It is slightly more compact than UBJSON, but is not directly readable compared to UBJSON. We envision that both JSON and its binary counterparts will play important rules not only for light-weight data storage, but also for storage and interchange of scientific data. It has both the flexibility and generality as in other general-purpose file specifications, such as [http://www.hdfgroup.org/HDF5/whatishdf5.html HDF5] but has significantly reduced complexity and excellent readability. Towards this goal, we have developed the JData Specification (http://github.com/fangq/jdata) to standardize serializations of complex scientific data structures, such as N-D arrays, sparse/complex-valued arrays, trees, maps, tables and graphs using JSON/binary JSON constructs. The text and binary formatted JData files are syntactically compatible with JSON/UBJSON formats, and can be readily parsed using existing JSON and UBJSON parsers. JSONLab is not just a parser and writer of JSON/UBJSON data files, but one that systematically converts complex scientific data structures into human-readable and universally supported JSON forms using the standardized JData data annotations. ------------------------------------------------------------------------------- II. Installation The installation of JSONLab is no different from installing any other MATLAB toolbox. You only need to download/unzip the JSONLab package to a folder, and add the folder's path to MATLAB/Octave's path list by using the following command: addpath('/path/to/jsonlab'); If you want to add this path permanently, you need to type `pathtool`, browse to the root folder of JSONLab and add to the list, then click "Save". Then, run `rehash` in MATLAB, and type "which savejson", if you see an output, that means JSONLab is installed for MATLAB/Octave. If you use MATLAB in a shared environment such as a Linux server, the best way to add path is to type mkdir ~/matlab/ nano ~/matlab/startup.m and type `addpath('/path/to/jsonlab')` in this file, save and exit the editor. MATLAB will execute this file every time it starts. For Octave, the file you need to edit is `~/.octaverc` , where `"~"` represents your home directory. To use the data compression features, please download the ZMat toolbox from https://github.com/fangq/zmat/releases/latest and follow the instruction to install ZMat first. The ZMat toolbox is required when compression is used on MATLAB running in the `-nojvm` mode or GNU Octave, or 'lzma/lzip/lz4/lz4hc' compression methods are specified. ZMat can also compress large arrays that MATLAB's Java-based compression API does not support. === Install JSONLab on Fedora 24 or later === JSONLab has been available as an official Fedora package since 2015. You may install it directly using the below command sudo dnf install octave-jsonlab To enable data compression/decompression, you need to install `octave-zmat` using sudo dnf install octave-zmat === Install JSONLab on Arch Linux === JSONLab is also available on Arch Linux. You may install it using the below command sudo pikaur -S jsonlab ------------------------------------------------------------------------------- III.Using JSONLab JSONLab provides a pair of functions, `loadjson` -- a JSON parser, and `savejson` -- a MATLAB-to-JSON encoder, to read/write the text-based JSON; and two equivallent pairs -- `loadubjson/saveubjson` for binary JSON and `loadmsgpack/savemsgpack` for MessagePack. The `load*` functions for the 3 supported data formats share almost the same input parameter format; similarly for the 3 `save*` functions (`savejson/saveubjson/savemsgpack`). These encoders and decoders are capable of processing/sharing almost all data structures supported by MATLAB, thanks to `jdataencode/jdatadecode` - a pair of in-memory data converters translating complex data structures to the easy-to-serialized forms according to the JData specifications. The detailed help information can be found in the `Contents.m` file. In the below section, we provide a few examples on how to us each of the core functions for encoding/decoding JSON/UBJSON/MessagePack data. === savejson.m === jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... 'MeshElem',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... 'MeshSurf',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... 'MeshCreator','FangQ','MeshTitle','T6 Cube',... 'SpecialData',[nan, inf, -inf]); savejson(jsonmesh) savejson('jmesh',jsonmesh) savejson('',jsonmesh,'compact',1) savejson('jmesh',jsonmesh,'outputfile.json') savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g','FileName','outputfile2.json') savejson('cpxrand',eye(5)+1i*magic(5)) savejson('ziparray',eye(10),'Compression','zlib','CompressArraySize',1) savejson('',jsonmesh,'ArrayToStruct',1) savejson('',eye(10),'UseArrayShape',1) === loadjson.m === loadjson('{}') dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}') dat=loadjson(['examples' filesep 'example1.json']) dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',0) === savebj.m (saveubjson.m as an alias) === a={single(rand(2)), struct('va',1,'vb','string'), 1+2i}; savebj(a) savebj('rootname',a,'testdata.ubj') savebj('zeros',zeros(100),'Compression','gzip') === loadbj.m (loadubjson.m as an alias) === obj=struct('string','value','array',single([1 2 3]),'empty',[],'magic',uint8(magic(5))); ubjdata=savebj('obj',obj); dat=loadbj(ubjdata) class(dat.obj.array) isequaln(obj,dat.obj) dat=loadbj(savebj('',eye(10),'Compression','zlib','CompressArraySize',1)) === jdataencode.m === jd=jdataencode(struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5))) savejson('',jd) === jdatadecode.m === rawdata=struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5)); jd=jdataencode(rawdata) newjd=jdatadecode(jd) isequaln(newjd,rawdata) === examples === Under the `examples` folder, you can find several scripts to demonstrate the basic utilities of JSONLab. Running the `demo_jsonlab_basic.m` script, you will see the conversions from MATLAB data structure to JSON text and backward. In `jsonlab_selftest.m`, we load complex JSON files downloaded from the Internet and validate the loadjson/savejson functions for regression testing purposes. Similarly, a `demo_ubjson_basic.m` script is provided to test the `saveubjson` and `loadubjson` functions for various matlab data structures, and ``demo_msgpack_basic.m`` is for testing ``savemsgpack`` and ``loadmsgpack``. Please run these examples and understand how JSONLab works before you use it to process your data. == unit testing === Under the `test` folder, you can find a script to test individual data types and inputs using various encoders and decoders. This unit testing script also serves as a '''specification validator''' to the JSONLab functions and ensure that the outputs are compliant to the underlying specifications. ------------------------------------------------------------------------------- IV.Using `jsave/jload` to share workspace Starting from JSONLab v2.0, we provide a pair of functions, `jsave/jload` to store and retrieve variables from the current workspace, similar to the `save/load` functions in MATLAB and Octave. The files that `jsave/jload` reads/writes is by default a binary JData file with a suffix `.jamm`. The file size is comparable (can be smaller if use `lzma` compression) to `.mat` files. This feature is currently experimental. The main benefits of using .jamm file to share matlab variables include * a `.jamm` file can be 50% smaller than a `.mat` file when using \ `jsave(..., "compression","lzma")`; the only drawback is longer saving time. * a `.jamm` file can be readily read/opened among many programming environments, including \ Python, JavaScript, Go, Java etc, where `.mat` file support is not generally available. \ Parsers of `.jamm` is largely compatible with UBJSON's parsers available at \ http://ubjson.org/?page_id=48 * a `.jamm` file is quasi-human-readable, one can see the internal data fields \ even in a command line, for example using `strings -n 2 file.jamm | astyle`, \ making the binary data easy to be understood, shared and reused. * `jsave/jload` can also use MessagePack and JSON formats as the underlying \ data storage format, addressing needs from diverse applications. \ MessagePack parsers are readily available at https://msgpack.org/ === jsave.m === jsave % save the current workspace to jamdata.jamm jsave mydata.jamm jsave('mydata.jamm','vars',{'var1','var2'}) jsave('mydata.jamm','compression','lzma') jsave('mydata.json','compression','gzip') === jload.m === jload % load variables from jamdata.jamm to the current workspace jload mydata.jamm % load variables from mydata.jamm vars=jload('mydata.jamm','vars',{'var1','var2'}) % return vars.var1, vars.var2 jload('mydata.jamm','simplifycell',0) jload('mydata.json') ------------------------------------------------------------------------------- V. Sharing JSONLab created data files in Python Despite the use of portable data annotation defined by the JData Specification, the output JSON files created by JSONLab are 100% JSON compatible (with the exception that long strings may be broken into multiple lines for better readability). Therefore, JSONLab-created JSON files (`.json, .jnii, .jnirs` etc) can be readily read and written by nearly all existing JSON parsers, including the built-in `json` module parser in Python. However, we strongly recommend one to use a lightweight `jdata` module, developed by the same author, to perform the extra JData encoding and decoding and convert JSON data directly to convenient Python/Numpy data structures. The `jdata` module can also directly read/write UBJSON/Binary JData outputs from JSONLab (`.bjd, .ubj, .bnii, .bnirs, .jamm` etc). Using binary JData files are exptected to produce much smaller file sizes and faster parsing, while maintainining excellent portability and generality. In short, to conveniently read/write data files created by JSONLab into Python, whether they are JSON based or binary JData/UBJSON based, one just need to download the below two light-weight python modules: * **jdata**: PyPi: https://pypi.org/project/jdata/ ; Github: https://github.com/fangq/pyjdata * **bjdata** PyPi: https://pypi.org/project/bjdata/ ; Github: https://github.com/fangq/pybj To install these modules on Python 2.x, please first check if your system has `pip` and `numpy`, if not, please install it by running (using Ubuntu/Debian as example) sudo apt-get install python-pip python3-pip python-numpy python3-numpy After the installation is done, one can then install the ``jdata`` and ``bjdata`` modules by pip install jdata --user pip install bjdata --user To install these modules for Python 3.x, please replace ``pip`` by ``pip3``. If one prefers to install these modules globally for all users, simply execute the above commands using `sudo` and remove the `--user` flag. The above modules require built-in Python modules `json` and NumPy (`numpy`). Once the necessary modules are installed, one can type `python` (or `python3`), and run import jdata as jd import numpy as np from collections import OrderedDict data1=jd.loadt('myfile.json',object_pairs_hook=OrderedDict); data2=jd.loadb('myfile.ubj',object_pairs_hook=OrderedDict); data3=jd.loadb('myfile.jamm',object_pairs_hook=OrderedDict); where `jd.loadt()` function loads a text-based JSON file, performs JData decoding and converts the enclosed data into Python `dict`, `list` and `numpy` objects. Similarly, `jd.loadb()` function loads a binary JData/UBJSON file and performs similar conversions. One can directly call `jd.load()` to open JSONLab (and derived toolboxes such as '''jnifti''': https://github.com/fangq/jnifti or '''jsnirfy''': https://github.com/fangq/jsnirfy) generated files based on their respective file suffix. Similarly, the `jd.savet()`, `jd.saveb()` and `jd.save` functions can revert the direction and convert a Python/Numpy object into JData encoded data structure and store as text-, binary- and suffix-determined output files, respectively. ------------------------------------------------------------------------------- VI. Known Issues and TODOs JSONLab has several known limitations. We are striving to make it more general and robust. Hopefully in a few future releases, the limitations become less. Here are the known issues: # 3D or higher dimensional cell/struct-arrays will be converted to 2D arrays; # When processing names containing multi-byte characters, Octave and MATLAB \ can give different field-names; you can use feature('DefaultCharacterSet','latin1') \ in MATLAB to get consistant results # `savejson` can only export the properties from MATLAB classes, but not the methods # `saveubjson` converts a logical array into a uint8 ([U]) array # a special N-D array format, as defined in the JData specification, is implemented in \ `saveubjson`. You may use `saveubjson(...,'NestArray',1)` to create UBJSON \ Draft-12 compliant files # loadubjson can not parse all UBJSON Specification (Draft 9) compliant \ files, however, it can parse all UBJSON files produced by `saveubjson`. ------------------------------------------------------------------------------- VII. Contribution and feedback JSONLab is an open-source project. This means you can not only use it and modify it as you wish, but also you can contribute your changes back to JSONLab so that everyone else can enjoy the improvement. For anyone who want to contribute, please download JSONLab source code from its source code repositories by using the following command: git clone https://github.com/fangq/jsonlab.git jsonlab or browsing the github site at https://github.com/fangq/jsonlab Please report any bugs or issues to the below URL: https://github.com/fangq/jsonlab/issues Sometimes, you may find it is necessary to modify JSONLab to achieve your goals, or attempt to modify JSONLab functions to fix a bug that you have encountered. If you are happy with your changes and willing to share those changes to the upstream author, you are recommended to create a pull-request on github. To create a pull-request, you first need to "fork" jsonlab on Github by clicking on the "fork" button on top-right of jsonlab's github page. Once you forked jsonlab to your own directory, you should then implement the changes in your own fork. After thoroughly testing it and you are confident the modification is complete and effective, you can then click on the "New pull request" button, and on the left, select fangq/jsonlab as the "base". Then type in the description of the changes. You are responsible to format the code updates using the same convention (tab-width: 8, indentation: 4 spaces) as the upstream code. We appreciate any suggestions and feedbacks from you. Please use the following mailing list to report any questions you may have regarding JSONLab: https://github.com/fangq/jsonlab/issues (Subscription to the mailing list is needed in order to post messages). ------------------------------------------------------------------------------- VIII. Acknowledgement This toolbox contains modified functions from the below toolboxes: === loadjson.m === The `loadjson.m` function was significantly modified from the earlier parsers (BSD 3-clause licensed) written by the below authors * Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713 created on 2009/11/02 * Franois Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393 created on 2009/03/22 * Joel Feenstra: http://www.mathworks.com/matlabcentral/fileexchange/20565 created on 2008/07/03 === loadmsgpack.m === * Author: Bastian Bechtold * URL: https://github.com/bastibe/matlab-msgpack/blob/master/parsemsgpack.m * License: BSD 3-clause license Copyright (c) 2014,2016 Bastian Bechtold All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. == zlibdecode.m, zlibencode.m, gzipencode.m, gzipdecode.m, base64encode.m, base64decode.m == * Author: Kota Yamaguchi * URL:https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities * License: BSD License, see below Copyright (c) 2012, Kota Yamaguchi All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. jsonlab-2.0/base64decode.m000066400000000000000000000025471367147361400154350ustar00rootroot00000000000000function output = base64decode(varargin) % % output = base64decode(input) % % Decoding a Base64-encoded byte-stream to recover the original data % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % Modified by: Qianqian Fang (q.fang neu.edu) % % input: % input: a base64-encoded string % % output: % output: the decoded binary byte-stream as a uint8 vector % % examples: % bytes=base64encode('Test JSONLab'); % orig=char(base64decode(bytes)) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) output=zmat(varargin{1},0,'base64'); return; elseif(isoctavemesh) error('You must install the ZMat toolbox (http://github.com/fangq/zmat) to use this function in Octave'); end error(javachk('jvm')); if(ischar(varargin{1})) varargin{1}=uint8(varargin{1}); end input=typecast(varargin{1}(:)','uint8'); output = typecast(org.apache.commons.codec.binary.Base64.decodeBase64(input), 'uint8')'; jsonlab-2.0/base64encode.m000066400000000000000000000026521367147361400154440ustar00rootroot00000000000000function varargout = base64encode(varargin) % % output = base64encode(input) % % Encoding a binary vector or array using Base64 % % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % Modified by: Qianqian Fang (q.fang neu.edu) % % input: % input: a base64-encoded string % % output: % output: the decoded binary byte-stream as a uint8 vector % % examples: % bytes=base64encode('Test JSONLab'); % orig=char(base64decode(bytes)) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) [varargout{1:nargout}]=zmat(varargin{1}, 1,'base64',varargin{2:end}); return; end if(ischar(varargin{1})) varargin{1}=uint8(varargin{1}); end input=typecast(varargin{1}(:)','uint8'); if(isoctavemesh) varargout{1} = base64_encode(uint8(input)); return; end error(javachk('jvm')); if ischar(input) input = uint8(input); end varargout{1} = char(org.apache.commons.codec.binary.Base64.encodeBase64Chunked(input))'; varargout{1} = regexprep(varargout{1} ,'\r',''); jsonlab-2.0/decodevarname.m000066400000000000000000000045601367147361400157770ustar00rootroot00000000000000function newname = decodevarname(name,varargin) % % newname = decodevarname(name) % % Decode a hex-encoded variable name (from encodevarname) and restore % its original form % % This function is sensitive to the default charset % settings in MATLAB, please call feature('DefaultCharacterSet','utf8') % to set the encoding to UTF-8 before calling this function. % % author: Qianqian Fang (q.fang neu.edu) % % input: % name: a string output from encodevarname, which converts the leading non-ascii % letter into "x0xHH_" and non-ascii letters into "_0xHH_" % format, where hex key HH stores the ascii (or Unicode) value % of the character. % % output: % newname: the restored original string % % example: % decodevarname('x0x5F_a') % returns _a % decodevarname('a_') % returns a_ as it is a valid variable name % decodevarname('x0xE58F98__0xE9878F_') % returns '变量' % % this file is part of EasyH5 Toolbox: https://github.com/fangq/easyh5 % % License: GPLv3 or 3-clause BSD license, see https://github.com/fangq/easyh5 for details % newname=name; isunpack=1; if(nargin==2 && ~isstruct(varargin{1})) isunpack=varargin{1}; elseif(nargin>1) isunpack=jsonopt('UnpackHex',1,varargin{:}); end if(isunpack) if(isempty(regexp(name,'0x([0-9a-fA-F]+)_','once'))) return end if(exist('native2unicode','builtin')) h2u=@hex2unicode; newname=regexprep(name,'(^x|_){1}0x([0-9a-fA-F]+)_','${h2u($2)}'); else pos=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','start'); pend=regexp(name,'(^x|_){1}0x([0-9a-fA-F]+)_','end'); if(isempty(pos)) return; end str0=name; pos0=[0 pend(:)' length(name)]; newname=''; for i=1:length(pos) newname=[newname str0(pos0(i)+1:pos(i)-1) char(hex2dec(str0(pos(i)+3:pend(i)-1)))]; end if(pos(end)~=length(name)) newname=[newname str0(pos0(end-1)+1:pos0(end))]; end end end %-------------------------------------------------------------------------- function str=hex2unicode(hexstr) val=hex2dec(hexstr); id=histc(val,[0 2^8 2^16 2^32 2^64]); type={'uint8','uint16','uint32','uint64'}; bytes=typecast(cast(val,type{id~=0}),'uint8'); str=native2unicode(fliplr(bytes(:,1:find(bytes,1,'last')))); jsonlab-2.0/encodevarname.m000066400000000000000000000043011367147361400160020ustar00rootroot00000000000000function str = encodevarname(str,varargin) % % newname = encodevarname(name) % % Encode an invalid variable name using a hex-format for bi-directional % conversions. % This function is sensitive to the default charset % settings in MATLAB, please call feature('DefaultCharacterSet','utf8') % to set the encoding to UTF-8 before calling this function. % % author: Qianqian Fang (q.fang neu.edu) % % input: % name: a string, can be either a valid or invalid variable name % % output: % newname: a valid variable name by converting the leading non-ascii % letter into "x0xHH_" and non-ascii letters into "_0xHH_" % format, where HH is the ascii (or Unicode) value of the % character. % % if the encoded variable name CAN NOT be longer than 63, i.e. % the maximum variable name specified by namelengthmax, and % one uses the output of this function as a struct or variable % name, the name will be trucated at 63. Please consider using % the name as a containers.Map key, which does not have such % limit. % % example: % encodevarname('_a') % returns x0x5F_a % encodevarname('a_') % returns a_ as it is a valid variable name % encodevarname('变量') % returns 'x0xE58F98__0xE9878F_' % % this file is part of EasyH5 Toolbox: https://github.com/fangq/easyh5 % % License: GPLv3 or 3-clause BSD license, see https://github.com/fangq/easyh5 for details % if(~isvarname(str(1))) str=sprintf('x0x%X_%s',char(str(1))+0,str(2:end)); end if(isvarname(str)) return; end if(exist('unicode2native','builtin')) str=regexprep(str,'([^0-9A-Za-z_])','_0x${sprintf(''%X'',unicode2native($1))}_'); else cpos=regexp(str,'[^0-9A-Za-z_]'); if(isempty(cpos)) return; end str0=str; pos0=[0 cpos(:)' length(str)]; str=''; for i=1:length(cpos) str=[str str0(pos0(i)+1:cpos(i)-1) sprintf('_0x%X_',str0(cpos(i))+0)]; end if(cpos(end)~=length(str)) str=[str str0(pos0(end-1)+1:pos0(end))]; end end end jsonlab-2.0/examples/000077500000000000000000000000001367147361400146355ustar00rootroot00000000000000jsonlab-2.0/examples/demo_jsonlab_basic.m000066400000000000000000000341121367147361400206110ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Demonstration of Basic Utilities of JSONlab %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rngstate = rand ('state'); randseed=hex2dec('623F9A9E'); clear data2json json2data if(exist('isequaln')==0) isequaln=@isequal; end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple scalar value \n') fprintf(1,'%%=================================================\n\n') data2json=pi savejson('',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty array \n') fprintf(1,'%%=================================================\n\n') data2json=[] savejson('',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an ampty string \n') fprintf(1,'%%=================================================\n\n') data2json='' savejson('emptystr',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple row vector \n') fprintf(1,'%%=================================================\n\n') data2json=1:3 savejson('',data2json) json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple column vector \n') fprintf(1,'%%=================================================\n\n') data2json=(1:3)' savejson('',data2json) json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a string array \n') fprintf(1,'%%=================================================\n\n') data2json=['AC';'EG'] savejson('',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a string with escape symbols \n') fprintf(1,'%%=================================================\n\n') data2json=sprintf('AB\tCD\none"two') savejson('str',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a mix-typed cell \n') fprintf(1,'%%=================================================\n\n') data2json={'a',true,[2;3]} savejson('',data2json) json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in nested array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savejson('',data2json,'NestArray',1) json2data=loadjson(ans,'fastarrayparser',0) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in annotated array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savejson('',data2json,'NestArray',0) json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 4-D array in annotated array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*3*2),[2,4,3,2]); savejson('',data2json,'NestArray',0) % nestarray for 4-D or above is not working json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in nested array form (JSONLab 1.9)\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savejson('',data2json,'NestArray',1,'FormatVersion',1.8) json2data=loadjson(ans,'FormatVersion',1.8) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in annotated array form (JSONLab 1.9 or earlier)\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savejson('',data2json,'NestArray',0,'FormatVersion',1.8) json2data=loadjson(ans,'FormatVersion',1.8) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex number\n') fprintf(1,'%%=================================================\n\n') data2json=1+2i savejson('',data2json) json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex matrix\n') fprintf(1,'%%=================================================\n\n') data2json=magic(6); data2json=data2json(:,1:3)+data2json(:,4:6)*1i savejson('',data2json) json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% MATLAB special constants\n') fprintf(1,'%%=================================================\n\n') data2json=[NaN Inf -Inf] savejson('specials',data2json) json2data=loadjson(ans) if(~isequaln(json2data.specials,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a real sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sprand(10,10,0.1) savejson('sparse',data2json,'FloatFormat','%.18g') json2data=loadjson(ans) if(~isequaln(json2data.sparse,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sprand(10,10,0.1); data2json=data2json-data2json*1i savejson('complex_sparse',data2json,'FloatFormat','%.18g') json2data=loadjson(ans) if(~isequaln(json2data.complex_sparse,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an all-zero sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sparse(2,3); savejson('all_zero_sparse',data2json) json2data=loadjson(ans) if(~isequaln(json2data.all_zero_sparse,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([]); savejson('empty_sparse',data2json) json2data=loadjson(ans) if(~isequaln(json2data.empty_sparse,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty 0-by-0 real matrix\n') fprintf(1,'%%=================================================\n\n') data2json=[]; savejson('empty_0by0_real',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty 0-by-3 real matrix\n') fprintf(1,'%%=================================================\n\n') data2json=zeros(0,3); savejson('empty_0by3_real',data2json) json2data=loadjson(ans) if(~isequaln(json2data.empty_0by3_real,data2json)) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse real column vector\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([0,3,0,1,4]'); savejson('sparse_column_vector',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse complex column vector\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-1i*data2json; savejson('complex_sparse_column_vector',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse real row vector\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([0,3,0,1,4]); savejson('sparse_row_vector',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse complex row vector\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-1i*data2json; savejson('complex_sparse_row_vector',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a structure\n') fprintf(1,'%%=================================================\n\n') data2json=struct('name','Think Different','year',1997,'magic',magic(3),... 'misfits',[Inf,NaN],'embedded',struct('left',true,'right',false)) savejson('astruct',data2json,struct('ParseLogical',1)) json2data=loadjson(ans) class(json2data.astruct.embedded.left) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a structure array\n') fprintf(1,'%%=================================================\n\n') data2json=struct('name','Nexus Prime','rank',9); data2json(2)=struct('name','Sentinel Prime','rank',9); data2json(3)=struct('name','Optimus Prime','rank',9); savejson('Supreme Commander',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a cell array\n') fprintf(1,'%%=================================================\n\n') data2json=cell(3,1); data2json{1}=struct('buzz',1.1,'rex',1.2,'bo',1.3,'hamm',2.0,'slink',2.1,'potato',2.2,... 'woody',3.0,'sarge',3.1,'etch',4.0,'lenny',5.0,'squeeze',6.0,'wheezy',7.0); data2json{2}=struct('Ubuntu',['Kubuntu';'Xubuntu';'Lubuntu']); data2json{3}=[10.04,10.10,11.04,11.10] savejson('debian',data2json,struct('FloatFormat','%.2f')) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% invalid field-name handling\n') fprintf(1,'%%=================================================\n\n') json2data=loadjson('{"ValidName":1, "_InvalidName":2, ":Field:":3, "项目":"绝密"}') fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a function handle\n') fprintf(1,'%%=================================================\n\n') data2json=@(x) x+1 savejson('handle',data2json) json2data=loadjson(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2D cell array\n') fprintf(1,'%%=================================================\n\n') data2json={{1,{2,3}},{4,5},{6};{7},{8,9},{10}}; savejson('data2json',data2json) json2data=loadjson(ans) % only savejson works for cell arrays, loadjson has issues fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2D struct array\n') fprintf(1,'%%=================================================\n\n') data2json=repmat(struct('idx',0,'data','structs'),[2,3]) for i=1:6 data2json(i).idx=i; end savejson('data2json',data2json) json2data=loadjson(ans) if(exist('datetime')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% datetime object \n') fprintf(1,'%%=================================================\n\n') data2json=datetime({'8 April 2015','9 May 2015'}, 'InputFormat','d MMMM yyyy') savejson('',data2json) json2data=loadjson(ans) end if(exist('containers.Map')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a container.Maps object \n') fprintf(1,'%%=================================================\n\n') data2json=containers.Map({'Andy','William','Om'},{21,21,22}) savejson('',data2json) json2data=loadjson(ans) end if(exist('istable')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a table object \n') fprintf(1,'%%=================================================\n\n') Names={'Andy','William','Om'}'; Age=[21,21,22]'; data2json=table(Names,Age) savejson('table',table(Names,Age)) json2data=loadjson(ans) end if(exist('bandwidth')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% use _ArrayShape_ \n') fprintf(1,'%%=================================================\n\n') lband=2; uband=3; data2json=spdiags(true(8,lband+uband+1),-uband:lband,5,8); data2json=full(double(data2json)); data2json(data2json~=0)=find(data2json) savejson('',data2json,'usearrayshape',1) json2data=loadjson(ans,'fullarrayshape',1) savejson('',tril(data2json),'usearrayshape',1) json2data=loadjson(ans,'fullarrayshape',1) savejson('',triu(data2json+1i*data2json),'usearrayshape',1) json2data=loadjson(ans,'fullarrayshape',1) savejson('',tril(triu(int8(data2json))),'usearrayshape',1) json2data=loadjson(ans,'fullarrayshape',1) savejson('',data2json(:,1:5)+data2json(:,1:5)','usearrayshape',1) json2data=loadjson(ans,'fullarrayshape',1) end try val=zlibencode('test'); fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2-D array in compressed array format\n') fprintf(1,'%%=================================================\n\n') data2json=eye(10); data2json(20,1)=1; savejson('',data2json,'Compression','zlib','CompressArraySize',0) % nestarray for 4-D or above is not working json2data=loadjson(ans) if(~isequaln(json2data,data2json)) warning('conversion does not preserve original data'); end catch end rand ('state',rngstate); jsonlab-2.0/examples/demo_msgpack_basic.m000066400000000000000000000305541367147361400206140ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Demonstration of Basic Utilities of JSONlab %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rngstate = rand ('state'); randseed=hex2dec('623F9A9E'); clear data2json json2data fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple scalar value \n') fprintf(1,'%%=================================================\n\n') data2json=pi savemsgpack('',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty array \n') fprintf(1,'%%=================================================\n\n') data2json=[] savemsgpack('empty',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an ampty string \n') fprintf(1,'%%=================================================\n\n') data2json='' savemsgpack('emptystr',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple row vector \n') fprintf(1,'%%=================================================\n\n') data2json=1:3 savemsgpack('',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple column vector \n') fprintf(1,'%%=================================================\n\n') data2json=(1:3)' savemsgpack('',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a string array \n') fprintf(1,'%%=================================================\n\n') data2json=['AC';'EG'] savemsgpack('',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a string with escape symbols \n') fprintf(1,'%%=================================================\n\n') data2json=sprintf('AB\tCD\none"two') savemsgpack('str',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a mix-typed cell \n') fprintf(1,'%%=================================================\n\n') data2json={'a',true,[2;3]} savemsgpack('',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in nested array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savemsgpack('',data2json,'NestArray',1) json2data=loadmsgpack(ans) if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in annotated array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savemsgpack('',data2json,'NestArray',0) json2data=loadmsgpack(ans) if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 4-D array in annotated array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*3*2),[2,4,3,2]); savemsgpack('',data2json,'NestArray',0) % nestarray for 4-D or above is not working json2data=loadmsgpack(ans) if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex number\n') fprintf(1,'%%=================================================\n\n') data2json=1+2i savemsgpack('',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex matrix\n') fprintf(1,'%%=================================================\n\n') data2json=magic(6); data2json=data2json(:,1:3)+data2json(:,4:6)*1i savemsgpack('',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% MATLAB special constants\n') fprintf(1,'%%=================================================\n\n') data2json=[NaN Inf -Inf] savemsgpack('specials',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a real sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sprand(10,10,0.1) savemsgpack('sparse',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-data2json*1i savemsgpack('complex_sparse',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an all-zero sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sparse(2,3); savemsgpack('all_zero_sparse',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([]); savemsgpack('empty_sparse',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty 0-by-0 real matrix\n') fprintf(1,'%%=================================================\n\n') data2json=[]; savemsgpack('empty_0by0_real',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty 0-by-3 real matrix\n') fprintf(1,'%%=================================================\n\n') data2json=zeros(0,3); savemsgpack('empty_0by3_real',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse real column vector\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([0,3,0,1,4]'); savemsgpack('sparse_column_vector',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse complex column vector\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-1i*data2json; savemsgpack('complex_sparse_column_vector',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse real row vector\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([0,3,0,1,4]); savemsgpack('sparse_row_vector',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse complex row vector\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-1i*data2json; savemsgpack('complex_sparse_row_vector',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a structure\n') fprintf(1,'%%=================================================\n\n') data2json=struct('name','Think Different','year',1997,'magic',magic(3),... 'misfits',[Inf,NaN],'embedded',struct('left',true,'right',false)) savemsgpack('astruct',data2json,struct('ParseLogical',1)) json2data=loadmsgpack(ans) class(json2data.astruct.embedded.left) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a structure array\n') fprintf(1,'%%=================================================\n\n') data2json=struct('name','Nexus Prime','rank',9); data2json(2)=struct('name','Sentinel Prime','rank',9); data2json(3)=struct('name','Optimus Prime','rank',9); savemsgpack('Supreme Commander',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a cell array\n') fprintf(1,'%%=================================================\n\n') data2json=cell(3,1); data2json{1}=struct('buzz',1.1,'rex',1.2,'bo',1.3,'hamm',2.0,'slink',2.1,'potato',2.2,... 'woody',3.0,'sarge',3.1,'etch',4.0,'lenny',5.0,'squeeze',6.0,'wheezy',7.0); data2json{2}=struct('Ubuntu',['Kubuntu';'Xubuntu';'Lubuntu']); data2json{3}=[10.04,10.10,11.04,11.10] savemsgpack('debian',data2json,struct('FloatFormat','%.2f')) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% invalid field-name handling\n') fprintf(1,'%%=================================================\n\n') json2data=loadmsgpack(savemsgpack('',loadjson('{"ValidName":1, "_InvalidName":2, ":Field:":3, "项目":"绝密"}'))) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a function handle\n') fprintf(1,'%%=================================================\n\n') data2json=@(x) x+1 savemsgpack('handle',data2json) json2data=loadmsgpack(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2D cell array\n') fprintf(1,'%%=================================================\n\n') data2json={{1,{2,3}},{4,5},{6};{7},{8,9},{10}}; savemsgpack('data2json',data2json) json2data=loadmsgpack(ans) % only savemsgpack works for cell arrays, loadmsgpack has issues fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2D struct array\n') fprintf(1,'%%=================================================\n\n') data2json=repmat(struct('idx',0,'data','structs'),[2,3]) for i=1:6 data2json(i).idx=i; end savemsgpack('data2json',data2json) json2data=loadmsgpack(ans) if(exist('datetime')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% datetime object \n') fprintf(1,'%%=================================================\n\n') data2json=datetime({'8 April 2015','9 May 2015'}, 'InputFormat','d MMMM yyyy') savemsgpack('',data2json) json2data=loadmsgpack(ans) end if(exist('containers.Map')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a container.Maps object \n') fprintf(1,'%%=================================================\n\n') data2json=containers.Map({'Andy','William','Om'},{21,21,22}) savemsgpack('',data2json) json2data=loadmsgpack(ans) end if(exist('istable')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a table object \n') fprintf(1,'%%=================================================\n\n') Names={'Andy','William','Om'}'; Age=[21,21,22]'; data2json=table(Names,Age) savemsgpack('table',table(Names,Age)) json2data=loadmsgpack(ans) end if(exist('bandwidth')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% use _ArrayShape_ \n') fprintf(1,'%%=================================================\n\n') lband=2; uband=3; data2json=spdiags(true(8,lband+uband+1),-uband:lband,5,8); data2json=full(double(data2json)); data2json(data2json~=0)=find(data2json) savemsgpack('',data2json,'usearrayshape',1) json2data=loadmsgpack(ans,'fullarrayshape',1) savemsgpack('',tril(data2json),'usearrayshape',1) json2data=loadmsgpack(ans,'fullarrayshape',1) savemsgpack('',triu(data2json+1i*data2json),'usearrayshape',1) json2data=loadmsgpack(ans,'fullarrayshape',1) savemsgpack('',tril(triu(int8(data2json))),'usearrayshape',1) json2data=loadmsgpack(ans,'fullarrayshape',1) savemsgpack('',data2json(:,1:5)+data2json(:,1:5)','usearrayshape',1) json2data=loadmsgpack(ans,'fullarrayshape',1) end try val=zlibencode('test'); fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2-D array in compressed array format\n') fprintf(1,'%%=================================================\n\n') data2json=eye(10); data2json(20,1)=1; savemsgpack('',data2json,'Compression','zlib','CompressArraySize',0) % nestarray for 4-D or above is not working json2data=loadmsgpack(ans) if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) warning('conversion does not preserve original data'); end catch end rand ('state',rngstate); jsonlab-2.0/examples/demo_ubjson_basic.m000066400000000000000000000310741367147361400204650ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Demonstration of Basic Utilities of JSONlab %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% rngstate = rand ('state'); randseed=hex2dec('623F9A9E'); clear data2json json2data fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple scalar value \n') fprintf(1,'%%=================================================\n\n') data2json=pi savebj('',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty array \n') fprintf(1,'%%=================================================\n\n') data2json=[] savebj('empty',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an ampty string \n') fprintf(1,'%%=================================================\n\n') data2json='' savebj('emptystr',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple row vector \n') fprintf(1,'%%=================================================\n\n') data2json=1:3 savebj('',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a simple column vector \n') fprintf(1,'%%=================================================\n\n') data2json=(1:3)' savebj('',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a string array \n') fprintf(1,'%%=================================================\n\n') data2json=['AC';'EG'] savebj('',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a string with escape symbols \n') fprintf(1,'%%=================================================\n\n') data2json=sprintf('AB\tCD\none"two') savebj('str',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a mix-typed cell \n') fprintf(1,'%%=================================================\n\n') data2json={'a',true,[2;3]} savebj('',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in nested array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savebj('',data2json,'NestArray',1) json2data=loadbj(ans) % if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) % warning('conversion does not preserve original data'); % end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in annotated array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savebj('',data2json,'NestArray',0) json2data=loadbj(ans) if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 4-D array in annotated array form\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*3*2),[2,4,3,2]); savebj('',data2json,'NestArray',0) % nestarray for 4-D or above is not working json2data=loadbj(ans) if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) warning('conversion does not preserve original data'); end fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in nested array form (JSONLab 1.9)\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savebj('',data2json,'NestArray',1,'FormatVersion',1.8) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 3-D array in annotated array form (JSONLab 1.9 or earlier)\n') fprintf(1,'%%=================================================\n\n') data2json=reshape(1:(2*4*6),[2,4,6]); savebj('',data2json,'NestArray',0,'FormatVersion',1.8) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex number\n') fprintf(1,'%%=================================================\n\n') data2json=1+2i savebj('',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex matrix\n') fprintf(1,'%%=================================================\n\n') data2json=magic(6); data2json=data2json(:,1:3)+data2json(:,4:6)*1i savebj('',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% MATLAB special constants\n') fprintf(1,'%%=================================================\n\n') data2json=[NaN Inf -Inf] savebj('specials',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a real sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sprand(10,10,0.1) savebj('sparse',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a complex sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-data2json*1i savebj('complex_sparse',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an all-zero sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sparse(2,3); savebj('all_zero_sparse',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty sparse matrix\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([]); savebj('empty_sparse',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty 0-by-0 real matrix\n') fprintf(1,'%%=================================================\n\n') data2json=[]; savebj('empty_0by0_real',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% an empty 0-by-3 real matrix\n') fprintf(1,'%%=================================================\n\n') data2json=zeros(0,3); savebj('empty_0by3_real',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse real column vector\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([0,3,0,1,4]'); savebj('sparse_column_vector',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse complex column vector\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-1i*data2json; savebj('complex_sparse_column_vector',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse real row vector\n') fprintf(1,'%%=================================================\n\n') data2json=sparse([0,3,0,1,4]); savebj('sparse_row_vector',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a sparse complex row vector\n') fprintf(1,'%%=================================================\n\n') data2json=data2json-1i*data2json; savebj('complex_sparse_row_vector',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a structure\n') fprintf(1,'%%=================================================\n\n') data2json=struct('name','Think Different','year',1997,'magic',magic(3),... 'misfits',[Inf,NaN],'embedded',struct('left',true,'right',false)) savebj('astruct',data2json,struct('ParseLogical',1)) json2data=loadbj(ans) class(json2data.astruct.embedded.left) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a structure array\n') fprintf(1,'%%=================================================\n\n') data2json=struct('name','Nexus Prime','rank',9); data2json(2)=struct('name','Sentinel Prime','rank',9); data2json(3)=struct('name','Optimus Prime','rank',9); savebj('Supreme Commander',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a cell array\n') fprintf(1,'%%=================================================\n\n') data2json=cell(3,1); data2json{1}=struct('buzz',1.1,'rex',1.2,'bo',1.3,'hamm',2.0,'slink',2.1,'potato',2.2,... 'woody',3.0,'sarge',3.1,'etch',4.0,'lenny',5.0,'squeeze',6.0,'wheezy',7.0); data2json{2}=struct('Ubuntu',['Kubuntu';'Xubuntu';'Lubuntu']); data2json{3}=[10.04,10.10,11.04,11.10] savebj('debian',data2json,struct('FloatFormat','%.2f')) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% invalid field-name handling\n') fprintf(1,'%%=================================================\n\n') json2data=loadbj(savebj('',loadjson('{"ValidName":1, "_InvalidName":2, ":Field:":3, "项目":"绝密"}'))) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a function handle\n') fprintf(1,'%%=================================================\n\n') data2json=@(x) x+1 savebj('handle',data2json) json2data=loadbj(ans) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2D cell array\n') fprintf(1,'%%=================================================\n\n') data2json={{1,{2,3}},{4,5},{6};{7},{8,9},{10}}; savebj('data2json',data2json) json2data=loadbj(ans) % only savebj works for cell arrays, loadbj has issues fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2D struct array\n') fprintf(1,'%%=================================================\n\n') data2json=repmat(struct('idx',0,'data','structs'),[2,3]) for i=1:6 data2json(i).idx=i; end savebj('data2json',data2json) json2data=loadbj(ans) if(exist('datetime')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% datetime object \n') fprintf(1,'%%=================================================\n\n') data2json=datetime({'8 April 2015','9 May 2015'}, 'InputFormat','d MMMM yyyy') savebj('',data2json) json2data=loadbj(ans) end if(exist('containers.Map')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a container.Maps object \n') fprintf(1,'%%=================================================\n\n') data2json=containers.Map({'Andy','William','Om'},{21,21,22}) savebj('',data2json) json2data=loadbj(ans) end if(exist('istable')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a table object \n') fprintf(1,'%%=================================================\n\n') Names={'Andy','William','Om'}'; Age=[21,21,22]'; data2json=table(Names,Age) savebj('table',table(Names,Age)) json2data=loadbj(ans) end if(exist('bandwidth')) fprintf(1,'\n%%=================================================\n') fprintf(1,'%% use _ArrayShape_ \n') fprintf(1,'%%=================================================\n\n') lband=2; uband=3; data2json=spdiags(true(8,lband+uband+1),-uband:lband,5,8); data2json=full(double(data2json)); data2json(data2json~=0)=find(data2json) savebj('',data2json,'usearrayshape',1) json2data=loadbj(ans,'fullarrayshape',1) savebj('',tril(data2json),'usearrayshape',1) json2data=loadbj(ans,'fullarrayshape',1) savebj('',triu(data2json+1i*data2json),'usearrayshape',1) json2data=loadbj(ans,'fullarrayshape',1) savebj('',tril(triu(int8(data2json))),'usearrayshape',1) json2data=loadbj(ans,'fullarrayshape',1) savebj('',data2json(:,1:5)+data2json(:,1:5)','usearrayshape',1) json2data=loadbj(ans,'fullarrayshape',1) end try val=zlibencode('test'); fprintf(1,'\n%%=================================================\n') fprintf(1,'%% a 2-D array in compressed array format\n') fprintf(1,'%%=================================================\n\n') data2json=eye(10); data2json(20,1)=1; savebj('',data2json,'Compression','zlib','CompressArraySize',0) % nestarray for 4-D or above is not working json2data=loadbj(ans) if(any(json2data(:)~=data2json(:)) || any(size(json2data)~=size(data2json))) warning('conversion does not preserve original data'); end catch end rand ('state',rngstate); jsonlab-2.0/examples/example1.json000066400000000000000000000006641367147361400172520ustar00rootroot00000000000000 { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] } jsonlab-2.0/examples/example2.json000066400000000000000000000011071367147361400172440ustar00rootroot00000000000000{ "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": ["GML", "XML"] }, "GlossSee": "markup" } } } } } jsonlab-2.0/examples/example3.json000066400000000000000000000004201367147361400172420ustar00rootroot00000000000000{"menu": { "id": "file", "value": "_&File", "popup": { "menuitem": [ {"value": "_&New", "onclick": "CreateNewDoc(\"'\\\"Untitled\\\"'\")"}, {"value": "_&Open", "onclick": "OpenDoc()"}, {"value": "_&Close", "onclick": "CloseDoc()"} ] } }} jsonlab-2.0/examples/example4.json000066400000000000000000000010631367147361400172470ustar00rootroot00000000000000[ { "sample" : { "rho" : 1 } }, { "sample" : { "rho" : 2 } }, [ { "_ArrayType_" : "double", "_ArraySize_" : [1,2], "_ArrayData_" : [1,0] }, { "_ArrayType_" : "double", "_ArraySize_" : [1,2], "_ArrayData_" : [1,1] }, { "_ArrayType_" : "double", "_ArraySize_" : [1,2], "_ArrayData_" : [1,2] } ], [ "Paper", "Scissors", "Stone" ], ["a", "b\\", "c\"","d\\\"","e\"[","f\\\"[","g[\\","h[\\\""] ] jsonlab-2.0/examples/jsonlab_basictest.matlab000066400000000000000000000542331367147361400215170ustar00rootroot00000000000000 < M A T L A B (R) > Copyright 1984-2016 The MathWorks, Inc. R2016a (9.0.0.341360) 64-bit (glnxa64) February 11, 2016 For online documentation, see http://www.mathworks.com/support For product information, visit www.mathworks.com. Academic License >> >> >> >> >> >> >> >> >> >> >> %================================================= >> % a simple scalar value >> %================================================= >> >> data2json = 3.1416 >> ans = [3.141592654] >> json2data = 3.1416 >> >> %================================================= >> % an empty array >> %================================================= >> >> data2json = [] >> ans = [] >> json2data = Empty cell array: 0-by-1 >> >> %================================================= >> % an ampty string >> %================================================= >> >> data2json = '' >> ans = { "emptystr": "" } >> json2data = emptystr: [1x0 char] >> >> %================================================= >> % a simple row vector >> %================================================= >> >> data2json = 1 2 3 >> ans = [1,2,3] >> json2data = 1 2 3 >> >> >> %================================================= >> % a simple column vector >> %================================================= >> >> data2json = 1 2 3 >> ans = [ [1], [2], [3] ] >> json2data = 1 2 3 >> >> >> %================================================= >> % a string array >> %================================================= >> >> data2json = AC EG >> ans = [ "AC", "EG" ] >> json2data = 'AC' 'EG' >> >> %================================================= >> % a string with escape symbols >> %================================================= >> >> data2json = AB CD one"two >> ans = { "str": "AB\tCD\none\"two" } >> json2data = str: 'AB CD...' >> >> %================================================= >> % a mix-typed cell >> %================================================= >> >> data2json = 'a' [1] [2x1 double] >> ans = [ "a", true, [ [2], [3] ] ] >> json2data = 'a' [1] [2x1 double] >> >> >> %================================================= >> % a 3-D array in nested array form >> %================================================= >> >> >> ans = [ [ [1,9,17,25,33,41], [3,11,19,27,35,43], [5,13,21,29,37,45], [7,15,23,31,39,47] ], [ [2,10,18,26,34,42], [4,12,20,28,36,44], [6,14,22,30,38,46], [8,16,24,32,40,48] ] ] >> json2data(:,:,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2) = 9 11 13 15 10 12 14 16 json2data(:,:,3) = 17 19 21 23 18 20 22 24 json2data(:,:,4) = 25 27 29 31 26 28 30 32 json2data(:,:,5) = 33 35 37 39 34 36 38 40 json2data(:,:,6) = 41 43 45 47 42 44 46 48 >> >> >> %================================================= >> % a 3-D array in annotated array form >> %================================================= >> >> >> ans = { "_ArrayType_": "double", "_ArraySize_": [2,4,6], "_ArrayData_": [1,9,17,25,33,41,3,11,19,27,35,43,5,13,21,29,37,45,7,15,23,31,39,47,2,10,18,26,34,42,4,12,20,28,36,44,6,14,22,30,38,46,8,16,24,32,40,48] } >> json2data(:,:,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2) = 9 11 13 15 10 12 14 16 json2data(:,:,3) = 17 19 21 23 18 20 22 24 json2data(:,:,4) = 25 27 29 31 26 28 30 32 json2data(:,:,5) = 33 35 37 39 34 36 38 40 json2data(:,:,6) = 41 43 45 47 42 44 46 48 >> >> >> %================================================= >> % a 4-D array in annotated array form >> %================================================= >> >> >> ans = { "_ArrayType_": "double", "_ArraySize_": [2,4,3,2], "_ArrayData_": [1,25,9,33,17,41,3,27,11,35,19,43,5,29,13,37,21,45,7,31,15,39,23,47,2,26,10,34,18,42,4,28,12,36,20,44,6,30,14,38,22,46,8,32,16,40,24,48] } >> json2data(:,:,1,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2,1) = 9 11 13 15 10 12 14 16 json2data(:,:,3,1) = 17 19 21 23 18 20 22 24 json2data(:,:,1,2) = 25 27 29 31 26 28 30 32 json2data(:,:,2,2) = 33 35 37 39 34 36 38 40 json2data(:,:,3,2) = 41 43 45 47 42 44 46 48 >> >> >> %================================================= >> % a 3-D array in nested array form (JSONLab 1.9) >> %================================================= >> >> >> ans = [ [ [1,2], [3,4], [5,6], [7,8] ], [ [9,10], [11,12], [13,14], [15,16] ], [ [17,18], [19,20], [21,22], [23,24] ], [ [25,26], [27,28], [29,30], [31,32] ], [ [33,34], [35,36], [37,38], [39,40] ], [ [41,42], [43,44], [45,46], [47,48] ] ] >> json2data(:,:,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2) = 9 11 13 15 10 12 14 16 json2data(:,:,3) = 17 19 21 23 18 20 22 24 json2data(:,:,4) = 25 27 29 31 26 28 30 32 json2data(:,:,5) = 33 35 37 39 34 36 38 40 json2data(:,:,6) = 41 43 45 47 42 44 46 48 >> >> >> %================================================= >> % a 3-D array in annotated array form (JSONLab 1.9 or earlier) >> %================================================= >> >> >> ans = { "_ArrayType_": "double", "_ArraySize_": [2,4,6], "_ArrayData_": [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48] } >> json2data(:,:,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2) = 9 11 13 15 10 12 14 16 json2data(:,:,3) = 17 19 21 23 18 20 22 24 json2data(:,:,4) = 25 27 29 31 26 28 30 32 json2data(:,:,5) = 33 35 37 39 34 36 38 40 json2data(:,:,6) = 41 43 45 47 42 44 46 48 >> >> >> %================================================= >> % a complex number >> %================================================= >> >> data2json = 1.0000 + 2.0000i >> ans = { "_ArrayType_": "double", "_ArraySize_": [1,1], "_ArrayIsComplex_": true, "_ArrayData_": [ [1], [2] ] } >> json2data = 1.0000 + 2.0000i >> >> >> %================================================= >> % a complex matrix >> %================================================= >> >> >> data2json = 35.0000 +26.0000i 1.0000 +19.0000i 6.0000 +24.0000i 3.0000 +21.0000i 32.0000 +23.0000i 7.0000 +25.0000i 31.0000 +22.0000i 9.0000 +27.0000i 2.0000 +20.0000i 8.0000 +17.0000i 28.0000 +10.0000i 33.0000 +15.0000i 30.0000 +12.0000i 5.0000 +14.0000i 34.0000 +16.0000i 4.0000 +13.0000i 36.0000 +18.0000i 29.0000 +11.0000i >> ans = { "_ArrayType_": "double", "_ArraySize_": [6,3], "_ArrayIsComplex_": true, "_ArrayData_": [ [35,1,6,3,32,7,31,9,2,8,28,33,30,5,34,4,36,29], [26,19,24,21,23,25,22,27,20,17,10,15,12,14,16,13,18,11] ] } >> json2data = 35.0000 +26.0000i 1.0000 +19.0000i 6.0000 +24.0000i 3.0000 +21.0000i 32.0000 +23.0000i 7.0000 +25.0000i 31.0000 +22.0000i 9.0000 +27.0000i 2.0000 +20.0000i 8.0000 +17.0000i 28.0000 +10.0000i 33.0000 +15.0000i 30.0000 +12.0000i 5.0000 +14.0000i 34.0000 +16.0000i 4.0000 +13.0000i 36.0000 +18.0000i 29.0000 +11.0000i >> >> >> %================================================= >> % MATLAB special constants >> %================================================= >> >> data2json = NaN Inf -Inf >> ans = { "specials": ["_NaN_","_Inf_","-_Inf_"] } >> json2data = specials: [NaN Inf -Inf] >> >> >> %================================================= >> % a real sparse matrix >> %================================================= >> >> data2json = (1,2) 0.6557 (9,2) 0.7577 (3,5) 0.8491 (10,5) 0.7431 (10,8) 0.3922 (7,9) 0.6787 (2,10) 0.0357 (6,10) 0.9340 (10,10) 0.6555 >> ans = { "sparse": { "_ArrayType_": "double", "_ArraySize_": [10,10], "_ArrayIsSparse_": true, "_ArrayData_": [ [1,9,3,10,10,7,2,6,10], [2,2,5,5,8,9,10,10,10], [0.655740699156586837,0.757740130578333448,0.849129305868777107,0.743132468124916179,0.392227019534168164,0.678735154857773471,0.0357116785741895537,0.933993247757550549,0.655477890177556644] ] } } >> json2data = sparse: [10x10 double] >> >> >> %================================================= >> % a complex sparse matrix >> %================================================= >> >> >> data2json = (2,1) 0.6551 - 0.6551i (1,2) 0.7547 - 0.7547i (1,4) 0.2760 - 0.2760i (7,5) 0.4984 - 0.4984i (8,5) 0.9597 - 0.9597i (9,5) 0.3404 - 0.3404i (4,7) 0.1190 - 0.1190i (1,8) 0.6797 - 0.6797i (3,8) 0.1626 - 0.1626i (10,8) 0.5853 - 0.5853i >> ans = { "complex_sparse": { "_ArrayType_": "double", "_ArraySize_": [10,10], "_ArrayIsComplex_": true, "_ArrayIsSparse_": true, "_ArrayData_": [ [2,1,1,7,8,9,4,1,3,10], [1,2,4,5,5,5,7,8,8,8], [0.655098003973840659,0.754686681982360885,0.276025076998578367,0.498364051982142953,0.959743958516081075,0.340385726666133204,0.118997681558376645,0.679702676853674803,0.162611735194630569,0.585267750979777346], [-0.655098003973840659,-0.754686681982360885,-0.276025076998578367,-0.498364051982142953,-0.959743958516081075,-0.340385726666133204,-0.118997681558376645,-0.679702676853674803,-0.162611735194630569,-0.585267750979777346] ] } } >> json2data = complex_sparse: [10x10 double] >> >> >> %================================================= >> % an all-zero sparse matrix >> %================================================= >> >> >> ans = { "all_zero_sparse": { "_ArrayType_": "double", "_ArraySize_": [2,3], "_ArrayIsSparse_": true, "_ArrayData_": [] } } >> json2data = all_zero_sparse: [2x3 double] >> >> >> %================================================= >> % an empty sparse matrix >> %================================================= >> >> >> ans = { "empty_sparse": { "_ArrayType_": "double", "_ArraySize_": [0,0], "_ArrayIsSparse_": true, "_ArrayData_": [] } } >> json2data = empty_sparse: [] >> >> >> %================================================= >> % an empty 0-by-0 real matrix >> %================================================= >> >> >> ans = { "empty_0by0_real": [] } >> json2data = empty_0by0_real: {0x1 cell} >> >> %================================================= >> % an empty 0-by-3 real matrix >> %================================================= >> >> >> ans = { "empty_0by3_real": { "_ArrayType_": "double", "_ArraySize_": [0,3], "_ArrayData_": [] } } >> json2data = empty_0by3_real: [0x3 double] >> >> >> %================================================= >> % a sparse real column vector >> %================================================= >> >> >> ans = { "sparse_column_vector": { "_ArrayType_": "double", "_ArraySize_": [5,1], "_ArrayIsSparse_": true, "_ArrayData_": [ [2,4,5], [3,1,4] ] } } >> json2data = sparse_column_vector: [5x1 double] >> >> %================================================= >> % a sparse complex column vector >> %================================================= >> >> >> ans = { "complex_sparse_column_vector": { "_ArrayType_": "double", "_ArraySize_": [5,1], "_ArrayIsComplex_": true, "_ArrayIsSparse_": true, "_ArrayData_": [ [2,4,5], [3,1,4], [-3,-1,-4] ] } } >> json2data = complex_sparse_column_vector: [5x1 double] >> >> %================================================= >> % a sparse real row vector >> %================================================= >> >> >> ans = { "sparse_row_vector": { "_ArrayType_": "double", "_ArraySize_": [1,5], "_ArrayIsSparse_": true, "_ArrayData_": [ [2,4,5], [3,1,4] ] } } >> json2data = sparse_row_vector: [0 3 0 1 4] >> >> %================================================= >> % a sparse complex row vector >> %================================================= >> >> >> ans = { "complex_sparse_row_vector": { "_ArrayType_": "double", "_ArraySize_": [1,5], "_ArrayIsComplex_": true, "_ArrayIsSparse_": true, "_ArrayData_": [ [2,4,5], [3,1,4], [-3,-1,-4] ] } } >> json2data = complex_sparse_row_vector: [1x5 double] >> >> %================================================= >> % a structure >> %================================================= >> >> data2json = name: 'Think Different' year: 1997 magic: [3x3 double] misfits: [Inf NaN] embedded: [1x1 struct] >> ans = { "astruct": { "name": "Think Different", "year": 1997, "magic": [ [8,1,6], [3,5,7], [4,9,2] ], "misfits": ["_Inf_","_NaN_"], "embedded": { "left": true, "right": false } } } >> json2data = astruct: [1x1 struct] >> ans = logical >> >> %================================================= >> % a structure array >> %================================================= >> >> >> >> >> ans = { "Supreme Commander": [ { "name": "Nexus Prime", "rank": 9 }, { "name": "Sentinel Prime", "rank": 9 }, { "name": "Optimus Prime", "rank": 9 } ] } >> json2data = Supreme_0x20_Commander: {[1x1 struct] [1x1 struct] [1x1 struct]} >> >> %================================================= >> % a cell array >> %================================================= >> >> >> >> >> data2json = [1x1 struct] [1x1 struct] [1x4 double] >> ans = { "debian": [ [ { "buzz": 1.10, "rex": 1.20, "bo": 1.30, "hamm": 2.00, "slink": 2.10, "potato": 2.20, "woody": 3.00, "sarge": 3.10, "etch": 4.00, "lenny": 5.00, "squeeze": 6.00, "wheezy": 7.00 }, { "Ubuntu": [ "Kubuntu", "Xubuntu", "Lubuntu" ] }, [10.04,10.10,11.04,11.10] ] ] } >> json2data = debian: {{1x3 cell}} >> >> %================================================= >> % invalid field-name handling >> %================================================= >> >> json2data = ValidName: 1 x0x5F_InvalidName: 2 x0x3A_Field_0x3A_: 3 x0xE9A1B9__0xE79BAE_: '绝密' >> >> %================================================= >> % a function handle >> %================================================= >> >> data2json = @(x)x+1 >> ans = { "handle": { "function": "@(x)x+1", "type": "anonymous", "file": "", "workspace": [ { } ], "within_file_path": "__base_function" } } >> json2data = handle: [1x1 struct] >> >> %================================================= >> % a 2D cell array >> %================================================= >> >> >> ans = { "data2json": [ [ [ 1, [ 2, 3 ] ], [ 4, 5 ], [ 6 ] ], [ [ 7 ], [ 8, 9 ], [ 10 ] ] ] } >> json2data = data2json: {{1x3 cell} {1x3 cell}} >> >> %================================================= >> % a 2D struct array >> %================================================= >> >> data2json = 2x3 struct array with fields: idx data >> >> ans = { "data2json": [ [ { "idx": 1, "data": "structs" }, { "idx": 2, "data": "structs" } ], [ { "idx": 3, "data": "structs" }, { "idx": 4, "data": "structs" } ], [ { "idx": 5, "data": "structs" }, { "idx": 6, "data": "structs" } ] ] } >> json2data = data2json: {{1x2 cell} {1x2 cell} {1x2 cell}} >> >> >> %================================================= % datetime object %================================================= data2json = 08-Apr-2015 09-May-2015 ans = [ { "Format": "dd-MMM-uuuu", "TimeZone": "", "Year": 2015, "Month": 4, "Day": 8, "Hour": 0, "Minute": 0, "Second": 0, "SystemTimeZone": "America\/New_York" }, { "Format": "dd-MMM-uuuu", "TimeZone": "", "Year": 2015, "Month": 5, "Day": 9, "Hour": 0, "Minute": 0, "Second": 0, "SystemTimeZone": "America\/New_York" } ] json2data = [1x1 struct] [1x1 struct] >> >> %================================================= % a container.Maps object %================================================= data2json = Map with properties: Count: 3 KeyType: char ValueType: double ans = { "Andy": 21, "Om": 22, "William": 21 } json2data = Andy: 21 Om: 22 William: 21 >> >> %================================================= % a table object %================================================= data2json = Names Age _________ ___ 'Andy' 21 'William' 21 'Om' 22 ans = { "table": { "_TableCols_": [ "Names", "Age" ], "_TableRows_": [], "_TableRecords_": [ [ "Andy", 21 ], [ "William", 21 ], [ "Om", 22 ] ] } } json2data = table: [3x2 table] >> >> %================================================= % use _ArrayShape_ %================================================= data2json = 1 6 11 0 0 0 0 0 2 7 12 17 0 0 0 0 3 8 13 18 23 0 0 0 4 9 14 19 24 29 0 0 0 10 15 20 25 30 35 0 ans = { "_ArrayType_": "double", "_ArraySize_": [5,8], "_ArrayZipSize_": [6,5], "_ArrayShape_": [ "band", 2, 3 ], "_ArrayData_": [11,17,23,29,35,6,12,18,24,30,1,7,13,19,25,0,2,8,14,20,0,0,3,9,15,0,0,0,4,10] } json2data = 1 6 11 0 0 0 0 0 2 7 12 17 0 0 0 0 3 8 13 18 23 0 0 0 4 9 14 19 24 29 0 0 0 10 15 20 25 30 35 0 ans = { "_ArrayType_": "double", "_ArraySize_": [5,8], "_ArrayZipSize_": [4,5], "_ArrayShape_": [ "lowerband", 3 ], "_ArrayData_": [1,7,13,19,25,0,2,8,14,20,0,0,3,9,15,0,0,0,4,10] } json2data = 1 0 0 0 0 0 0 0 2 7 0 0 0 0 0 0 3 8 13 0 0 0 0 0 4 9 14 19 0 0 0 0 0 10 15 20 25 0 0 0 ans = { "_ArrayType_": "double", "_ArraySize_": [5,8], "_ArrayIsComplex_": true, "_ArrayZipSize_": [2,3,5], "_ArrayShape_": [ "upperband", 2 ], "_ArrayData_": [11,17,23,29,35,6,12,18,24,30,1,7,13,19,25,11,17,23,29,35,6,12,18,24,30,1,7,13,19,25] } json2data = Columns 1 through 4 1.0000 + 1.0000i 6.0000 + 6.0000i 11.0000 +11.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 7.0000 + 7.0000i 12.0000 +12.0000i 17.0000 +17.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 13.0000 +13.0000i 18.0000 +18.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 19.0000 +19.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i Columns 5 through 8 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 23.0000 +23.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 24.0000 +24.0000i 29.0000 +29.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 25.0000 +25.0000i 30.0000 +30.0000i 35.0000 +35.0000i 0.0000 + 0.0000i ans = { "_ArrayType_": "int8", "_ArraySize_": [5,8], "_ArrayShape_": "diag", "_ArrayData_": [1,7,13,19,25] } json2data = 1 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 13 0 0 0 0 0 0 0 0 19 0 0 0 0 0 0 0 0 25 0 0 0 ans = { "_ArrayType_": "double", "_ArraySize_": [5,5], "_ArrayZipSize_": [4,5], "_ArrayShape_": [ "lowersymmband", 3 ], "_ArrayData_": [2,14,26,38,50,0,8,20,32,44,0,0,14,26,38,0,0,0,4,10] } json2data = 2 8 14 4 0 8 14 20 26 10 14 20 26 32 38 4 26 32 38 44 0 10 38 44 50 >> >> %================================================= % a 2-D array in compressed array format %================================================= ans = { "_ArrayType_": "double", "_ArraySize_": [20,10], "_ArrayZipSize_": [1,200], "_ArrayZipType_": "zlib", "_ArrayZipData_": "eJxjYACBD/YMNAGj5o6aO2ruKBgFgwtQL10DAMHODQY= " } json2data = 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 >> >> >> >> jsonlab-2.0/examples/jsonlab_selftest.m000066400000000000000000000017231367147361400203570ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Regression Test Unit of loadjson and savejson %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% for i=1:4 fname=sprintf('example%d.json',i); if(exist(fname,'file')==0) break; end fprintf(1,'===============================================\n>> %s\n',fname); json=savejson('data',loadjson(fname)); fprintf(1,'%s\n',json); fprintf(1,'%s\n',savejson('data',loadjson(fname),'Compact',1)); data=loadjson(json); savejson('data',data,'selftest.json'); data=loadjson('selftest.json'); end for i=1:4 fname=sprintf('example%d.json',i); if(exist(fname,'file')==0) break; end fprintf(1,'===============================================\n>> %s\n',fname); json=savebj('data',loadjson(fname)); fprintf(1,'%s\n',json); data=loadbj(json); savejson('',data); savebj('data',data,'selftest.ubj'); data=loadbj('selftest.ubj'); end jsonlab-2.0/examples/jsonlab_selftest.matlab000066400000000000000000000104621367147361400213630ustar00rootroot00000000000000 < M A T L A B (R) > Copyright 1984-2016 The MathWorks, Inc. R2016a (9.0.0.341360) 64-bit (glnxa64) February 11, 2016 For online documentation, see http://www.mathworks.com/support For product information, visit www.mathworks.com. Academic License >> >> >> >> >> =============================================== >> example1.json { "data": { "firstName": "John", "lastName": "Smith", "age": 25, "address": { "streetAddress": "21 2nd Street", "city": "New York", "state": "NY", "postalCode": "10021" }, "phoneNumber": [ { "type": "home", "number": "212 555-1234" }, { "type": "fax", "number": "646 555-4567" } ] } } {"data": {"firstName": "John","lastName": "Smith","age": 25,"address": {"streetAddress": "21 2nd Street","city": "New York","state": "NY","postalCode": "10021"},"phoneNumber": [{"type": "home","number": "212 555-1234"},{"type": "fax","number": "646 555-4567"}]}} =============================================== >> example2.json { "data": { "glossary": { "title": "example glossary", "GlossDiv": { "title": "S", "GlossList": { "GlossEntry": { "ID": "SGML", "SortAs": "SGML", "GlossTerm": "Standard Generalized Markup Language", "Acronym": "SGML", "Abbrev": "ISO 8879:1986", "GlossDef": { "para": "A meta-markup language, used to create markup languages such as DocBook.", "GlossSeeAlso": [ "GML", "XML" ] }, "GlossSee": "markup" } } } } } } {"data": {"glossary": {"title": "example glossary","GlossDiv": {"title": "S","GlossList": {"GlossEntry": {"ID": "SGML","SortAs": "SGML","GlossTerm": "Standard Generalized Markup Language","Acronym": "SGML","Abbrev": "ISO 8879:1986","GlossDef": {"para": "A meta-markup language, used to create markup languages such as DocBook.","GlossSeeAlso": ["GML","XML"]},"GlossSee": "markup"}}}}}} =============================================== >> example3.json { "data": { "menu": { "id": "file", "value": "_&File", "popup": { "menuitem": [ { "value": "_&New", "onclick": "CreateNewDoc(\"'\\\"Untitled\\\"'\")" }, { "value": "_&Open", "onclick": "OpenDoc()" }, { "value": "_&Close", "onclick": "CloseDoc()" } ] } } } } {"data": {"menu": {"id": "file","value": "_&File","popup": {"menuitem": [{"value": "_&New","onclick": "CreateNewDoc(\"'\\\"Untitled\\\"'\")"},{"value": "_&Open","onclick": "OpenDoc()"},{"value": "_&Close","onclick": "CloseDoc()"}]}}}} =============================================== >> example4.json { "data": [ { "sample": { "rho": 1 } }, { "sample": { "rho": 2 } }, [ [1,0], [1,1], [1,2] ], [ "Paper", "Scissors", "Stone" ], [ "a", "b\\", "c\"", "d\\\"", "e\"[", "f\\\"[", "g[\\", "h[\\\"" ] ] } {"data": [{"sample": {"rho": 1}},{"sample": {"rho": 2}},[[1,0],[1,1],[1,2]],["Paper","Scissors","Stone"],["a","b\\","c\"","d\\\"","e\"[","f\\\"[","g[\\","h[\\\""]]} >> >> =============================================== >> example1.json {Udata{U firstNameSUJohnUlastNameSUSmithUageUUaddress{U streetAddressSU 21 2nd StreetUcitySUNew YorkUstateSUNYU postalCodeSU10021}U phoneNumber[{UtypeSUhomeUnumberSU 212 555-1234}{UtypeSUfaxUnumberSU 646 555-4567}]}} =============================================== >> example2.json {Udata{Uglossary{UtitleSUexample glossaryUGlossDiv{UtitleCSU GlossList{U GlossEntry{UIDSUSGMLUSortAsSUSGMLU GlossTermSU$Standard Generalized Markup LanguageUAcronymSUSGMLUAbbrevSU ISO 8879:1986UGlossDef{UparaSUHA meta-markup language, used to create markup languages such as DocBook.U GlossSeeAlso[SUGMLSUXML]}UGlossSeeSUmarkup}}}}}} =============================================== >> example3.json {Udata{Umenu{UidSUfileUvalueSU_&FileUpopup{Umenuitem[{UvalueSU_&NewUonclickSUCreateNewDoc("'\"Untitled\"'")}{UvalueSU_&OpenUonclickSU OpenDoc()}{UvalueSU_&CloseUonclickSU CloseDoc()}]}}}} =============================================== >> example4.json {Udata[{Usample{UrhoU}}{Usample{UrhoU}}[[$U#U [$U#U[$U#U][SUPaperSUScissorsSUStone][CaSUb\SUc"SUd\"SUe"[SUf\"[SUg[\SUh[\"]]} >> jsonlab-2.0/examples/jsonlab_speedtest.m000066400000000000000000000012431367147361400205230ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Benchmarking processing speed of savejson and loadjson %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% datalen=[1e3 1e4 1e5 1e6]; len=length(datalen); tsave=zeros(len,1); tload=zeros(len,1); for i=1:len tic; json=savejson('data',struct('d1',rand(datalen(i),3),'d2',rand(datalen(i),3)>0.5)); tsave(i)=toc; data=loadjson(json); tload(i)=toc-tsave(i); fprintf(1,'matrix size: %d\n',datalen(i)); end loglog(datalen,tsave,'o-',datalen,tload,'r*-'); legend('savejson runtime (s)','loadjson runtime (s)'); xlabel('array size'); ylabel('running time (s)'); jsonlab-2.0/examples/jsonlab_ubjson_basictest.matlab000066400000000000000000000456511367147361400231030ustar00rootroot00000000000000 < M A T L A B (R) > Copyright 1984-2016 The MathWorks, Inc. R2016a (9.0.0.341360) 64-bit (glnxa64) February 11, 2016 For online documentation, see http://www.mathworks.com/support For product information, visit www.mathworks.com. Academic License >> >> >> >> >> >> >> >> >> %================================================= >> % a simple scalar value >> %================================================= >> >> data2json = 3.1416 >> ans = [D@ !ûTD-] >> json2data = 3.1416 >> >> %================================================= >> % an empty array >> %================================================= >> >> data2json = [] >> ans = {UemptyZ} >> json2data = empty: [] >> >> %================================================= >> % an ampty string >> %================================================= >> >> data2json = '' >> ans = {UemptystrSU } >> json2data = emptystr: [1x0 char] >> >> %================================================= >> % a simple row vector >> %================================================= >> >> data2json = 1 2 3 >> ans = [$U#U >> json2data = 1 2 3 >> >> %================================================= >> % a simple column vector >> %================================================= >> >> data2json = 1 2 3 >> ans = [$U#[$U#U >> json2data = 1 2 3 >> >> %================================================= >> % a string array >> %================================================= >> >> data2json = AC EG >> ans = [SUACSUEG] >> json2data = 'AC' 'EG' >> >> %================================================= >> % a string with escape symbols >> %================================================= >> >> data2json = AB CD one"two >> ans = {UstrSU AB CD one"two} >> json2data = str: 'AB CD...' >> >> %================================================= >> % a mix-typed cell >> %================================================= >> >> data2json = 'a' [1] [2x1 double] >> ans = [CaT[$U#[$U#U] >> json2data = 'a' [1] [2x1 uint8] >> >> %================================================= >> % a 3-D array in nested array form >> %================================================= >> >> >> ans = [[[UU UUU!U)][UU UUU#U+][UU UUU%U-][UUUUU'U/]][[UU UUU"U*][UU UUU$U,][UUUUU&U.][UUUU U(U0]]] >> json2data(:,:,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2) = 9 11 13 15 10 12 14 16 json2data(:,:,3) = 17 19 21 23 18 20 22 24 json2data(:,:,4) = 25 27 29 31 26 28 30 32 json2data(:,:,5) = 33 35 37 39 34 36 38 40 json2data(:,:,6) = 41 43 45 47 42 44 46 48 >> >> >> >> >> %================================================= >> % a 3-D array in annotated array form >> %================================================= >> >> >> ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU _ArrayData_[$U#U0 !) #+ %-'/ "* $,&. (0} >> json2data(:,:,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2) = 9 11 13 15 10 12 14 16 json2data(:,:,3) = 17 19 21 23 18 20 22 24 json2data(:,:,4) = 25 27 29 31 26 28 30 32 json2data(:,:,5) = 33 35 37 39 34 36 38 40 json2data(:,:,6) = 41 43 45 47 42 44 46 48 >> >> >> %================================================= >> % a 4-D array in annotated array form >> %================================================= >> >> >> ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU _ArrayData_[$U#U0 !) #+ %-'/ "* $,&. (0} >> json2data(:,:,1,1) = 1 3 5 7 2 4 6 8 json2data(:,:,2,1) = 9 11 13 15 10 12 14 16 json2data(:,:,3,1) = 17 19 21 23 18 20 22 24 json2data(:,:,1,2) = 25 27 29 31 26 28 30 32 json2data(:,:,2,2) = 33 35 37 39 34 36 38 40 json2data(:,:,3,2) = 41 43 45 47 42 44 46 48 >> >> >> %================================================= >> % a 3-D array in nested array form (JSONLab 1.9) >> %================================================= >> >> >> ans = [[[UU][UU][UU][UU]][[U U ][U U ][U U][UU]][[UU][UU][UU][UU]][[UU][UU][UU][UU ]][[U!U"][U#U$][U%U&][U'U(]][[U)U*][U+U,][U-U.][U/U0]]] >> >> %================================================= >> % a 3-D array in annotated array form (JSONLab 1.9 or earlier) >> %================================================= >> >> >> ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU _ArrayData_[$U#U0  !"#$%&'()*+,-./0} >> >> %================================================= >> % a complex number >> %================================================= >> >> data2json = 1.0000 + 2.0000i >> ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsComplex_TU _ArrayData_[$U#[$U#U} >> json2data = 1.0000 + 2.0000i >> >> %================================================= >> % a complex matrix >> %================================================= >> >> >> data2json = 35.0000 +26.0000i 1.0000 +19.0000i 6.0000 +24.0000i 3.0000 +21.0000i 32.0000 +23.0000i 7.0000 +25.0000i 31.0000 +22.0000i 9.0000 +27.0000i 2.0000 +20.0000i 8.0000 +17.0000i 28.0000 +10.0000i 33.0000 +15.0000i 30.0000 +12.0000i 5.0000 +14.0000i 34.0000 +16.0000i 4.0000 +13.0000i 36.0000 +18.0000i 29.0000 +11.0000i >> ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsComplex_TU _ArrayData_[$U#[$U#U#   ! " $ } >> json2data = 35.0000 +26.0000i 1.0000 +19.0000i 6.0000 +24.0000i 3.0000 +21.0000i 32.0000 +23.0000i 7.0000 +25.0000i 31.0000 +22.0000i 9.0000 +27.0000i 2.0000 +20.0000i 8.0000 +17.0000i 28.0000 +10.0000i 33.0000 +15.0000i 30.0000 +12.0000i 5.0000 +14.0000i 34.0000 +16.0000i 4.0000 +13.0000i 36.0000 +18.0000i 29.0000 +11.0000i >> >> %================================================= >> % MATLAB special constants >> %================================================= >> >> data2json = NaN Inf -Inf >> ans = {Uspecials[$D#Uÿø ð ÿð } >> json2data = specials: [NaN Inf -Inf] >> >> %================================================= >> % a real sparse matrix >> %================================================= >> >> data2json = (1,2) 0.6557 (9,2) 0.7577 (3,5) 0.8491 (10,5) 0.7431 (10,8) 0.3922 (7,9) 0.6787 (2,10) 0.0357 (6,10) 0.9340 (10,10) 0.6555 >> ans = {Usparse{U _ArrayType_SUdoubleU _ArraySize_[$U#U U_ArrayIsSparse_TU _ArrayData_[$D#[$U#U ?ð @ ?äûÓë12@" @ ?è?h:öl;@ @ ?ë,8Ù±@$ @ ?çǽ½æ'#@$ @ ?Ù?[`o€@ @" ?å¸2ɘNé@ @$ ?¢HÍpà@ @$ ?íãEι¶P@$ @$ ?äù¬Ä² ¶}} >> json2data = sparse: [10x10 double] >> >> %================================================= >> % a complex sparse matrix >> %================================================= >> >> data2json = (1,2) 0.6557 - 0.6557i (9,2) 0.7577 - 0.7577i (3,5) 0.8491 - 0.8491i (10,5) 0.7431 - 0.7431i (10,8) 0.3922 - 0.3922i (7,9) 0.6787 - 0.6787i (2,10) 0.0357 - 0.0357i (6,10) 0.9340 - 0.9340i (10,10) 0.6555 - 0.6555i >> ans = {Ucomplex_sparse{U _ArrayType_SUdoubleU _ArraySize_[$U#U U_ArrayIsComplex_TU_ArrayIsSparse_TU _ArrayData_[$D#[$U#U ?ð @ ?äûÓë12¿äûÓë12@" @ ?è?h:öl;¿è?h:öl;@ @ ?ë,8Ù±¿ë,8Ù±@$ @ ?çǽ½æ'#¿çǽ½æ'#@$ @ ?Ù?[`o€¿Ù?[`o€@ @" ?å¸2ɘNé¿å¸2ɘNé@ @$ ?¢HÍpà¿¢HÍpà@ @$ ?íãEι¶P¿íãEι¶P@$ @$ ?äù¬Ä² ¶¿äù¬Ä² ¶}} >> json2data = complex_sparse: [10x10 double] >> >> %================================================= >> % an all-zero sparse matrix >> %================================================= >> >> >> ans = {Uall_zero_sparse{U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsSparse_TU _ArrayData_Z}} >> json2data = all_zero_sparse: [2x3 double] >> >> %================================================= >> % an empty sparse matrix >> %================================================= >> >> >> ans = {U empty_sparseZ} >> json2data = empty_sparse: [] >> >> %================================================= >> % an empty 0-by-0 real matrix >> %================================================= >> >> >> ans = {Uempty_0by0_realZ} >> json2data = empty_0by0_real: [] >> >> %================================================= >> % an empty 0-by-3 real matrix >> %================================================= >> >> >> ans = {Uempty_0by3_realZ} >> json2data = empty_0by3_real: [] >> >> %================================================= >> % a sparse real column vector >> %================================================= >> >> >> ans = {Usparse_column_vector{U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsSparse_TU _ArrayData_[$U#[$U#U}} >> json2data = sparse_column_vector: [5x1 double] >> >> %================================================= >> % a sparse complex column vector >> %================================================= >> >> >> ans = {Ucomplex_sparse_column_vector{U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsComplex_TU_ArrayIsSparse_TU _ArrayData_[$i#[$U#Uýÿü}} >> json2data = complex_sparse_column_vector: [5x1 double] >> >> %================================================= >> % a sparse real row vector >> %================================================= >> >> >> ans = {Usparse_row_vector{U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsSparse_TU _ArrayData_[$U#[$U#U}} >> json2data = sparse_row_vector: [0 3 0 1 4] >> >> %================================================= >> % a sparse complex row vector >> %================================================= >> >> >> ans = {Ucomplex_sparse_row_vector{U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsComplex_TU_ArrayIsSparse_TU _ArrayData_[$i#[$U#Uýÿü}} >> json2data = complex_sparse_row_vector: [1x5 double] >> >> %================================================= >> % a structure >> %================================================= >> >> data2json = name: 'Think Different' year: 1997 magic: [3x3 double] misfits: [Inf NaN] embedded: [1x1 struct] >> ans = {Uastruct{UnameSUThink DifferentUyearuÍUmagic[$U#[$U#U Umisfits[$D#Uð ÿø Uembedded{UleftTUrightF}}} >> json2data = astruct: [1x1 struct] >> ans = logical >> >> %================================================= >> % a structure array >> %================================================= >> >> >> >> >> ans = {USupreme Commander[{UnameSU Nexus PrimeUrankU }{UnameSUSentinel PrimeUrankU }{UnameSU Optimus PrimeUrankU }]} >> json2data = Supreme_0x20_Commander: {[1x1 struct] [1x1 struct] [1x1 struct]} >> >> %================================================= >> % a cell array >> %================================================= >> >> >> >> >> data2json = [1x1 struct] [1x1 struct] [1x4 double] >> ans = {Udebian[[{Ubuzz[D?ñ™™™™™š]Urex[D?ó333333]Ubo[D?ôÌÌÌÌÌÍ]UhammUUslink[D@ ÌÌÌÌÌÍ]Upotato[D@™™™™™š]UwoodyUUsarge[D@ÌÌÌÌÌÍ]UetchUUlennyUUsqueezeUUwheezyU}{UUbuntu[SUKubuntuSUXubuntuSULubuntu]}[$D#U@$záG®@$333333@&záG®@&333333]]} >> json2data = debian: {{1x3 cell}} >> >> %================================================= >> % invalid field-name handling >> %================================================= >> >> json2data = ValidName: 1 x0x5F_InvalidName: 2 x0x3A_Field_0x3A_: 3 x0xE9A1B9__0xE79BAE_: '绝密' >> >> %================================================= >> % a function handle >> %================================================= >> >> data2json = @(x)x+1 >> ans = {Uhandle{UfunctionSU@(x)x+1UtypeSU anonymousUfileSU U workspace[{}]Uwithin_file_pathSU__base_function}} >> json2data = handle: [1x1 struct] >> >> %================================================= >> % a 2D cell array >> %================================================= >> >> >> ans = {U data2json[[[U[UU]][UU][U]][[U][UU ][U ]]]} >> json2data = data2json: {{1x3 cell} {1x3 cell}} >> >> %================================================= >> % a 2D struct array >> %================================================= >> >> data2json = 2x3 struct array with fields: idx data >> >> ans = {U data2json[[{UidxUUdataSUstructs}{UidxUUdataSUstructs}][{UidxUUdataSUstructs}{UidxUUdataSUstructs}][{UidxUUdataSUstructs}{UidxUUdataSUstructs}]]} >> json2data = data2json: {{1x2 cell} {1x2 cell} {1x2 cell}} >> >> >> %================================================= % datetime object %================================================= data2json = 08-Apr-2015 09-May-2015 ans = [{UFormatSU dd-MMM-uuuuUTimeZoneSU UYearußUMonthUUDayUUHourU UMinuteU USecondU USystemTimeZoneSUAmerica/New_York}{UFormatSU dd-MMM-uuuuUTimeZoneSU UYearußUMonthUUDayU UHourU UMinuteU USecondU USystemTimeZoneSUAmerica/New_York}] json2data = [1x1 struct] [1x1 struct] >> >> %================================================= % a container.Maps object %================================================= data2json = Map with properties: Count: 3 KeyType: char ValueType: double ans = {UAndyUUOmUUWilliamU} json2data = Andy: 21 Om: 22 William: 21 >> >> %================================================= % a table object %================================================= data2json = Names Age _________ ___ 'Andy' 21 'William' 21 'Om' 22 ans = {Utable{U _TableCols_[SUNamesSUAge]U _TableRows_ZU_TableRecords_[[SUAndyU][SUWilliamU][SUOmU]]}} json2data = table: [3x2 table] >> >> %================================================= % use _ArrayShape_ %================================================= data2json = 1 6 11 0 0 0 0 0 2 7 12 17 0 0 0 0 3 8 13 18 23 0 0 0 4 9 14 19 24 29 0 0 0 10 15 20 25 30 35 0 ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayZipSize_[$U#UU _ArrayShape_[SUbandUU]U _ArrayData_[$U#U #       } json2data = 1 6 11 0 0 0 0 0 2 7 12 17 0 0 0 0 3 8 13 18 23 0 0 0 4 9 14 19 24 29 0 0 0 10 15 20 25 30 35 0 ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayZipSize_[$U#UU _ArrayShape_[SU lowerbandU]U _ArrayData_[$U#U      } json2data = 1 0 0 0 0 0 0 0 2 7 0 0 0 0 0 0 3 8 13 0 0 0 0 0 4 9 14 19 0 0 0 0 0 10 15 20 25 0 0 0 ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayIsComplex_TU_ArrayZipSize_[$U#UU _ArrayShape_[SU upperbandU]U _ArrayData_[$U#U #   #  } json2data = Columns 1 through 4 1.0000 + 1.0000i 6.0000 + 6.0000i 11.0000 +11.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 7.0000 + 7.0000i 12.0000 +12.0000i 17.0000 +17.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 13.0000 +13.0000i 18.0000 +18.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 19.0000 +19.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i Columns 5 through 8 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 23.0000 +23.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 24.0000 +24.0000i 29.0000 +29.0000i 0.0000 + 0.0000i 0.0000 + 0.0000i 25.0000 +25.0000i 30.0000 +30.0000i 35.0000 +35.0000i 0.0000 + 0.0000i ans = {U _ArrayType_SUint8U _ArraySize_[$U#UU _ArrayShape_SUdiagU _ArrayData_[$U#U } json2data = 1 0 0 0 0 0 0 0 0 7 0 0 0 0 0 0 0 0 13 0 0 0 0 0 0 0 0 19 0 0 0 0 0 0 0 0 25 0 0 0 ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#UU_ArrayZipSize_[$U#UU _ArrayShape_[SU lowersymmbandU]U _ArrayData_[$U#U&2  , &  } json2data = 2 8 14 4 0 8 14 20 26 10 14 20 26 32 38 4 26 32 38 44 0 10 38 44 50 >> >> %================================================= % a 2-D array in compressed array format %================================================= ans = {U _ArrayType_SUdoubleU _ArraySize_[$U#U U_ArrayZipSize_[$U#UÈU_ArrayZipType_SUzlibU_ArrayZipData_[$U#U xœc` ö 4£æŽš;jî(ƒ P/] ÁÎ } json2data = 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 >> >> >> >> jsonlab-2.0/fast_match_bracket.m000066400000000000000000000052051367147361400170030ustar00rootroot00000000000000function [endpos, maxlevel] = fast_match_bracket(key,pos,startpos,brackets) % % [endpos, maxlevel] = fast_match_bracket(key,pos,startpos,brackets) % % A fast function to find the position of a closing bracket token in a string % % authors:Qianqian Fang (q.fang neu.edu) % % input: % key: a preprocessed string containing only relevant opening/closing % bracket characters for accelerating the search. % pos: a 1D integer vector with a length matching the length of key, % recording the corresponding position of each char. in the original string. % startpos: the index in the original string as the start position to search; the % startpos must be at least 1 greater than the opening bracket position % brackets: (optional), a string of length 2, with the first character % being the opening token and the 2nd being the closing token. % if not given, brackets is set to '[]' to find matching square-brackets; % for example, '{}' looks for a matching closing curly-bracket in % the string key(pos(startpos,:end)) % % output: % endpos: if a matching bracket is found, return its position in the original % string % maxlevel: return the depth of the enclosed brackets between the searched pair, % includig the searching pair. For example, the matching closing-bracket % of the 1st square bracket (startpos=2) in '[[[]],[]]' returns a % position of 9, with a maximum depth of 3; searching for the closing % bracket for the 2nd square bracket (startpos=3) returns a position of % 5 and max-depth of 2. % % example: % str='[[ [1,2], 1], 10, [5,10] ]'; % pos=find(str=='[' | str==']') % key=str(pos) % [p1,dep]=fast_match_bracket(key,1:length(key),3) % [p2,dep]=fast_match_bracket(key,pos,2) % [p3,dep]=fast_match_bracket(key,pos,3) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin<4) brackets='[]'; end startpos=find( pos >= startpos, 1 ); count = key(startpos:end); if(length(count)==1 && count==']') endpos=pos(end); maxlevel=1; return; end count=count(1:min(length(count),8)); flag=cumsum(count==brackets(1))-cumsum(count==brackets(2))+1; endpos = find(flag==0,1); if(isempty(endpos)) count= key(startpos:end); flag=cumsum(count==brackets(1))-cumsum(count==brackets(2))+1; endpos = find(flag==0,1); end maxlevel=max([1,max(flag(1:endpos))]); endpos = pos(endpos + startpos-1); jsonlab-2.0/gendocs.sh000077500000000000000000000031221367147361400147760ustar00rootroot00000000000000#!/bin/sh #============================================================ # JSONLAB inline documentation to wiki convertor # # Author: Qianqian Fang #============================================================ print_help() { awk '/^%/ {dp=1} / this file is part of EasyH5/ {exit} \ /-- this function is part of JSONLab/ {exit} \ /^function/ {dp=1} /./ {if(dp==1) print;}' $1 \ | grep -v 'Qianqian' | grep -v 'date:' | #grep -v '^%\s*$'| \ sed -e 's/^function\(.*$\)/\n%==== function\1 ====/g' } print_group() { for fun in $@ do print_help $fun.m done echo '' } func_jdata="jdataencode jdatadecode" func_json="loadjson savejson" func_bjdata="loadbj savebj" func_ubjson="loadubjson saveubjson" func_msgpack="loadmsgpack savemsgpack" func_space="jsave jload" func_zip="zlibencode zlibdecode gzipencode gzipdecode lzmaencode lzmadecode lzipencode lzipdecode lz4encode lz4decode lz4hcencode lz4hcdecode base64encode base64decode encodevarname decodevarname" func_helper="jsonopt mergestruct varargin2struct match_bracket fast_match_bracket nestbracket2dim" echo %%=== "#" JData specification === print_group $func_jdata echo %%=== "#" JSON === print_group $func_json echo %%=== "#" BJData === print_group $func_bjdata echo %%=== "#" UBJSON === print_group $func_ubjson echo %%=== "#" MessagePack === print_group $func_msgpack echo %%=== "#" Workspace === print_group $func_space echo %%=== "#" Compression and decompression === print_group $func_zip echo %%=== "#" Miscellaneous functions === print_group $func_helper jsonlab-2.0/genlog.sh000077500000000000000000000000771367147361400146350ustar00rootroot00000000000000#!/bin/sh git log --date=short --pretty='format: %cd [%h] %s' jsonlab-2.0/gzipdecode.m000066400000000000000000000043621367147361400153170ustar00rootroot00000000000000function varargout = gzipdecode(varargin) % % output = gzipdecode(input) % or % output = gzipdecode(input,info) % % Decompressing a GZIP-compressed byte-stream to recover the original data % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % Modified by: Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store the GZIP-compressed data % info (optional): a struct produced by the zmat/lz4hcencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=gzipencode(eye(10)); % orig=gzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) if(nargin>1) [varargout{1:nargout}]=zmat(varargin{1},varargin{2:end}); else [varargout{1:nargout}]=zmat(varargin{1},0,'gzip',varargin{2:end}); end return; elseif(isoctavemesh) error('You must install the ZMat toolbox (http://github.com/fangq/zmat) to use this function in Octave'); end error(javachk('jvm')); if(ischar(varargin{1})) varargin{1}=uint8(varargin{1}); end input=typecast(varargin{1}(:)','uint8'); gzip = java.util.zip.GZIPInputStream(java.io.ByteArrayInputStream(input)); buffer = java.io.ByteArrayOutputStream(); org.apache.commons.io.IOUtils.copy(gzip, buffer); gzip.close(); if(nargout>0) varargout{1} = typecast(buffer.toByteArray(), 'uint8')'; if(nargin>1 && isstruct(varargin{2}) && isfield(varargin{2},'type')) inputinfo=varargin{2}; varargout{1}=typecast(varargout{1},inputinfo.type); varargout{1}=reshape(varargout{1},inputinfo.size); end end jsonlab-2.0/gzipencode.m000066400000000000000000000034171367147361400153310ustar00rootroot00000000000000function varargout = gzipencode(varargin) % % output = gzipencode(input) % or % [output, info] = gzipencode(input) % % Compress a string or numerical array using the GZIP-compression % % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % Modified by: Qianqian Fang (q.fang neu.edu) % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=gzipencode(eye(10)); % orig=gzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) [varargout{1:nargout}]=zmat(varargin{1},1,'gzip'); return; elseif(isoctavemesh) error('You must install the ZMat toolbox (http://github.com/fangq/zmat) to use this function in Octave'); end error(javachk('jvm')); if(ischar(varargin{1})) varargin{1}=uint8(varargin{1}); end input=typecast(varargin{1}(:)','uint8'); buffer = java.io.ByteArrayOutputStream(); gzip = java.util.zip.GZIPOutputStream(buffer); gzip.write(input, 0, numel(input)); gzip.close(); varargout{1} = typecast(buffer.toByteArray(), 'uint8')'; if(nargout>1) varargout{2}=struct('type',class(varargin{1}),'size',size(varargin{1}),'method','gzip','status',0); end jsonlab-2.0/images/000077500000000000000000000000001367147361400142645ustar00rootroot00000000000000jsonlab-2.0/images/jsonlab-banner.png000066400000000000000000000242311367147361400176670ustar00rootroot00000000000000PNG  IHDR@,OsRGBPLTE  &#'--/.26:5;6;<==>>>DhjgikhjlikmjFElnkGEmolnpmILoqnqsprtqOMsurPNtvsuwtRUvxuwyvxzwy{xWUz|yXVYW{}z|~{[]}|~}~`_b`bfdggghgjhkilppqrrsswtxzy{z|~|}~¾ÿ.MbKGDH pHYsnVnVEtIME5 +ʘ IDATxoLTWFSt$Z1ku6Zu4)MUF5Ej[%X$DJ|pa%$e'MMJRj aj&̇w?ws̜{~qR2ݗG3?1--,UmY=3˿?巣r9]~iBCnˣ$&gx̗?8@?}0Ӂ -6@2 i -+@_3>6@<&9ӾHw [wh|@6@I>o[[{/82ritz$V o?2 @7rٽ9)E \kq.\maqoʊhcώXKz  Q@#m޹i};Ex쇻6GZ v)nAm?>i;{+vX(ʜZ 4g= 0{-u h^?_//s&ܲN?';'?{=n9=l2hqehYo~=7v+?|:4)-u"rTZEiO:C\@ e!@rR_8.yABzy{ P $`N `K3P }i{,&bPWVUjx,@&r%-}ܩ(RZ o\^"_#=2(л\% .M AKKj~{wXX[AK=+ hi`]%.t8_/|!jflh28n- Tn-Go\v!M= P?K_}iH}ᔖrJZ UW7.ހ+_R.fJGiRj ׃v[:AK{;S6z{̍4v`9+ۡ2#-%%vO7 MoULrJJb{4=}ح6tI̟<4_s76t=/w{ϳV+M o#eJ @8 =GO)~mTm̩K;#l;Uf~tu-(2: JE+;6 o:+uZ'Q'^K8lXd|xAet$*=M@G+>fؑnU_v/ۙNT?d"B-d珣ee9~3?T`}޺5V8̓.*4`Z`DpֲoWɟqMIF/Z 9| Nh}"?  Ubnmvuso}[ܮi.s0.W|MKm'Xvd#r䴫J "M%ۈmH5KƚMW}/vJ@At?&/KowfV-=V5QMmx2CPlw1@LVZ U⯕@кdƻř~pH]?sE|#-J:2\\|˜"ɣޟx'@v@EO,$UPlwAT"iUX% Px^l42~԰<]^Τ"_DT!',Xק`!h<@Z\NF?\Ӳ@-܍).Xiy:S Pn9ʉ B AZ\SM W?:"}QKLQӤK$wr>`kZJ Mõ6J&@,J<@n0yG@ΜUuFZnZF*0hp ?}1W|A JZ}Ro)q1Q1E JjJGm<9ܔomV+(?iR₥#\VI쭥^ɡO5&>n^yH{R5m$Q!uL)+ .-Rƒ+J{_@Z\&mH ^2qczDKC‚EsR D5aB3c$@>|R/e $> _5ZsHiZ4@qL(A8QRF 1q 7\CL3J&c%*6>Q~Ӵ G 5l})Ҽ($@^*-W9b T\hh:tLyM5nq dRS =^=ݡԁE'˪.]mpV^jl?Ev8s-[>rDؙKWw SC&ø :LڹͿ/pd3 w庸R^rV+Q"@al0-TkG|N]P?@= 4*(e4Ch6)\R{t5TI&+yQ;Z=´"<I P? JNOuI\0(rީ6NJ@m&/Ɉ+]{ 7j!:tmbHғ=U>ą,-Ї Q4 C`tw土:^@YGsSxhee1Z0)-E 6T*Uj4l $_|ZRl̊K"@OQu$&iCVh 3y]N@-B!^0Oe =;,*P;GJ@ڤT$@2f@Ygr?/g/OVi )TݕjS3UiߋkD0@fh9Z@i/|:,STLѱ`&@ũ 6ȣ T|)Hsh|? }9- ouP1A@ ) \ T?H)A퇹Ȝ1M@{DfpoFF^}@ifR,3n_@yDZw,-*(ưð*H1Ρ{8m[02ִ$U^C>Er&v_2l_R mN* p:h-@cVw_Xe.9kRQtqܝt iW:O=ݕ|[4P3O,qyOx=/O[ Gȶ?R=dbK@΀X 'v%P*j̵a"kZE'9o9Fzs{Mxz_ߕuL`t 5ATS4VZ@XQMRȌf<>` {/KqAZ`˿ ٨υPxoΰqa7 jאP7UI:@K=7,Dž&ߜk9FE}7^R#E"deZ$Q6 o9EPL>@T\}ydSu =_ O4l!DG#r0zNq7k|1 jw8d Y0n>@@KҖl.+(M6}X?@[2$b*xp޽?ݼ~+Ύd_Vr)r6%;0} Ŧv J]q b|.@\C.zug]> {7b@j3Cte dzb&J2VRhF65 X=n)t\~3vsdN8qgvcs#ҡ5:b@pECԆ-6Y P?j:::'M*4$Zb|Luy^P!kL V1+AVx&ߠQ)3@:sЂ&؁c|c7K]#Z'0ͨ~ExJU 1$3Ӭ5zIW+7J@a?'M(DYFZYZc<(FAX ,؝I g93 ߣ6go|o0KJW"}\/h(OdN=Xp(^k~Y·o=\UHC@qkA%}ƫ#7a $`RȤ|:IkRwi$#O)\(s޲-|{vp~@ #}*AcIhaՄV't^z >0=1D鉤DFtFJcLZ| 3H"s."Efm@ĺudDrnf؁R!'+G( aBJOBJ7<֐FP:鯴Q}>EV=yAydr/P b+<* {h!6@WnԞ繻7.9Y!̩5,@_'<ڗeDǯYM^(pV @ѷ%XM?lfPd!9;C s9{i$xqwjgDFVZUiԅm&jI(AV E ,2#؊3GY 0p|*7~+PRhH*3A ĕ(h@t^)#~"`uwY=~)oeAD-/Pޠb stt#5\ PmM.P25>Dmlx\TI&dR*(!:VdkD>c嗠}j&4up*{jG LnVu=U&3dDuO@Lj(O6c37T`q9]@J h @Fg h5D0]072Gk @$3 P.nXP~&.ڢg| p:SP)n{MN0"@@J=RH (WD@z,z"Y 蟦*^PmټAP9Pzu6pHaԯzT%Ϭ2H@_S8^BHx$(V&p2`5@#*Dg9GLfJD9twved0F!@(fUĎaԨjxX@td4jqPl#B P{% PNVNqLJMN{j P7I)?%1@m %@-+WI!&v v~@#WBT~N5\Dd"݄) P +w?# &j\#uWNǯrjҢ-w5 ι} :$W> Sn>@]h3A˹BM-@ua;~& 2&\͏3Yu$0 IQѥI?wgdo&=iCKAih- :Na9qLK $6'l><`n{xfCK9ob&zU\8CgǏGk_4ZՒ [)] _%(1,h {)[~1np?96jTޞC<#șJf40]=Q $@v _L"gQnQ7[2 "Ph(7/o6k) )$Z&l7Qس#* PEQG/ vO)J(A&DLXv u.o4Y:Rٻ"I62kqK. STE(18^h/os=FЪ1b!MtHMQjE=`,?@m@g,q0x6iD+R@d(9$C:&ti:@O z͒嚝BIut; 3fDK팫ϳ s ǽ]r5 IDAT gᏫaq\eȊTW3zf*vv ">E ɬh@&Oj9A@i/ckD-8RD!@n+֖IJvO QG6YŠ"$H e:`?*8^gG{z?VhZ\z>8T X?@Zgm@dC >i0-sb$R_E96l[% ΏF*7 %ȫH&4 P( tfY^f ?*8daT@ŖKZ)BO_lS(e>@mg1@@4r P'@K=󳖂iirYyZp oj9b(ê 2͏DB"J <9b?ti:ED= {h˻(zK6Y#1 N(5@ TLyf//o¢S-n{lumSwH5Ua3C۷ӛ,WAjQZw\n/ڄo]!~KzY3h6mƬg7BnHU-IENDB`jsonlab-2.0/images/jsonlab-logo.png000066400000000000000000000055321367147361400173650ustar00rootroot00000000000000PNG  IHDRXrPLTEcoliiijjjkkk<~otRNS@fbKGDH pHYs??w tIME $A]| IDATx]&zn/rW9Ћ띑?!Oi ied`=c} R`er'yq/lan|$|U+_'~{Lx=`娺V=rVk-S_ujKyeP!k-X<k)X}be+E],Ȃ) XK|D~eZwoBcV?XV1"΢k)Q ,:bY=Y [kuc%\ OXTkXhc1g`f/oX2b' X_r VAXƃ%aaUJPd c =XȗвXV,HrZY%,HW~raYAGE҇'X,8B^3b `V96 3; k4fƩJO9jXgĢ X4 Y4,wĢ =(5ZKbQX2c `a,zh`X0조,8,X!,dB UX6rS,W`2XoKT<BwhUk bA,I䴶La,?XsjY,bp`ɱ;DEOr eX8,X ,qa`dr X=4JMbgƀXtk,B9rEfKL9,ܔf A?b`*Cab2:,| bу=d:bp`y  ,>07``` 2X(p,\,Y*3 łEa,X ϧŷVKc1x,H[XީaZ縔;(RZ:r>,X -M`3/P2*_=KӸ) `qX&˴zJȭ`' Z7:ƂXT+q9,̏XϢLXp{)7Vb(ۑXKX֒oQf{%`gyE>,kM=oK(ǚ2cQ<;nc-wK% 'cQҔwV<g!UKXXdptiX: k^8 WS@uBeYr'P,Vkc;٪C:i nPmnM9<:X>_5%bВb-šRf҂Q\ \ \ F.a<`ĕw,"o `{^bc;\|X'?v<~N3;m AX ]'UX݋VVōbA^˚iaOaJګbXdn9.BvCʄrs:|y-V‚1XB9yX.}0zDXZ#Xt?͇5٪?1*X - uXkNv=fv k:&6V-bAXkO2+;b.̿rb ‚&$:U.- %X?cmg kˍ܎*nDzXNXt=hXs>,`AX3sS3bCNWA rcA+4#=UjjBihc]u0X2%vKB 5 k.EDuȱ\Xmh~5&ڊcYеI :<<32~,j V6,' MbmلeLGXug^,dp`55賚"wc72qX%XcX*ezpbQXʀ= XXky 5c >,P`XYEV-Unn7aVξ,.4͌t29 XuXv_ĚӱqX(PrHZaA){:1:,SkeVY Xg93ޜXgJ3c-72|Zyʌb XZ:"nV*֮21Xʁl_:˽R7&:% % % output: % isoctave: 1 if in octave, otherwise 0 % verinfo: a string, showing the version of octave (OCTAVE_VERSION) % % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net) % verinfo=''; isoctave=(exist('OCTAVE_VERSION','builtin')~=0); if(nargout==2 && isoctave) verinfo=OCTAVE_VERSION; end jsonlab-2.0/jdatadecode.m000066400000000000000000000467601367147361400154410ustar00rootroot00000000000000function newdata=jdatadecode(data,varargin) % % newdata=jdatadecode(data,opt,...) % % Convert all JData object (in the form of a struct array) into an array % (accepts JData objects loaded from either loadjson/loadubjson or % jsondecode for MATLAB R2016b or later) % % This function implements the JData Specification Draft 3 (Jun. 2020) % see http://github.com/fangq/jdata for details % % authors:Qianqian Fang (q.fang neu.edu) % % input: % data: a struct array. If data contains JData keywords in the first % level children, these fields are parsed and regrouped into a % data object (arrays, trees, graphs etc) based on JData % specification. The JData keywords are % "_ArrayType_", "_ArraySize_", "_ArrayData_" % "_ArrayIsSparse_", "_ArrayIsComplex_", % "_ArrayZipType_", "_ArrayZipSize", "_ArrayZipData_" % opt: (optional) a list of 'Param',value pairs for additional options % The supported options include % Recursive: [1|0] if set to 1, will apply the conversion to % every child; 0 to disable % Base64: [0|1] if set to 1, _ArrayZipData_ is assumed to % be encoded with base64 format and need to be % decoded first. This is needed for JSON but not % UBJSON data % Prefix: ['x0x5F'|'x'] for JData files loaded via loadjson/loadubjson, the % default JData keyword prefix is 'x0x5F'; if the % json file is loaded using matlab2018's % jsondecode(), the prefix is 'x'; this function % attempts to automatically determine the prefix; % for octave, the default value is an empty string ''. % FullArrayShape: [0|1] if set to 1, converting _ArrayShape_ % objects to full matrices, otherwise, stay sparse % FormatVersion: [2|float]: set the JSONLab output version; % since v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1 % % output: % newdata: the covnerted data if the input data does contain a JData % structure; otherwise, the same as the input. % % examples: % obj={[],{'test'},true,struct('sparse',sparse(2,3),'magic',uint8(magic(5)))} % jdata=jdatadecode(jdataencode(obj)) % isequaln(obj,jdata) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % newdata=data; opt=struct; if(nargin==2) opt=varargin{1}; elseif(nargin>2) opt=varargin2struct(varargin{:}); end opt.fullarrayshape=jsonopt('FullArrayShape',0,opt); %% process non-structure inputs if(~isstruct(data)) if(iscell(data)) newdata=cellfun(@(x) jdatadecode(x,opt),data,'UniformOutput',false); elseif(isa(data,'containers.Map')) newdata=containers.Map('KeyType',data.KeyType,'ValueType','any'); names=data.keys; for i=1:length(names) newdata(names{i})=jdatadecode(data(names{i}),opt); end end return; end %% assume the input is a struct below fn=fieldnames(data); len=length(data); needbase64=jsonopt('Base64',0,opt); format=jsonopt('FormatVersion',2,opt); if(isoctavemesh) prefix=jsonopt('Prefix','',opt); else prefix=jsonopt('Prefix','x0x5F',opt); end if(~isfield(data,N_('_ArrayType_')) && isfield(data,'x_ArrayType_')) prefix='x'; opt.prefix='x'; end %% recursively process subfields if(jsonopt('Recursive',1,opt)==1) for i=1:length(fn) % depth-first for j=1:len if(isstruct(data(j).(fn{i})) || isa(data(j).(fn{i}),'containers.Map')) newdata(j).(fn{i})=jdatadecode(data(j).(fn{i}),opt); elseif(iscell(data(j).(fn{i}))) newdata(j).(fn{i})=cellfun(@(x) jdatadecode(x,opt),newdata(j).(fn{i}),'UniformOutput',false); end end end end %% handle array data if(isfield(data,N_('_ArrayType_')) && (isfield(data,N_('_ArrayData_')) || isfield(data,N_('_ArrayZipData_')))) newdata=cell(len,1); for j=1:len if(isfield(data,N_('_ArrayZipSize_')) && isfield(data,N_('_ArrayZipData_'))) zipmethod='zip'; if(isstruct(data(j).(N_('_ArrayZipSize_')))) data(j).(N_('_ArrayZipSize_'))=jdatadecode(data(j).(N_('_ArrayZipSize_')),opt); end dims=data(j).(N_('_ArrayZipSize_'))(:)'; if(length(dims)==1) dims=[1 dims]; end if(isfield(data,N_('_ArrayZipType_'))) zipmethod=data(j).(N_('_ArrayZipType_')); end if(~isempty(strmatch(zipmethod,{'zlib','gzip','lzma','lzip','lz4','lz4hc'}))) decompfun=str2func([zipmethod 'decode']); arraytype=data(j).(N_('_ArrayType_')); chartype=0; if(strcmp(arraytype,'char') || strcmp(arraytype,'logical')) chartype=1; arraytype='uint8'; end if(needbase64) ndata=reshape(typecast(decompfun(base64decode(data(j).(N_('_ArrayZipData_')))),arraytype),dims); else ndata=reshape(typecast(decompfun(data(j).(N_('_ArrayZipData_'))),arraytype),dims); end if(chartype) ndata=char(ndata); end else error('compression method is not supported'); end else if(isstruct(data(j).(N_('_ArrayData_')))) data(j).(N_('_ArrayData_'))=jdatadecode(data(j).(N_('_ArrayData_')),opt); end if(isstruct(data(j).(N_('_ArrayData_'))) && isfield(data(j).(N_('_ArrayData_')),N_('_ArrayType_'))) data(j).(N_('_ArrayData_'))=jdatadecode(data(j).(N_('_ArrayData_')),varargin{:}); end if(iscell(data(j).(N_('_ArrayData_')))) data(j).(N_('_ArrayData_'))=cell2mat(cellfun(@(x) double(x(:)),data(j).(N_('_ArrayData_')),'uniformoutput',0)).'; end ndata=cast(data(j).(N_('_ArrayData_')),char(data(j).(N_('_ArrayType_')))); end if(isfield(data,N_('_ArrayZipSize_'))) if(isstruct(data(j).(N_('_ArrayZipSize_')))) data(j).(N_('_ArrayZipSize_'))=jdatadecode(data(j).(N_('_ArrayZipSize_')),opt); end dims=data(j).(N_('_ArrayZipSize_'))(:)'; if(iscell(dims)) dims=cell2mat(dims); end if(length(dims)==1) dims=[1 dims]; end ndata=reshape(ndata(:),fliplr(dims)); ndata=permute(ndata,ndims(ndata):-1:1); end iscpx=0; if(isfield(data,N_('_ArrayIsComplex_')) && isstruct(data(j).(N_('_ArrayIsComplex_'))) ) data(j).(N_('_ArrayIsComplex_'))=jdatadecode(data(j).(N_('_ArrayIsComplex_')),opt); end if(isfield(data,N_('_ArrayIsComplex_')) && data(j).(N_('_ArrayIsComplex_')) ) iscpx=1; end iscol=0; if(isfield(data,N_('_ArrayOrder_'))) arrayorder=data(j).(N_('_ArrayOrder_')); if(~isempty(arrayorder) && (arrayorder(1)=='c' || arrayorder(1)=='C')) iscol=1; end end if(isfield(data,N_('_ArrayIsSparse_')) && isstruct(data(j).(N_('_ArrayIsSparse_'))) ) data(j).(N_('_ArrayIsSparse_'))=jdatadecode(data(j).(N_('_ArrayIsSparse_')),opt); end if(isfield(data,N_('_ArrayIsSparse_')) && data(j).(N_('_ArrayIsSparse_'))) if(isfield(data,N_('_ArraySize_'))) if(isstruct(data(j).(N_('_ArraySize_')))) data(j).(N_('_ArraySize_'))=jdatadecode(data(j).(N_('_ArraySize_')),opt); end dim=data(j).(N_('_ArraySize_'))(:)'; if(iscell(dim)) dim=cell2mat(dim); end dim=double(dim); if(length(dim)==1) dim=[1 dim]; end if(iscpx) ndata(end-1,:)=complex(ndata(end-1,:),ndata(end,:)); end if isempty(ndata) % All-zeros sparse ndata=sparse(dim(1),prod(dim(2:end))); elseif dim(1)==1 % Sparse row vector ndata=sparse(1,ndata(1,:),ndata(2,:),dim(1),prod(dim(2:end))); elseif dim(2)==1 % Sparse column vector ndata=sparse(ndata(1,:),1,ndata(2,:),dim(1),prod(dim(2:end))); else % Generic sparse array. ndata=sparse(ndata(1,:),ndata(2,:),ndata(3,:),dim(1),prod(dim(2:end))); end else if(iscpx && size(ndata,2)==4) ndata(3,:)=complex(ndata(3,:),ndata(4,:)); end ndata=sparse(ndata(1,:),ndata(2,:),ndata(3,:)); end elseif(isfield(data,N_('_ArrayShape_'))) if(isstruct(data(j).(N_('_ArrayShape_')))) data(j).(N_('_ArrayShape_'))=jdatadecode(data(j).(N_('_ArrayShape_')),opt); end if(iscpx) if(size(ndata,1)==2) dim=size(ndata); dim(end+1)=1; arraydata=reshape(complex(ndata(1,:),ndata(2,:)),dim(2:end)); else error('The first dimension must be 2 for complex-valued arrays'); end else arraydata=data.(N_('_ArrayData_')); end shapeid=data.(N_('_ArrayShape_')); if(isfield(data,N_('_ArrayZipSize_'))) datasize=data.(N_('_ArrayZipSize_')); if(iscell(datasize)) datasize=cell2mat(datasize); end datasize=double(datasize); if(iscpx) datasize=datasize(2:end); end else datasize=size(arraydata); end if(isstruct(data(j).(N_('_ArraySize_')))) data(j).(N_('_ArraySize_'))=jdatadecode(data(j).(N_('_ArraySize_')),opt); end arraysize=data.(N_('_ArraySize_')); if(iscell(arraysize)) arraysize=cell2mat(arraysize); end arraysize=double(arraysize); if(ischar(shapeid)) shapeid={shapeid}; end arraydata=double(arraydata).'; if(strcmpi(shapeid{1},'diag')) ndata=spdiags(arraydata(:),0,arraysize(1),arraysize(2)); elseif(strcmpi(shapeid{1},'upper') || strcmpi(shapeid{1},'uppersymm')) ndata=zeros(arraysize); ndata(triu(true(size(ndata)))')=arraydata(:); if(strcmpi(shapeid{1},'uppersymm')) ndata(triu(true(size(ndata))))=arraydata(:); end ndata=ndata.'; elseif(strcmpi(shapeid{1},'lower') || strcmpi(shapeid{1},'lowersymm')) ndata=zeros(arraysize); ndata(tril(true(size(ndata)))')=arraydata(:); if(strcmpi(shapeid{1},'lowersymm')) ndata(tril(true(size(ndata))))=arraydata(:); end ndata=ndata.'; elseif(strcmpi(shapeid{1},'upperband') || strcmpi(shapeid{1},'uppersymmband')) if(length(shapeid)>1 && isvector(arraydata)) datasize=double([shapeid{2}+1, prod(datasize)/(shapeid{2}+1)]); end ndata=spdiags(reshape(arraydata,min(arraysize),datasize(1)),-datasize(1)+1:0,arraysize(2),arraysize(1)).'; if(strcmpi(shapeid{1},'uppersymmband')) diagonal=diag(ndata); ndata=ndata+ndata.'; ndata(1:arraysize(1)+1:end)=diagonal; end elseif(strcmpi(shapeid{1},'lowerband') || strcmpi(shapeid{1},'lowersymmband')) if(length(shapeid)>1 && isvector(arraydata)) datasize=double([shapeid{2}+1, prod(datasize)/(shapeid{2}+1)]); end ndata=spdiags(reshape(arraydata,min(arraysize),datasize(1)),0:datasize(1)-1,arraysize(2),arraysize(1)).'; if(strcmpi(shapeid{1},'lowersymmband')) diagonal=diag(ndata); ndata=ndata+ndata.'; ndata(1:arraysize(1)+1:end)=diagonal; end elseif(strcmpi(shapeid{1},'band')) if(length(shapeid)>1 && isvector(arraydata)) datasize=double([shapeid{2}+shapeid{3}+1, prod(datasize)/(shapeid{2}+shapeid{3}+1)]); end ndata=spdiags(reshape(arraydata,min(arraysize),datasize(1)),double(shapeid{2}):-1:-double(shapeid{3}),arraysize(1),arraysize(2)); elseif(strcmpi(shapeid{1},'toeplitz')) arraydata=reshape(arraydata,flipud(datasize(:))'); ndata=toeplitz(arraydata(1:arraysize(1),2),arraydata(1:arraysize(2),1)); end if(opt.fullarrayshape && issparse(ndata)) ndata=cast(full(ndata),data(j).(N_('_ArrayType_'))); end elseif(isfield(data,N_('_ArraySize_'))) if(isstruct(data(j).(N_('_ArraySize_')))) data(j).(N_('_ArraySize_'))=jdatadecode(data(j).(N_('_ArraySize_')),opt); end if(iscpx) ndata=complex(ndata(1,:),ndata(2,:)); end if(format>1.9 && iscol==0) data(j).(N_('_ArraySize_'))=data(j).(N_('_ArraySize_'))(end:-1:1); end dims=data(j).(N_('_ArraySize_'))(:)'; if(iscell(dims)) dims=cell2mat(dims); end if(length(dims)==1) dims=[1 dims]; end ndata=reshape(ndata(:),dims(:)'); if(format>1.9 && iscol==0) ndata=permute(ndata,ndims(ndata):-1:1); end end newdata{j}=ndata; end if(len==1) newdata=newdata{1}; end end %% handle table data if(isfield(data,N_('_TableRecords_'))) newdata=cell(len,1); for j=1:len ndata=data(j).(N_('_TableRecords_')); if(iscell(ndata)) if(iscell(ndata{1})) rownum=length(ndata); colnum=length(ndata{1}); nd=cell(rownum, colnum); for i1=1:rownum for i2=1:colnum nd{i1,i2}=ndata{i1}{i2}; end end newdata{j}=cell2table(nd); else newdata{j}=cell2table(ndata); end else newdata{j}=array2table(ndata); end if(isfield(data(j),N_('_TableRows_'))&& ~isempty(data(j).(N_('_TableRows_')))) newdata{j}.Properties.RowNames=data(j).(N_('_TableRows_'))(:); end if(isfield(data(j),N_('_TableCols_')) && ~isempty(data(j).(N_('_TableCols_')))) newdata{j}.Properties.VariableNames=data(j).(N_('_TableCols_')); end end if(len==1) newdata=newdata{1}; end end %% handle map data if(isfield(data,N_('_MapData_'))) newdata=cell(len,1); for j=1:len key=cell(1,length(data(j).(N_('_MapData_')))); val=cell(size(key)); for k=1:length(data(j).(N_('_MapData_'))) key{k}=data(j).(N_('_MapData_')){k}{1}; val{k}=jdatadecode(data(j).(N_('_MapData_')){k}{2},opt); end ndata=containers.Map(key,val); newdata{j}=ndata; end if(len==1) newdata=newdata{1}; end end %% handle graph data if(isfield(data,N_('_GraphNodes_')) && exist('graph','file') && exist('digraph','file')) newdata=cell(len,1); isdirected=1; for j=1:len nodedata=data(j).(N_('_GraphNodes_')); if(isstruct(nodedata)) nodetable=struct2table(nodedata); elseif(isa(nodedata,'containers.Map')) nodetable=[keys(nodedata);values(nodedata)]; if(strcmp(nodedata.KeyType,'char')) nodetable=table(nodetable(1,:)',nodetable(2,:)','VariableNames',{'Name','Data'}); else nodetable=table(nodetable(2,:)','VariableNames',{'Data'}); end else nodetable=table; end if(isfield(data,N_('_GraphEdges_'))) edgedata=data(j).(N_('_GraphEdges_')); elseif(isfield(data,N_('_GraphEdges0_'))) edgedata=data(j).(N_('_GraphEdges0_')); isdirected=0; elseif(isfield(data,N_('_GraphMatrix_'))) edgedata=jdatadecode(data(j).(N_('_GraphMatrix_')),varargin{:}); end if(exist('edgedata','var')) if(iscell(edgedata)) endnodes=edgedata(:,1:2); endnodes=reshape([endnodes{:}],size(edgedata,1),2); weight=cell2mat(edgedata(:,3:end)); edgetable=table(endnodes,[weight.Weight]','VariableNames',{'EndNodes','Weight'}); if(isdirected) newdata{j}=digraph(edgetable,nodetable); else newdata{j}=graph(edgetable,nodetable); end elseif(ndims(edgedata)==2 && isstruct(nodetable)) newdata{j}=digraph(edgedata,fieldnames(nodetable)); end end end if(len==1) newdata=newdata{1}; end end %% handle bytestream and arbitrary matlab objects if(isfield(data,N_('_ByteStream_')) && isfield(data,N_('_DataInfo_'))==2) newdata=cell(len,1); for j=1:len if(isfield(data(j).(N_('_DataInfo_')),'MATLABObjectClass')) if(needbase64) newdata{j}=getArrayFromByteStream(base64decode(data(j).(N_('_ByteStream_')))); else newdata{j}=getArrayFromByteStream(data(j).(N_('_ByteStream_'))); end end end if(len==1) newdata=newdata{1}; end end %% subfunctions function escaped=N_(str) escaped=[prefix str]; end end jsonlab-2.0/jdataencode.m000066400000000000000000000364341367147361400154500ustar00rootroot00000000000000function jdata=jdataencode(data, varargin) % % jdata=jdataencode(data) % or % jdata=jdataencode(data, options) % jdata=jdataencode(data, 'Param1',value1, 'Param2',value2,...) % % Annotate a MATLAB struct or cell array into a JData-compliant data % structure as defined in the JData spec: http://github.com/fangq/jdata. % This encoded form servers as an intermediate format that allows unambiguous % storage, exchange of complex data structures and easy-to-serialize by % json encoders such as savejson and jsonencode (MATLAB R2016b or newer) % % This function implements the JData Specification Draft 3 (Jun. 2020) % see http://github.com/fangq/jdata for details % % author: Qianqian Fang (q.fang neu.edu) % % input: % data: a structure (array) or cell (array) to be encoded. % options: (optional) a struct or Param/value pairs for user % specified options (first in [.|.] is the default) % AnnotateArray: [0|1] - if set to 1, convert all 1D/2D matrices % to the annotated JData array format to preserve data types; % N-D (N>2), complex and sparse arrays are encoded using the % annotated format by default. Please set this option to 1 if % you intend to use MATLAB's jsonencode to convert to JSON. % Base64: [0|1] if set to 1, _ArrayZipData_ is assumed to % be encoded with base64 format and need to be % decoded first. This is needed for JSON but not % UBJSON data % Prefix: ['x0x5F'|'x'] for JData files loaded via loadjson/loadubjson, the % default JData keyword prefix is 'x0x5F'; if the % json file is loaded using matlab2018's % jsondecode(), the prefix is 'x'; this function % attempts to automatically determine the prefix; % for octave, the default value is an empty string ''. % UseArrayZipSize: [1|0] if set to 1, _ArrayZipSize_ will be added to % store the "pre-processed" data dimensions, i.e. % the original data stored in _ArrayData_, and then flaten % _ArrayData_ into a row vector using row-major % order; if set to 0, a 2D _ArrayData_ will be used % UseArrayShape: [0|1] if set to 1, a matrix will be tested by % to determine if it is diagonal, triangular, banded or % toeplitz, and use _ArrayShape_ to encode the matrix % MapAsStruct: [0|1] if set to 1, convert containers.Map into % struct; otherwise, keep it as map % Compression: ['zlib'|'gzip','lzma','lz4','lz4hc'] - use zlib method % to compress data array % CompressArraySize: [100|int]: only to compress an array if the % total element count is larger than this number. % FormatVersion [2|float]: set the JSONLab output version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % % example: % jd=jdataencode(struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5))) % % encodedmat=jdataencode(single(magic(5)),'annotatearray',1,'prefix','x') % jdatadecode(jsondecode(jsonencode(encodedmat))) % serialize by jsonencode % jdatadecode(loadjson(savejson('',encodedmat))) % serialize by savejson % % encodedtoeplitz=jdataencode(uint8(toeplitz([1,2,3,4],[1,5,6])),'usearrayshape',1,'prefix','x') % jdatadecode(jsondecode(jsonencode(encodedtoeplitz))) % serialize by jsonencode % jdatadecode(loadjson(savejson('',encodedtoeplitz))) % serialize by savejson % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) help jdataencode return; end opt=varargin2struct(varargin{:}); if(isoctavemesh) opt.prefix=jsonopt('Prefix','',opt); else opt.prefix=jsonopt('Prefix',sprintf('x0x%X','_'+0),opt); end opt.compression=jsonopt('Compression','',opt); opt.nestarray=jsonopt('NestArray',0,opt); opt.formatversion=jsonopt('FormatVersion',2,opt); opt.compressarraysize=jsonopt('CompressArraySize',100,opt); opt.base64=jsonopt('Base64',0,opt); opt.mapasstruct=jsonopt('MapAsStruct',0,opt); opt.usearrayzipsize=jsonopt('UseArrayZipSize',1,opt); opt.messagepack=jsonopt('MessagePack',0,opt); opt.usearrayshape=jsonopt('UseArrayShape',0,opt) && exist('bandwidth'); opt.annotatearray=jsonopt('AnnotateArray',0,opt); jdata=obj2jd(data,opt); %%------------------------------------------------------------------------- function newitem=obj2jd(item,varargin) if(iscell(item)) newitem=cell2jd(item,varargin{:}); elseif(isstruct(item)) newitem=struct2jd(item,varargin{:}); elseif(isnumeric(item) || islogical(item)) newitem=mat2jd(item,varargin{:}); elseif(ischar(item) || isa(item,'string')) newitem=mat2jd(item,varargin{:}); elseif(isa(item,'containers.Map')) newitem=map2jd(item,varargin{:}); elseif(isa(item,'categorical')) newitem=cell2jd(cellstr(item),varargin{:}); elseif(isa(item,'function_handle')) newitem=struct2jd(functions(item),varargin{:}); elseif(isa(item,'table')) newitem=table2jd(item,varargin{:}); elseif(isa(item,'digraph') || isa(item,'graph')) newitem=graph2jd(item,varargin{:}); elseif(isobject(item)) newitem=matlabobject2jd(item,varargin{:}); else newitem=item; end %%------------------------------------------------------------------------- function newitem=cell2jd(item,varargin) newitem=cellfun(@(x) obj2jd(x, varargin{:}), item, 'UniformOutput',false); %%------------------------------------------------------------------------- function newitem=struct2jd(item,varargin) num=numel(item); if(num>1) % struct array newitem=obj2jd(num2cell(item),varargin{:}); try newitem=cell2mat(newitem); catch end else % a single struct names=fieldnames(item); newitem=struct; for i=1:length(names) newitem.(names{i})=obj2jd(item.(names{i}),varargin{:}); end end %%------------------------------------------------------------------------- function newitem=map2jd(item,varargin) names=item.keys; if(varargin{1}.mapasstruct) % convert a map to struct newitem=struct; if(~strcmp(item.KeyType,'char')) data=num2cell(reshape([names, item.values],length(names),2),2); for i=1:length(names) data{i}{2}=obj2jd(data{i}{2},varargin{:}); end newitem.(N_('_MapData_',varargin{:}))=data; else for i=1:length(names) newitem.(N_(names{i},varargin{:}))=obj2jd(item(names{i}),varargin{:}); end end else % keep as a map and only encode its values if(strcmp(item.KeyType,'char')) newitem=containers.Map(); else newitem=containers.Map('KeyType',item.KeyType,'ValueType','any'); end for i=1:length(names) newitem(names{i})=obj2jd(item(names{i}),varargin{:}); end end %%------------------------------------------------------------------------- function newitem=mat2jd(item,varargin) N=@(x) N_(x,varargin{:}); newitem=struct(N('_ArrayType_'),class(item),N('_ArraySize_'),size(item)); zipmethod=varargin{1}.compression; minsize=varargin{1}.compressarraysize; % 2d numerical (real/complex/sparse) arrays with _ArrayShape_ encoding enabled if(varargin{1}.usearrayshape && ndims(item)==2 && ~isvector(item)) encoded=1; if(~isreal(item)) newitem.(N('_ArrayIsComplex_'))=true; end symmtag=''; if(isreal(item) && issymmetric(double(item))) symmtag='symm'; item=tril(item); elseif(~isreal(item) && ishermitian(double(item))) symmtag='herm'; item=tril(item); end [lband,uband]=bandwidth(double(item)); newitem.(N('_ArrayZipSize_'))=[lband+uband+1, min(size(item,1),size(item,2))]; if(lband+uband==0) % isdiag newitem.(N('_ArrayShape_'))='diag'; newitem.(N('_ArrayData_'))=diag(item).'; elseif(uband==0 && lband==size(item,1)-1) % lower triangular newitem.(N('_ArrayShape_'))=['lower' symmtag]; item=item.'; newitem.(N('_ArrayData_'))=item(triu(true(size(item)))).'; elseif(lband==0 && uband==size(item,2)-1) % upper triangular newitem.(N('_ArrayShape_'))='upper'; item=item.'; newitem.(N('_ArrayData_'))=item(tril(true(size(item)))).'; elseif(lband==0) % upper band newitem.(N('_ArrayShape_'))={'upperband',uband}; newitem.(N('_ArrayData_'))=spdiags(item.',-uband:lband).'; elseif(uband==0) % lower band newitem.(N('_ArrayShape_'))={sprintf('lower%sband',symmtag),lband}; newitem.(N('_ArrayData_'))=spdiags(item.',-uband:lband).'; elseif(uband1.9) item=permute(item,ndims(item):-1:1); end newitem.(N('_ArrayData_'))=item(:)'; end else newitem.(N('_ArrayIsComplex_'))=true; if(issparse(item)) fulldata=full(item(item~=0)); newitem.(N('_ArrayIsSparse_'))=true; newitem.(N('_ArrayZipSize_'))=[3+(~isvector(item)),length(fulldata)]; if(isvector(item)) newitem.(N('_ArrayData_'))=[find(item(:))', real(fulldata(:))', imag(fulldata(:))']; else [ix,iy]=find(item); newitem.(N('_ArrayData_'))=[ix(:)' , iy(:)' , real(fulldata(:))', imag(fulldata(:))']; end else if(varargin{1}.formatversion>1.9) item=permute(item,ndims(item):-1:1); end newitem.(N('_ArrayZipSize_'))=[2,numel(item)]; newitem.(N('_ArrayData_'))=[real(item(:))', imag(item(:))']; end end if(varargin{1}.usearrayzipsize==0 && isfield(newitem,N('_ArrayZipSize_'))) data=newitem.(N('_ArrayData_')); data=reshape(data,fliplr(newitem.(N('_ArrayZipSize_')))); newitem.(N('_ArrayData_'))=permute(data,ndims(data):-1:1); newitem=rmfield(newitem,N('_ArrayZipSize_')); end if(~isempty(zipmethod) && numel(item)>minsize) compfun=str2func([zipmethod 'encode']); newitem.(N('_ArrayZipType_'))=lower(zipmethod); if(~isfield(newitem,N('_ArrayZipSize_'))) newitem.(N('_ArrayZipSize_'))=size(newitem.(N('_ArrayData_'))); end newitem.(N('_ArrayZipData_'))=compfun(typecast(newitem.(N('_ArrayData_'))(:).','uint8')); newitem=rmfield(newitem,N('_ArrayData_')); if(varargin{1}.base64) newitem.(N('_ArrayZipData_'))=char(base64encode(newitem.(N('_ArrayZipData_')))); end end if(isfield(newitem,N('_ArrayData_')) && isempty(newitem.(N('_ArrayData_')))) newitem.(N('_ArrayData_'))=[]; end %%------------------------------------------------------------------------- function newitem=table2jd(item,varargin) newitem=struct; newitem.(N_('_TableCols_',varargin{:}))=item.Properties.VariableNames; newitem.(N_('_TableRows_',varargin{:}))=item.Properties.RowNames'; newitem.(N_('_TableRecords_',varargin{:}))=table2cell(item); %%------------------------------------------------------------------------- function newitem=graph2jd(item,varargin) newitem=struct; nodedata=table2struct(item.Nodes); if(isfield(nodedata,'Name')) nodedata=rmfield(nodedata,'Name'); newitem.(N_('_GraphNodes_',varargin{:}))=containers.Map(item.Nodes.Name,num2cell(nodedata),'UniformValues',false); else newitem.(N_('_GraphNodes_',varargin{:}))=containers.Map(1:max(item.Edges.EndNodes(:)),num2cell(nodedata),'UniformValues',false); end edgenodes=num2cell(item.Edges.EndNodes); edgedata=table2struct(item.Edges); if(isfield(edgedata,'EndNodes')) edgedata=rmfield(edgedata,'EndNodes'); end edgenodes(:,3)=num2cell(edgedata); if(isa(item,'graph')) if(strcmp(varargin{1}.prefix,'x')) newitem.(genvarname('_GraphEdges0_'))=edgenodes; else newitem.(encodevarname('_GraphEdges0_'))=edgenodes; end else newitem.(N_('_GraphEdges_',varargin{:}))=edgenodes; end %%------------------------------------------------------------------------- function newitem=matlabobject2jd(item,varargin) try if numel(item) == 0 %empty object newitem = struct(); elseif numel(item) == 1 % newitem = char(item); else propertynames = properties(item); for p = 1:numel(propertynames) for o = numel(item):-1:1 % aray of objects newitem(o).(propertynames{p}) = item(o).(propertynames{p}); end end end catch newitem=any2jd(item,varargin{:}); end %%------------------------------------------------------------------------- function newitem=any2jd(item,varargin) N=@(x) N_(x,varargin{:}); newitem.(N('_DataInfo_'))=struct('MATLABObjectClass',class(item),'MATLABObjectSize',size(item)); newitem.(N('_ByteStream_'))=getByteStreamFromArray(item); % use undocumented matlab function if(varargin{1}.base64) newitem.(N('_ByteStream_'))=char(base64encode(newitem.(N('_ByteStream_')))); end %%------------------------------------------------------------------------- function newname=N_(name,varargin) newname=[varargin{1}.prefix name]; jsonlab-2.0/jload.m000066400000000000000000000071701367147361400142730ustar00rootroot00000000000000function varargout=jload(filename, varargin) % % jload % or % jload(fname) % varlist=jload(fname) % [varlist, header]=jload(fname) % varlist=jload(fname,'param1',value1,'param2',value2,...) % % Load variables from a JSON or binary JSON file to a workspace % % authors:Qianqian Fang (q.fang neu.edu) % created on 2020/05/31 % % input: % fname: (optional) input file name; if not given, load 'jamdata.jamm' % if fname has a '.json' or '.jdt' suffix, a text-based % JSON/JData file will be expected; if the suffix is '.jamm' or % '.jdb', a Binary JData file will be expected. % opt: (optional) a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % ws ['caller'|'base']: the name of the workspace in which the % variables are to be saved % vars [{'var1','var2',...}]: list of variables to be saved % header [0|1]: if set to 1, return the metadata of the variables % stored in the file % matlab [0|1] if set to 1, use matlab's built-in jsondecode to % parse the json file and then decode the output by % jdatadecode; input file must have a suffix of .jdt % % all options for loadubjson/loadjson (depends on file suffix) % can be used to adjust the parsing options % % output: % varlist: a struct with each subfield a variable stored in the file, % if output is ignored, the variables will be loaded to the % workspace specified by the 'ws' option, which by default % load the variables to the current workspace ('caller') % % examples: % jload % load all variables in jamdata.jamm to the 'caller' workspace % jload mydat.jamm % jload('mydat.jamm','vars', {'v1','v2',...}) % load selected variables % varlist=jload('mydat.jamm','simplifycell',1) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://openjdata.org/jsonlab) % if(nargin==0) filename=[pwd filesep 'jamdata.jamm']; end opt=varargin2struct(varargin{:}); ws=jsonopt('ws','caller',opt); loadfun=@loadbj; if(regexp(filename,'\.[jJ][sS][oO][nN]$')) loadfun=@loadjson; elseif(regexp(filename,'\.[jJ][dD][tT]$')) loadfun=@loadjson; elseif(regexp(filename,'\.[mM][sS][gG][pP][kK]$')) loadfun=@loadmsgpack; end if(jsonopt('matlab',0,opt) && exist('jsonencode','builtin')) jsonstr=fileread(filename); pos=regexp(jsonstr,'}\n\n\n{"WorkspaceData":','once'); if(isempty(pos)) error('the json file is not generated using matlab''s jsonencode'); end header=jsondecode(jsonstr(1:pos+1)); else header=loadfun(filename,'ObjectID',1, varargin{:}); end allvar=fieldnames(header.WorkspaceHeader); varlist=jsonopt('vars',allvar,opt); varlist(ismember(varlist,encodevarname('_DataInfo_')))=[]; isfound=ismember(varlist,allvar); if(any(isfound==0)) error('specified variable is not found'); end if(jsonopt('matlab',0,opt) && exist('jsonencode','builtin')) body=jdatadecode(jsondecode(jsonstr(pos+4:end))); else body=loadfun(filename,'ObjectID',2, varargin{:}); end if(nargout==0) for i=1:length(varlist) assignin(ws, varlist{i}, body.WorkspaceData.(varlist{i})); end else varargout{1}=rmfield(body.WorkspaceData,setdiff(fieldnames(body.WorkspaceData),varlist)); if(nargout>1) varargout{2}=header; end end jsonlab-2.0/jsave.m000066400000000000000000000077771367147361400143270ustar00rootroot00000000000000function varargout=jsave(filename, varargin) % % jsave % or % jsave(fname) % varlist=jsave(fname,'param1',value1,'param2',value2,...) % % Store variables in a workspace to a JSON or binary JSON file % % authors:Qianqian Fang (q.fang neu.edu) % created on 2020/05/31 % % input: % fname: (optional) output file name; if not given, save to 'jamdata.jamm' % if fname has a '.json' or '.jdt' suffix, a text-based % JSON/JData file will be created (slow); if the suffix is '.jamm' or % '.jdb', a Binary JData (https://github.com/fangq/bjdata/) file will be created. % opt: (optional) a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % ws ['caller'|'base']: the name of the workspace in which the % variables are to be saved % vars [{'var1','var2',...}]: cell array of variable names to be saved % matlab [0|1] if set to 1, use matlab's built-in jsonencode to % store encoded data to a json file; output file % must have a suffix of .jdt % % all options for savebj/savejson (depends on file suffix) % can be used to adjust the output unless "'matlab',1" is used % % output: % varlist: a list of variables loaded % % examples: % jsave % save all variables in the 'caller' workspace to jamdata.jamm % jsave('mydat.jamm','vars', {'v1','v2',...}) % save selected variables % jsave('mydat.jamm','compression','lzma') % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://openjdata.org/jsonlab) % if(nargin==0) filename=[pwd filesep 'jamdata.jamm']; end opt=varargin2struct(varargin{:}); ws=jsonopt('ws','caller',opt); allvar=evalin(ws,'whos'); varlist=jsonopt('vars',{allvar.name},opt); [isfound, dontsave]=ismember(varlist,{allvar.name}); if(any(isfound==0)) error('specified variable is not found'); end header=struct; body=struct; metadata=struct('CreateDate',datestr(now,29),... 'CreateTime',datestr(now,'hh:mm:ss'),... 'OriginalName',filename); vers=ver('MATLAB'); if(isempty(vers)) vers=ver('Octave'); [verstr, releasedate]=version; vers.Release=verstr; vers.Date=releasedate; end metadata.CreatorApp=vers.Name; metadata.CreatorVersion=vers.Version; metadata.CreatorRelease=vers.Release; metadata.ReleaseDate=vers.Date; metadata.FormatVersion=1; metadata.Parameters=opt; header.(encodevarname('_DataInfo_'))=metadata; for i=1:length(varlist) header.(varlist{i})=allvar(dontsave(i)); body.(varlist{i})=evalin(ws,varlist{i}); end savefun=@savebj; if(regexp(filename,'\.[jJ][sS][oO][nN]$')) savefun=@savejson; elseif(regexp(filename,'\.[jJ][dD][tT]$')) savefun=@savejson; elseif(regexp(filename,'\.[mM][sS][gG][pP][kK]$')) savefun=@savemsgpack; end if(nargout==1) varargout{1}=header; end if(jsonopt('matlab',0,opt) && exist('jsonencode','builtin')) if(isempty(regexp(filename,'\.[jJ][sS][oO][nN]$', 'once'))) filename=regexprep(filename,'\.[a-zA-Z]+$','.jdt'); end output.WorkspaceHeader=jdataencode(header,'prefix','x','base64',1,varargin{:}); headerjson=jsonencode(output); clear output; output.WorkspaceData=jdataencode(body,'AnnotateArray',1,'base64',1,... 'Compression','zlib','UseArrayZipSize',1,'MapAsStruct',1,... 'prefix','x',varargin{:}); bodyjson=jsonencode(output); clear output; fid=fopen(filename,jsonopt('writemode','w',opt)); fwrite(fid,headerjson); fwrite(fid,sprintf('\n\n\n')); fwrite(fid,bodyjson); fclose(fid); else savefun('WorkspaceHeader',header,'filename',filename,varargin{:}); savefun('WorkspaceData',body,'filename',filename,'append',1,... 'compression','zlib','keeptype',1,'array2struct',1,varargin{:}); end jsonlab-2.0/jsonlab.prj000066400000000000000000000206671367147361400151770ustar00rootroot00000000000000 jsonlab Qianqian Fang fangqq@gmail.com Northeastern University A native JSON/UBJSON/MassagePack encoder/decoder for MATLAB/Octave JSONLab is a free and open-source implementation of a JSON/UBJSON/MessagePack encoder and a decoder in the native MATLAB language. It can be used to convert a MATLAB data structure (array, struct, cell, struct array, cell array, and objects) into JSON/UBJSON/MessagePack formatted strings, or to decode a JSON/UBJSON/MessagePack file into MATLAB data structure. JSONLab supports both MATLAB and [http://www.gnu.org/software/octave GNU Octave] (a free MATLAB clone). JSON ([http://www.json.org/ JavaScript Object Notation]) is a highly portable, human-readable and [http://en.wikipedia.org/wiki/JSON "fat-free"] text format to represent complex and hierarchical data. It is as powerful as [http://en.wikipedia.org/wiki/XML XML] but less verbose. JSON format is widely used for data-exchange in applications. UBJSON ([http://ubjson.org/ Universal Binary JSON]) is a binary JSON format, specifically optimized for compact file size and better performance while keeping the semantics as simple as the text-based JSON format. Using the UBJSON format allows to wrap complex binary data in a flexible and extensible structure, making it possible to process complex and large dataset without accuracy loss due to text conversions. MessagePack is another binary JSON-like data format widely used in data exchange in web/native applications. It is slightly more compact than UBJSON, but is not directly readable compared to UBJSON. We envision that both JSON and its binary counterparts will play important roles as mainstream data-exchange formats for scientific research. It has both the flexibility and generality as offered by other popular general-purpose file specifications, such as [http://www.hdfgroup.org/HDF5/whatishdf5.html HDF5] but with significantly reduced complexity and excellent readability. Towards this goal, we have developed the JData Specification (http://github.com/fangq/jdata) to standardize serializations of complex scientific data structures, such as N-D arrays, sparse/complex-valued arrays, trees, maps, tables and graphs using JSON/binary JSON constructs. The text and binary formatted JData files are syntactically compatible with JSON/UBJSON formats, and can be readily parsed using existing JSON and UBJSON parsers. Please note that data files produced by `saveubjson` may utilize a special "optimized header" to store N-D (N>1) arrays, as defined in the JData Specification Draft 2. This feature is not supported by UBJSON Specification Draft 12. To produce UBJSON files that can be parsed by UBJSON-Draft-12 compliant parsers, you must add the option `'NestArray',1 ` in the call to `saveubjson`. ${PROJECT_ROOT}/images/jsonlab-logo.png 1.9.8 ${PROJECT_ROOT}/jsonlab.mltbx d1e5cb15-4ada-479a-aafd-24b64efb8455 *.m~ .git* true false false true true true true /drives/taote1/users/fangq/git/Project/jsonlab ${PROJECT_ROOT}/AUTHORS.txt ${PROJECT_ROOT}/ChangeLog.txt ${PROJECT_ROOT}/Contents.m ${PROJECT_ROOT}/DESCRIPTION ${PROJECT_ROOT}/INDEX ${PROJECT_ROOT}/LICENSE_BSD.txt ${PROJECT_ROOT}/LICENSE_GPLv3.txt ${PROJECT_ROOT}/README.rst ${PROJECT_ROOT}/README.txt ${PROJECT_ROOT}/base64decode.m ${PROJECT_ROOT}/base64encode.m ${PROJECT_ROOT}/decodevarname.m ${PROJECT_ROOT}/encodevarname.m ${PROJECT_ROOT}/examples ${PROJECT_ROOT}/fast_match_bracket.m ${PROJECT_ROOT}/gendocs.sh ${PROJECT_ROOT}/genlog.sh ${PROJECT_ROOT}/gzipdecode.m ${PROJECT_ROOT}/gzipencode.m ${PROJECT_ROOT}/isoctavemesh.m ${PROJECT_ROOT}/jdatadecode.m ${PROJECT_ROOT}/jdataencode.m ${PROJECT_ROOT}/images/jsonlab-logo.png ${PROJECT_ROOT}/jsonopt.m ${PROJECT_ROOT}/jsave.m ${PROJECT_ROOT}/jload.m ${PROJECT_ROOT}/savebj.m ${PROJECT_ROOT}/loadbj.m ${PROJECT_ROOT}/loadjson.m ${PROJECT_ROOT}/loadmsgpack.m ${PROJECT_ROOT}/loadubjson.m ${PROJECT_ROOT}/lz4decode.m ${PROJECT_ROOT}/lz4encode.m ${PROJECT_ROOT}/lz4hcdecode.m ${PROJECT_ROOT}/lz4hcencode.m ${PROJECT_ROOT}/lzipdecode.m ${PROJECT_ROOT}/lzipencode.m ${PROJECT_ROOT}/lzmadecode.m ${PROJECT_ROOT}/lzmaencode.m ${PROJECT_ROOT}/match_bracket.m ${PROJECT_ROOT}/mergestruct.m ${PROJECT_ROOT}/nestbracket2dim.m ${PROJECT_ROOT}/package.json ${PROJECT_ROOT}/savejson.m ${PROJECT_ROOT}/savemsgpack.m ${PROJECT_ROOT}/saveubjson.m ${PROJECT_ROOT}/varargin2struct.m ${PROJECT_ROOT}/zlibdecode.m ${PROJECT_ROOT}/zlibencode.m jsonlab.mltbx /pub/MATLAB/R2018a true false false false false false true false 4.15.0-96-generic false true glnxa64 true jsonlab-2.0/jsonopt.m000066400000000000000000000016341367147361400146750ustar00rootroot00000000000000function val=jsonopt(key,default,varargin) % % val=jsonopt(key,default,optstruct) % % setting options based on a struct. The struct can be produced % by varargin2struct from a list of 'param','value' pairs % % authors:Qianqian Fang (q.fang neu.edu) % % input: % key: a string with which one look up a value from a struct % default: if the key does not exist, return default % optstruct: a struct where each sub-field is a key % % output: % val: if key exists, val=optstruct.key; otherwise val=default % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % val=default; if(nargin<=2) return; end key0=lower(key); opt=varargin{1}; if(isstruct(opt)) if(isfield(opt,key0)) val=opt.(key0); elseif(isfield(opt,key)) val=opt.(key); end end jsonlab-2.0/loadbj.m000066400000000000000000000342111367147361400144310ustar00rootroot00000000000000function data = loadbj(fname,varargin) % % data=loadbj(fname,opt) % or % data=loadbj(fname,'param1',value1,'param2',value2,...) % % Parse a Binary JData (BJData v1 Draft-1, defined in https://github.com/OpenJData/bjdata) % file or memory buffer and convert into a MATLAB data structure % % authors:Qianqian Fang (q.fang neu.edu) % initially created on 2013/08/01 % % input: % fname: input file name, if fname contains "{}" or "[]", fname % will be interpreted as a BJData/UBJSON string % opt: a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % SimplifyCell [1|0]: if set to 1, loadbj will call cell2mat % for each element of the JSON data, and group % arrays based on the cell2mat rules. % IntEndian [B|L]: specify the endianness of the integer fields % in the BJData/UBJSON input data. B - Big-Endian format for % integers (as required in the UBJSON specification); % L - input integer fields are in Little-Endian order. % NameIsString [0|1]: for UBJSON Specification Draft 8 or % earlier versions (JSONLab 1.0 final or earlier), % the "name" tag is treated as a string. To load % these UBJSON data, you need to manually set this % flag to 1. % UseMap [0|1]: if set to 1, loadjson uses a containers.Map to % store map objects; otherwise use a struct object % ObjectID [0|interger or list]: if set to a positive number, % it returns the specified JSON object by index % in a multi-JSON document; if set to a vector, % it returns a list of specified objects. % FormatVersion [2|float]: set the JSONLab format version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % % output: % dat: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % % examples: % obj=struct('string','value','array',[1 2 3]); % ubjdata=savebj('obj',obj); % dat=loadbj(ubjdata) % dat=loadbj(['examples' filesep 'example1.bjd']) % dat=loadbj(['examples' filesep 'example1.bjd'],'SimplifyCell',0) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(exist(fname,'file')) fid = fopen(fname,'rb'); string = fread(fid,inf,'uint8=>char')'; fclose(fid); elseif(regexp(fname, '^\s*[\[\{SCHiUIulmLMhdDTFZN]')) string=fname; else error_pos('input file does not exist or buffer is invalid'); end pos = 1; inputlen = length(string); inputstr = string; arraytoken=find(inputstr=='[' | inputstr==']' | inputstr=='"'); jstr=regexprep(inputstr,'\\\\',' '); escquote=regexp(jstr,'\\"'); arraytoken=sort([arraytoken escquote]); opt=varargin2struct(varargin{:}); opt.arraytoken_=arraytoken; opt.simplifycell=jsonopt('SimplifyCell',1,opt); opt.simplifycellarray=jsonopt('SimplifyCellArray',0,opt); opt.usemap=jsonopt('UseMap',0,opt); opt.nameisstring=jsonopt('NameIsString',0,opt); [os,maxelem,systemendian]=computer; opt.flipendian_=(systemendian ~= upper(jsonopt('IntEndian','B',opt))); objid=jsonopt('ObjectID',0,opt); maxobjid=max(objid); if(maxobjid==0) maxobjid=inf; end jsoncount=1; while pos <= inputlen [cc, pos]=next_char(inputstr, pos); switch(cc) case '{' [data{jsoncount}, pos] = parse_object(inputstr, pos, opt); case '[' [data{jsoncount}, pos] = parse_array(inputstr, pos, opt); case {'S','C','H','i','U','I','u','l','m','L','M','h','d','D','T','F','Z','N'} [data{jsoncount}, pos] = parse_value(inputstr, pos, opt); otherwise error_pos('Outer level structure must be an object or an array', inputstr, pos); end if(jsoncount>=maxobjid) break; end jsoncount=jsoncount+1; end % while if(length(objid)>1 || min(objid)>1) data=data(objid(objid<=length(data))); end jsoncount=length(data); if(jsoncount==1 && iscell(data)) data=data{1}; end if(jsonopt('JDataDecode',1,varargin{:})==1) data=jdatadecode(data,'Base64',0,'Recursive',1,varargin{:}); end end %%------------------------------------------------------------------------- %% helper functions %%------------------------------------------------------------------------- function [data, adv]=parse_block(inputstr, pos, type,count,varargin) [cid,len]=elem_info(inputstr, pos, type); datastr=inputstr(pos:pos+len*count-1); newdata=uint8(datastr); %id=strfind('iUIulmLMhdD',type); if(varargin{1}.flipendian_) newdata=swapbytes(typecast(newdata,cid)); end data=typecast(newdata,cid); adv=double(len*count); end %%------------------------------------------------------------------------- function [object, pos] = parse_array(inputstr, pos, varargin) % JSON array is written in row-major order pos=parse_char(inputstr, pos, '['); object = cell(0, 1); dim=[]; type=''; count=-1; [cc,pos]=next_char(inputstr,pos); if(cc == '$') type=inputstr(pos+1); pos=pos+2; end [cc,pos]=next_char(inputstr,pos); if(cc == '#') pos=pos+1; [cc,pos]=next_char(inputstr,pos); if(cc=='[') if(isfield(varargin{1},'noembedding_') && varargin{1}.noembedding_==1) error_pos('ND array size specifier does not support embedding'); end varargin{1}.noembedding_=1; [dim, pos]=parse_array(inputstr, pos, varargin{:}); count=prod(double(dim)); varargin{1}.noembedding_=0; else [val,pos]=parse_number(inputstr,pos, varargin{:}); count=double(val); end end if(~isempty(type)) if(count>=0) [object, adv]=parse_block(inputstr, pos, type,count,varargin{:}); if(~isempty(dim)) object=reshape(object,dim); end pos=pos+adv; return; else endpos=match_bracket(inputstr,pos); [cid,len]=elem_info(inputstr, pos, type); count=(endpos-pos)/len; [object, adv]=parse_block(inputstr, pos, type,count,varargin{:}); pos=pos+adv; pos=parse_char(inputstr, pos, ']'); return; end end [cc,pos]=next_char(inputstr,pos); if cc ~= ']' while 1 [val, pos] = parse_value(inputstr, pos, varargin{:}); object{end+1} = val; [cc,pos]=next_char(inputstr,pos); if cc == ']' break; end end end if(varargin{1}.simplifycell) if(iscell(object) && ~isempty(object) && isnumeric(object{1})) if(all(cellfun(@(e) isequal(size(object{1}), size(e)) , object(2:end)))) try oldobj=object; if(iscell(object) && length(object)>1 && ndims(object{1})>=2) catdim=size(object{1}); catdim=ndims(object{1})-(catdim(end)==1)+1; object=cat(catdim,object{:}); object=permute(object,ndims(object):-1:1); else object=cell2mat(object')'; end if(iscell(oldobj) && isstruct(object) && numel(object)>1 && varargin{1}.simplifycellarray==0) object=oldobj; end catch end end end if(~iscell(object) && size(object,1)>1 && ndims(object)==2) object=object'; end end if(count==-1) pos=parse_char(inputstr, pos, ']'); end end %%------------------------------------------------------------------------- function pos=parse_char(inputstr, pos, c) if pos > length(inputstr) || inputstr(pos) ~= c error_pos(sprintf('Expected %c at position %%d', c),inputstr, pos); else pos = pos + 1; end end %%------------------------------------------------------------------------- function [c, pos] = next_char(inputstr, pos) if pos > length(inputstr) c = []; else c = inputstr(pos); while(c=='N') pos=pos+1; c = inputstr(pos); end end end %%------------------------------------------------------------------------- function [str, pos] = parse_name(inputstr, pos, varargin) [val, pos]=parse_number(inputstr,pos,varargin{:}); bytelen=double(val); if(length(inputstr)>=pos+bytelen-1) str=inputstr(pos:pos+bytelen-1); pos=pos+bytelen; else error_pos('End of file while expecting end of name', inputstr, pos); end end %%------------------------------------------------------------------------- function [str, pos] = parseStr(inputstr, pos, varargin) type=inputstr(pos); if type ~= 'S' && type ~= 'C' && type ~= 'H' error_pos('String starting with S expected at position %d',inputstr, pos); else pos = pos + 1; end if(type == 'C') str=inputstr(pos); pos=pos+1; return; end [val, pos]=parse_number(inputstr,pos,varargin{:}); bytelen=double(val); if(length(inputstr)>=pos+bytelen-1) str=inputstr(pos:pos+bytelen-1); pos=pos+bytelen; else error_pos('End of file while expecting end of inputstr',inputstr, pos); end end %%------------------------------------------------------------------------- function [num, pos] = parse_number(inputstr, pos, varargin) id=strfind('iUIulmLMhdD',inputstr(pos)); if(isempty(id)) error_pos('expecting a number at position %d',inputstr, pos); end type={'int8','uint8','int16','uint16','int32','uint32','int64','uint64','half','single','double'}; bytelen=[1,1,2,2,4,4,8,8,2,4,8]; if(~exist('half','builtin')) type{9}='uint16'; end datastr=inputstr(pos+1:pos+bytelen(id)); newdata=uint8(datastr); if(varargin{1}.flipendian_) newdata=swapbytes(typecast(newdata,type{id})); end num=typecast(newdata,type{id}); pos = pos + bytelen(id)+1; end %%------------------------------------------------------------------------- function [val, pos] = parse_value(inputstr, pos, varargin) [cc,pos]=next_char(inputstr,pos); switch(cc) case {'S','C','H'} [val, pos] = parseStr(inputstr, pos, varargin{:}); return; case '[' [val, pos] = parse_array(inputstr, pos, varargin{:}); return; case '{' [val, pos] = parse_object(inputstr, pos, varargin{:}); return; case {'i','U','I','u','l','m','L','M','h','d','D'} [val, pos] = parse_number(inputstr, pos, varargin{:}); return; case 'T' val = true; pos = pos + 1; return; case 'F' val = false; pos = pos + 1; return; case {'Z','N'} val = []; pos = pos + 1; return; end error_pos('Value expected at position %d', inputstr, pos); end %%------------------------------------------------------------------------- function pos=error_pos(msg, inputstr, pos) poShow = max(min([pos-15 pos-1 pos pos+20],length(inputstr)),1); if poShow(3) == poShow(2) poShow(3:4) = poShow(2)+[0 -1]; % display nothing after end msg = [sprintf(msg, pos) ': ' ... inputstr(poShow(1):poShow(2)) '' inputstr(poShow(3):poShow(4)) ]; error( ['JSONLAB:BJData:InvalidFormat: ' msg] ); end %%------------------------------------------------------------------------- function [object, pos] = parse_object(inputstr, pos, varargin) pos=parse_char(inputstr,pos,'{'); usemap=varargin{1}.usemap; if(usemap) object = containers.Map(); else object = []; end count=-1; [cc, pos]=next_char(inputstr,pos); if(cc == '$') pos=pos+2; end [cc, pos]=next_char(inputstr,pos); if(cc == '#') pos=pos+1; [val,pos]=parse_number(inputstr, pos, varargin{:}); count=double(val); end [cc, pos]=next_char(inputstr,pos); if cc ~= '}' num=0; while 1 if(varargin{1}.nameisstring) [str, pos] = parseStr(inputstr, pos, varargin{:}); else [str, pos] = parse_name(inputstr, pos, varargin{:}); end if isempty(str) error_pos('Name of value at position %d cannot be empty', inputstr, pos); end [val, pos] = parse_value(inputstr, pos, varargin{:}); num=num+1; if(usemap) object(str)=val; else object.(encodevarname(str,varargin{:}))=val; end [cc, pos]=next_char(inputstr,pos); if cc == '}' || (count>=0 && num>=count) break; end end end if(count==-1) pos=parse_char(inputstr, pos, '}'); end end %%------------------------------------------------------------------------- function [cid,len]=elem_info(inputstr, pos, type) id=strfind('iUIulmLMhdD',type); type={'int8','uint8','int16','uint16','int32','uint32','int64','uint64','half','single','double'}; bytelen=[1,1,2,2,4,4,8,8,2,4,8]; if(~exist('half','builtin')) type{9}='uint16'; end if(id>0) cid=type{id}; len=bytelen(id); else error_pos('unsupported type at position %d',inputstr, pos); end end jsonlab-2.0/loadjson.m000066400000000000000000000521441367147361400150140ustar00rootroot00000000000000function data = loadjson(fname,varargin) % % data=loadjson(fname,opt) % or % data=loadjson(fname,'param1',value1,'param2',value2,...) % % parse a JSON (JavaScript Object Notation) file or string % % authors:Qianqian Fang (q.fang neu.edu) % created on 2011/09/09, including previous works from % % Nedialko Krouchev: http://www.mathworks.com/matlabcentral/fileexchange/25713 % created on 2009/11/02 % François Glineur: http://www.mathworks.com/matlabcentral/fileexchange/23393 % created on 2009/03/22 % Joel Feenstra: % http://www.mathworks.com/matlabcentral/fileexchange/20565 % created on 2008/07/03 % % input: % fname: input file name; if fname contains "{}" or "[]", fname % will be interpreted as a JSON string % opt: (optional) a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. opt can have the following % fields (first in [.|.] is the default) % % SimplifyCell [1|0]: if set to 1, loadjson will call cell2mat % for each element of the JSON data, and group % arrays based on the cell2mat rules. % FastArrayParser [1|0 or integer]: if set to 1, use a % speed-optimized array parser when loading an % array object. The fast array parser may % collapse block arrays into a single large % array similar to rules defined in cell2mat; 0 to % use a legacy parser; if set to a larger-than-1 % value, this option will specify the minimum % dimension to enable the fast array parser. For % example, if the input is a 3D array, setting % FastArrayParser to 1 will return a 3D array; % setting to 2 will return a cell array of 2D % arrays; setting to 3 will return to a 2D cell % array of 1D vectors; setting to 4 will return a % 3D cell array. % UseMap [0|1]: if set to 1, loadjson uses a containers.Map to % store map objects; otherwise use a struct object % ShowProgress [0|1]: if set to 1, loadjson displays a progress bar. % ParseStringArray [0|1]: if set to 0, loadjson converts "string arrays" % (introduced in MATLAB R2016b) to char arrays; if set to 1, % loadjson skips this conversion. % FormatVersion [2|float]: set the JSONLab format version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % Encoding ['']: json file encoding. Support all encodings of % fopen() function % ObjectID [0|interger or list]: if set to a positive number, % it returns the specified JSON object by index % in a multi-JSON document; if set to a vector, % it returns a list of specified objects. % JDataDecode [1|0]: if set to 1, call jdatadecode to decode % JData structures defined in the JData % Specification. % % output: % dat: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % % examples: % dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}') % dat=loadjson(['examples' filesep 'example1.json']) % dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',0) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % opt=varargin2struct(varargin{:}); if(regexp(fname,'^\s*(?:\[.*\])|(?:\{.*\})\s*$','once')) string=fname; elseif(exist(fname,'file')) try encoding = jsonopt('Encoding','',opt); if(isempty(encoding)) string = fileread(fname); else fid = fopen(fname,'r','n',encoding); string = fread(fid,'*char')'; fclose(fid); end catch try string = urlread(['file://',fname]); catch string = urlread(['file://',fullfile(pwd,fname)]); end end else error_pos('input file does not exist'); end pos = 1; inputlen = length(string); inputstr = string; arraytokenidx=find(inputstr=='[' | inputstr==']'); arraytoken=inputstr(arraytokenidx); % String delimiters and escape chars identified to improve speed: esc = find(inputstr=='"' | inputstr=='\' ); % comparable to: regexp(inputstr, '["\\]'); index_esc = 1; opt.arraytoken_=arraytoken; opt.arraytokenidx_=arraytokenidx; opt.simplifycell=jsonopt('SimplifyCell',1,opt); opt.simplifycellarray=jsonopt('SimplifyCellArray',0,opt); opt.formatversion=jsonopt('FormatVersion',2,opt); opt.fastarrayparser=jsonopt('FastArrayParser',1,opt); opt.parsestringarray=jsonopt('ParseStringArray',0,opt); opt.usemap=jsonopt('UseMap',0,opt); opt.arraydepth_=1; if(jsonopt('ShowProgress',0,opt)==1) opt.progressbar_=waitbar(0,'loading ...'); end objid=jsonopt('ObjectID',0,opt); maxobjid=max(objid); if(maxobjid==0) maxobjid=inf; end jsoncount=1; while pos <= inputlen [cc,pos]=next_char(inputstr, pos); switch(cc) case '{' [data{jsoncount},pos,index_esc] = parse_object(inputstr, pos, esc, index_esc,opt); case '[' [data{jsoncount},pos,index_esc] = parse_array(inputstr, pos, esc, index_esc,opt); otherwise pos=error_pos('Outer level structure must be an object or an array',inputstr,pos); end if(jsoncount>=maxobjid) break; end jsoncount=jsoncount+1; end % while if(length(objid)>1 || min(objid)>1) data=data(objid(objid<=length(data))); end jsoncount=length(data); if(jsoncount==1 && iscell(data)) data=data{1}; end if(jsonopt('JDataDecode',1,varargin{:})==1) data=jdatadecode(data,'Base64',1,'Recursive',1,varargin{:}); end if(isfield(opt,'progressbar_')) close(opt.progressbar_); end end %%------------------------------------------------------------------------- %% helper functions %%------------------------------------------------------------------------- function [object, pos,index_esc] = parse_array(inputstr, pos, esc, index_esc, varargin) % JSON array is written in row-major order pos=parse_char(inputstr, pos, '['); object = cell(0, 1); arraydepth=varargin{1}.arraydepth_; pbar=-1; if(isfield(varargin{1},'progressbar_')) pbar=varargin{1}.progressbar_; end format=varargin{1}.formatversion; [cc,pos]=next_char(inputstr,pos); endpos=[]; if cc ~= ']' try if((varargin{1}.fastarrayparser)>=1 && arraydepth>=varargin{1}.fastarrayparser) [endpos, maxlevel]=fast_match_bracket(varargin{1}.arraytoken_,varargin{1}.arraytokenidx_,pos); if(~isempty(endpos)) arraystr=['[' inputstr(pos:endpos)]; arraystr=sscanf_prep(arraystr); if(isempty(find(arraystr=='"', 1))) % handle 1D array first if(maxlevel==1) astr=arraystr(2:end-1); astr(astr==' ')=''; [obj, count, errmsg, nextidx]=sscanf(astr,'%f,',[1,inf]); if(nextidx>=length(astr)-1) object=obj; pos=endpos; pos=parse_char(inputstr, pos, ']'); return; end end % next handle 2D array, these are most common ones if(maxlevel==2 && ~isempty(regexp(arraystr(2:end),'^\s*\[','once'))) rowstart=find(arraystr(2:end)=='[',1)+1; if(rowstart) [obj, nextidx]=parse2darray(inputstr,pos+rowstart,arraystr); if(nextidx>=length(arraystr)-1) object=obj; if(format>1.9) object=object.'; end pos=endpos; pos=parse_char(inputstr, pos, ']'); if(pbar>0) waitbar(pos/length(inStr),pbar,'loading ...'); end return; end end end % for N-D packed array in a nested array construct, % in the future can replace 1d and 2d cases if(maxlevel>2 && ~isempty(regexp(arraystr(2:end),'^\s*\[\s*\[','once'))) astr=arraystr; dims=nestbracket2dim(astr); if(any(dims==0) || all(mod(dims(:),1) == 0)) % all dimensions are integers - this can be problematic astr=arraystr; astr(astr=='[')=''; astr(astr==']')=''; astr=regexprep(astr,'\s*,',','); astr=regexprep(astr,'\s*$',''); [obj, count, errmsg, nextidx]=sscanf(astr,'%f,',inf); if(nextidx>=length(astr)-1) object=reshape(obj,dims); if(format>1.9) object=permute(object,ndims(object):-1:1); end pos=endpos; pos=parse_char(inputstr, pos, ']'); if(pbar>0) waitbar(pos/length(inStr),pbar,'loading ...'); end return; end end end end end end if(isempty(regexp(arraystr,':','once'))) arraystr=regexprep(arraystr,'\[','{'); arraystr=regexprep(arraystr,'\]','}'); if(varargin{1}.parsestringarray==0) arraystr=regexprep(arraystr,'\"',''''); end object=eval(arraystr); if(iscell(object)) object=cellfun(@unescapejsonstring,object,'UniformOutput',false); end pos=endpos; end catch end if(isempty(endpos) || pos~=endpos) while 1 varargin{1}.arraydepth_=arraydepth+1; [val, pos,index_esc] = parse_value(inputstr, pos, esc, index_esc,varargin{:}); object{end+1} = val; [cc,pos]=next_char(inputstr,pos); if cc == ']' break; end pos=parse_char(inputstr, pos, ','); end end end if(varargin{1}.simplifycell) if(iscell(object) && ~isempty(object) && isnumeric(object{1})) if(all(cellfun(@(e) isequal(size(object{1}), size(e)) , object(2:end)))) try oldobj=object; if(iscell(object) && length(object)>1 && ndims(object{1})>=2) catdim=size(object{1}); catdim=ndims(object{1})-(catdim(end)==1)+1; object=cat(catdim,object{:}); object=permute(object,ndims(object):-1:1); else object=cell2mat(object')'; end if(iscell(oldobj) && isstruct(object) && numel(object)>1 && varargin{1}.simplifycellarray==0) object=oldobj; end catch end end end if(~iscell(object) && size(object,1)>1 && ndims(object)==2) object=object'; end end pos=parse_char(inputstr, pos, ']'); if(pbar>0) waitbar(pos/length(inputstr),pbar,'loading ...'); end end %%------------------------------------------------------------------------- function pos=parse_char(inputstr, pos, c) pos=skip_whitespace(pos, inputstr); if pos > length(inputstr) || inputstr(pos) ~= c pos=error_pos(sprintf('Expected %c at position %%d', c),inputstr,pos); else pos = pos + 1; pos=skip_whitespace(pos, inputstr); end end %%------------------------------------------------------------------------- function [c, pos] = next_char(inputstr, pos) pos=skip_whitespace(pos, inputstr); if pos > length(inputstr) c = []; else c = inputstr(pos); end end %%------------------------------------------------------------------------- function [str, pos,index_esc] = parseStr(inputstr, pos, esc, index_esc, varargin) if inputstr(pos) ~= '"' pos=error_pos('String starting with " expected at position %d',inputstr,pos); else pos = pos + 1; end str = ''; while pos <= length(inputstr) while index_esc <= length(esc) && esc(index_esc) < pos index_esc = index_esc + 1; end if index_esc > length(esc) str = [str inputstr(pos:end)]; pos = length(inputstr) + 1; break; else str = [str inputstr(pos:esc(index_esc)-1)]; pos = esc(index_esc); end nstr = length(str); switch inputstr(pos) case '"' pos = pos + 1; if(~isempty(str)) if(strcmp(str,'_Inf_')) str=Inf; elseif(strcmp(str,'-_Inf_')) str=-Inf; elseif(strcmp(str,'_NaN_')) str=NaN; end end return; case '\' if pos+1 > length(inputstr) pos=error_pos('End of file reached right after escape character',inputstr,pos); end pos = pos + 1; switch inputstr(pos) case {'"' '\' '/'} str(nstr+1) = inputstr(pos); pos = pos + 1; case {'b' 'f' 'n' 'r' 't'} str(nstr+1) = sprintf(['\' inputstr(pos)]); pos = pos + 1; case 'u' if pos+4 > length(inputstr) pos=error_pos('End of file reached in escaped unicode character',inputstr,pos); end str(nstr+(1:6)) = inputstr(pos-1:pos+4); pos = pos + 5; end otherwise % should never happen str(nstr+1) = inputstr(pos); keyboard; pos = pos + 1; end end str=unescapejsonstring(str); pos=error_pos('End of file while expecting end of inputstr',inputstr,pos); end %%------------------------------------------------------------------------- function [num, pos] = parse_number(inputstr, pos, varargin) currstr=inputstr(pos:min(pos+30,end)); [num, one, err, delta] = sscanf(currstr, '%f', 1); if ~isempty(err) pos=error_pos('Error reading number at position %d',inputstr,pos); end pos = pos + delta-1; end %%------------------------------------------------------------------------- function [val, pos,index_esc] = parse_value(inputstr, pos, esc, index_esc, varargin) len=length(inputstr); if(isfield(varargin{1},'progressbar_')) waitbar(pos/len,varargin{1}.progressbar_,'loading ...'); end switch(inputstr(pos)) case '"' [val, pos,index_esc] = parseStr(inputstr, pos, esc, index_esc,varargin{:}); return; case '[' [val, pos,index_esc] = parse_array(inputstr, pos, esc, index_esc, varargin{:}); return; case '{' [val, pos,index_esc] = parse_object(inputstr, pos, esc, index_esc, varargin{:}); return; case {'-','0','1','2','3','4','5','6','7','8','9'} [val, pos] = parse_number(inputstr, pos, varargin{:}); return; case 't' if pos+3 <= len && strcmpi(inputstr(pos:pos+3), 'true') val = true; pos = pos + 4; return; end case 'f' if pos+4 <= len && strcmpi(inputstr(pos:pos+4), 'false') val = false; pos = pos + 5; return; end case 'n' if pos+3 <= len && strcmpi(inputstr(pos:pos+3), 'null') val = []; pos = pos + 4; return; end end pos=error_pos('Value expected at position %d',inputstr,pos); end %%------------------------------------------------------------------------- function [object, pos, index_esc] = parse_object(inputstr, pos, esc, index_esc, varargin) pos=parse_char(inputstr, pos, '{'); usemap=varargin{1}.usemap; if(usemap) object = containers.Map(); else object = []; end [cc,pos]=next_char(inputstr,pos); if cc ~= '}' while 1 [str, pos, index_esc] = parseStr(inputstr, pos, esc, index_esc, varargin{:}); if isempty(str) pos=error_pos('Name of value at position %d cannot be empty',inputstr,pos); end pos=parse_char(inputstr, pos, ':'); [val, pos,index_esc] = parse_value(inputstr, pos, esc, index_esc, varargin{:}); if(usemap) object(str)=val; else object.(encodevarname(str,varargin{:}))=val; end [cc,pos]=next_char(inputstr,pos); if cc == '}' break; end pos=parse_char(inputstr, pos, ','); end end pos=parse_char(inputstr, pos, '}'); end %%------------------------------------------------------------------------- function pos=error_pos(msg, inputstr, pos) poShow = max(min([pos-15 pos-1 pos pos+20],length(inputstr)),1); if poShow(3) == poShow(2) poShow(3:4) = poShow(2)+[0 -1]; % display nothing after end msg = [sprintf(msg, pos) ': ' ... inputstr(poShow(1):poShow(2)) '' inputstr(poShow(3):poShow(4)) ]; error( ['JSONLAB:JSON:InvalidFormat: ' msg] ); end %%------------------------------------------------------------------------- function newpos=skip_whitespace(pos, inputstr) newpos=pos; while newpos <= length(inputstr) && isspace(inputstr(newpos)) newpos = newpos + 1; end end %%------------------------------------------------------------------------- function newstr=unescapejsonstring(str) newstr=str; if(iscell(str)) try newstr=cell2mat(cellfun(@(x) cell2mat(x),str(:),'un',0)); catch end end if(~ischar(str)) return; end escapechars={'\\','\"','\/','\a','\b','\f','\n','\r','\t','\v'}; for i=1:length(escapechars); newstr=regexprep(newstr,regexprep(escapechars{i},'\\','\\\\'), escapechars{i}); end newstr=regexprep(newstr,'\\u([0-9A-Fa-f]{4})', '${char(base2dec($1,16))}'); end %%------------------------------------------------------------------------- function arraystr=sscanf_prep(str) arraystr=str; if(regexp(str,'"','once')) arraystr=regexprep(arraystr,'"_NaN_"','NaN'); arraystr=regexprep(arraystr,'"([-+]*)_Inf_"','$1Inf'); end arraystr(arraystr==sprintf('\n'))=[]; arraystr(arraystr==sprintf('\r'))=[]; end %%------------------------------------------------------------------------- function [obj, nextidx,nextdim]=parse2darray(inputstr,startpos,arraystr) rowend=match_bracket(inputstr,startpos); rowstr=sscanf_prep(inputstr(startpos-1:rowend)); [vec1, nextdim, errmsg, nextidx]=sscanf(rowstr,'%f,',[1 inf]); if(nargin==2) obj=nextdim; return; end astr=arraystr; astr(astr=='[')=''; astr(astr==']')=''; astr=regexprep(deblank(astr),'\s+,',','); [obj, count, errmsg, nextidx]=sscanf(astr,'%f,',inf); if(nextidx>=length(astr)-1) obj=reshape(obj,nextdim,numel(obj)/nextdim); nextidx=length(arraystr)+1; end end jsonlab-2.0/loadmsgpack.m000066400000000000000000000210011367147361400154540ustar00rootroot00000000000000function data = loadmsgpack(fname,varargin) % % data = loadmsgpack(fname,varargin) % %LOADMSGPACK parses a msgpack byte buffer into Matlab data structures % LOADMSGPACK(BYTES) % reads BYTES as msgpack data, and creates Matlab data structures % from it. % - strings are converted to strings % - numbers are converted to appropriate numeric values % - true, false are converted to logical 1, 0 % - nil is converted to [] % - arrays are converted to cell arrays % - maps are converted to containers.Map % % (c) 2016 Bastian Bechtold % modified by Qianqian Fang % % license: % BSD 3-clause license or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(exist(fname,'file')) fid = fopen(fname,'rb'); bytes = fread(fid,inf,'uint8=>char')'; fclose(fid); else bytes=fname; end opt=varargin2struct(varargin{:}); opt.simplifycell=jsonopt('SimplifyCell',1,opt); opt.simplifycellarray=jsonopt('SimplifyCellArray',0,opt); jsoncount=1; idx=0; while idx <= length(bytes) [obj, idx] = parse(uint8(bytes(:)), 1, opt); data{jsoncount}=obj; jsoncount=jsoncount+1; end jsoncount=length(data); if(jsoncount==1 && iscell(data)) data=data{1}; end if(iscell(data)) data=cellfun(@(x) jdatadecode(x),data,'UniformOutput',false); elseif(isstruct(data)) data=jdatadecode(data,'Base64',0, opt); end end function [obj, idx] = parse(bytes, idx, varargin) % masks: b10000000 = 128; b01111111 = 127; b11000000 = 192; b00111111 = 63; b11100000 = 224; b00011111 = 31; b11110000 = 240; b00001111 = 15; % values: b00000000 = 0; b10010000 = 144; b10100000 = 160; currentbyte = bytes(idx); if bitand(b10000000, currentbyte) == b00000000 % decode positive fixint obj = int8(currentbyte); idx = idx + 1; return elseif bitand(b11100000, currentbyte) == b11100000 % decode negative fixint obj = typecast(currentbyte, 'int8'); idx = idx + 1; return elseif bitand(b11110000, currentbyte) == b10000000 % decode fixmap len = double(bitand(b00001111, currentbyte)); [obj, idx] = parsemap(len, bytes, idx+1, varargin{:}); return elseif bitand(b11110000, currentbyte) == b10010000 % decode fixarray len = double(bitand(b00001111, currentbyte)); [obj, idx] = parsearray(len, bytes, idx+1, varargin{:}); return elseif bitand(b11100000, currentbyte) == b10100000 % decode fixstr len = double(bitand(b00011111, currentbyte)); [obj, idx] = parsestring(len, bytes, idx + 1); return end switch currentbyte case 192 % nil obj = []; idx = idx+1; % case 193 % unused case 194 % false obj = false; idx = idx+1; case 195 % true obj = true; idx = idx+1; case 196 % bin8 len = double(bytes(idx+1)); [obj, idx] = parsebytes(len, bytes, idx+2); case 197 % bin16 len = double(bytes2scalar(bytes(idx+1:idx+2), 'uint16')); [obj, idx] = parsebytes(len, bytes, idx+3); case 198 % bin32 len = double(bytes2scalar(bytes(idx+1:idx+4), 'uint32')); [obj, idx] = parsebytes(len, bytes, idx+5); case 199 % ext8 len = double(bytes(idx+1)); [obj, idx] = parseext(len, bytes, idx+1); case 200 % ext16 len = double(bytes2scalar(bytes(idx+1:idx+2), 'uint16')); [obj, idx] = parseext(len, bytes, idx+3); case 201 % ext32 len = double(bytes2scalar(bytes(idx+1:idx+4), 'uint32')); [obj, idx] = parseext(len, bytes, idx+5); case 202 % float32 obj = bytes2scalar(bytes(idx+1:idx+4), 'single'); idx = idx+5; case 203 % float64 obj = bytes2scalar(bytes(idx+1:idx+8), 'double'); idx = idx+9; case 204 % uint8 obj = bytes(idx+1); idx = idx+2; case 205 % uint16 obj = bytes2scalar(bytes(idx+1:idx+2), 'uint16'); idx = idx+3; case 206 % uint32 obj = bytes2scalar(bytes(idx+1:idx+4), 'uint32'); idx = idx+5; case 207 % uint64 obj = bytes2scalar(bytes(idx+1:idx+8), 'uint64'); idx = idx+9; case 208 % int8 obj = bytes2scalar(bytes(idx+1), 'int8'); idx = idx+2; case 209 % int16 obj = bytes2scalar(bytes(idx+1:idx+2), 'int16'); idx = idx+3; case 210 % int32 obj = bytes2scalar(bytes(idx+1:idx+4), 'int32'); idx = idx+5; case 211 % int64 obj = bytes2scalar(bytes(idx+1:idx+8), 'int64'); idx = idx+9; case 212 % fixext1 [obj, idx] = parseext(1, bytes, idx+1); case 213 % fixext2 [obj, idx] = parseext(2, bytes, idx+1); case 214 % fixext4 [obj, idx] = parseext(4, bytes, idx+1); case 215 % fixext8 [obj, idx] = parseext(8, bytes, idx+1); case 216 % fixext16 [obj, idx] = parseext(16, bytes, idx+1); case 217 % str8 len = double(bytes(idx+1)); [obj, idx] = parsestring(len, bytes, idx+2); case 218 % str16 len = double(bytes2scalar(bytes(idx+1:idx+2), 'uint16')); [obj, idx] = parsestring(len, bytes, idx+3); case 219 % str32 len = double(bytes2scalar(bytes(idx+1:idx+4), 'uint32')); [obj, idx] = parsestring(len, bytes, idx+5); case 220 % array16 len = double(bytes2scalar(bytes(idx+1:idx+2), 'uint16')); [obj, idx] = parsearray(len, bytes, idx+3, varargin{:}); case 221 % array32 len = double(bytes2scalar(bytes(idx+1:idx+4), 'uint32')); [obj, idx] = parsearray(len, bytes, idx+5, varargin{:}); case 222 % map16 len = double(bytes2scalar(bytes(idx+1:idx+2), 'uint16')); [obj, idx] = parsemap(len, bytes, idx+3, varargin{:}); case 223 % map32 len = double(bytes2scalar(bytes(idx+1:idx+4), 'uint32')); [obj, idx] = parsemap(len, bytes, idx+5, varargin{:}); otherwise error('JSONLAB:MSGPACK:InvalidFormat', ... ['Unknown type "' dec2bin(currentbyte) '"']); end end function value = bytes2scalar(bytes, type) % reverse byte order to convert from little-endian to big-endian value = typecast(bytes(end:-1:1), type); end function [str, idx] = parsestring(len, bytes, idx) if(~isoctavemesh) str = native2unicode(bytes(idx:idx+len-1)', 'utf-8'); else str = char(bytes(idx:idx+len-1)'); end idx = idx + len; end function [out, idx] = parsebytes(len, bytes, idx) out = bytes(idx:idx+len-1); idx = idx + len; end function [out, idx] = parseext(len, bytes, idx) obj.type = bytes(idx); obj.data = bytes(idx+1:idx+len); idx = idx + len + 1; end function [out, idx] = parsearray(len, bytes, idx, varargin) out = cell(1,len); for n=1:len [out{n}, idx] = parse(bytes, idx, varargin{:}); end if(len==1) out=out{1}; end if(varargin{1}.simplifycell) if(iscell(out) && ~isempty(out) && isnumeric(out{1})) if(all(cellfun(@(e) isequal(size(out{1}), size(e)) , out(2:end)))) try oldobj=out; if(iscell(out) && length(out)>1 && ndims(out{1})>=2) catdim=size(out{1}); catdim=ndims(out{1})-(catdim(end)==1)+1; out=cat(catdim,out{:}); out=permute(out,ndims(out):-1:1); else out=cell2mat(out')'; end if(iscell(oldobj) && isstruct(out) && numel(out)>1 && varargin{1}.simplifycellarray==0) out=oldobj; end catch end end end if(~iscell(out) && size(out,2)>1 && ndims(out)==2) out=out'; end end end function [out, idx] = parsemap(len, bytes, idx, varargin) out = struct(); for n=1:len [key, idx] = parse(bytes, idx, varargin{:}); [out.(encodevarname(char(key))), idx] = parse(bytes, idx, varargin{:}); end end jsonlab-2.0/loadubjson.m000066400000000000000000000025301367147361400153350ustar00rootroot00000000000000function varargout = loadubjson(varargin) % % data=loadubjson(fname,opt) % or % data=loadubjson(fname,'param1',value1,'param2',value2,...) % % Parse a UBJSON file or string and store the output into a MATLAB variable % % author: Qianqian Fang (q.fang neu.edu) % initially created on 2019/06/08 % % This function is an alias to loadbj % % input: % fname: input file name, if fname contains "{}" or "[]", fname % will be interpreted as a UBJSON string % opt: a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivallent % to a field in opt. The supported options can be found by typing % "help loadbj". % % output: % data: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % % examples: % obj=struct('string','value','array',[1 2 3]); % ubjdata=saveubjson('obj',obj); % dat=loadubjson(ubjdata) % dat=loadubjson(['examples' filesep 'example1.ubj']) % dat=loadubjson(['examples' filesep 'example1.ubj'],'SimplifyCell',0) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % [varargout{1:nargout}]=loadbj(varargin{:}); jsonlab-2.0/lz4decode.m000066400000000000000000000026511367147361400150560ustar00rootroot00000000000000function varargout = lz4decode(varargin) % % output = lz4decode(input) % or % output = lz4decode(input,info) % % Decompressing an LZ4-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store LZ4-compressed data % info (optional): a struct produced by the zmat/lz4encode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lz4encode(eye(10)); % orig=lz4decode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) if(nargin>1) [varargout{1:nargout}]=zmat(varargin{1},varargin{2:end}); else [varargout{1:nargout}]=zmat(varargin{1},0,'lz4',varargin{2:end}); end else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/lz4encode.m000066400000000000000000000022041367147361400150620ustar00rootroot00000000000000function varargout = lz4encode(varargin) % % output = lz4encode(input) % or % [output, info] = lz4encode(input) % % Compress a string or a numerical array using LZ4-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lz4encode(eye(10)); % orig=lz4decode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) [varargout{1:nargout}]=zmat(varargin{1}, 1,'lz4',varargin{2:end}); return; else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/lz4hcdecode.m000066400000000000000000000026731367147361400153750ustar00rootroot00000000000000function varargout = lz4hcdecode(varargin) % % output = lz4hcdecode(input) % or % output = lz4hcdecode(input,info) % % Decompressing an LZ4HC-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store LZ4HC-compressed data % info (optional): a struct produced by the zmat/lz4hcencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lz4hcencode(eye(10)); % orig=lz4hcdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) if(nargin>1) [varargout{1:nargout}]=zmat(varargin{1},varargin{2:end}); else [varargout{1:nargout}]=zmat(varargin{1},0,'lz4hc',varargin{2:end}); end else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/lz4hcencode.m000066400000000000000000000022221367147361400153750ustar00rootroot00000000000000function varargout = lz4hcencode(varargin) % % output = lz4hcencode(input) % or % [output, info] = lz4hcencode(input) % % Compress a string or a numerical array using LZ4HC-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lz4hcencode(eye(10)); % orig=lz4hcdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) [varargout{1:nargout}]=zmat(varargin{1}, 1,'lz4hc',varargin{2:end}); return; else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/lzipdecode.m000066400000000000000000000026621367147361400153250ustar00rootroot00000000000000function varargout = lzipdecode(varargin) % % output = lzipdecode(input) % or % output = lzipdecode(input,info) % % Decompressing an Lzip-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store Lzip-compressed data % info (optional): a struct produced by the zmat/lzipencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lzipencode(eye(10)); % orig=lzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) if(nargin>1) [varargout{1:nargout}]=zmat(varargin{1},varargin{2:end}); else [varargout{1:nargout}]=zmat(varargin{1},0,'lzip',varargin{2:end}); end else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/lzipencode.m000066400000000000000000000022131367147361400153270ustar00rootroot00000000000000function varargout = lzipencode(varargin) % % output = lzipencode(input) % or % [output, info] = lzipencode(input) % % Compress a string or a numerical array using LZip-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lzipencode(eye(10)); % orig=lzipdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) [varargout{1:nargout}]=zmat(varargin{1}, 1,'lzip',varargin{2:end}); return; else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/lzmadecode.m000066400000000000000000000026621367147361400153120ustar00rootroot00000000000000function varargout = lzmadecode(varargin) % % output = lzmadecode(input) % or % output = lzmadecode(input,info) % % Decompressing an LZMA-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store LZMA-compressed data % info (optional): a struct produced by the zmat/lzmaencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=lzmaencode(eye(10)); % orig=lzmadecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) if(nargin>1) [varargout{1:nargout}]=zmat(varargin{1},varargin{2:end}); else [varargout{1:nargout}]=zmat(varargin{1},0,'lzma',varargin{2:end}); end else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/lzmaencode.m000066400000000000000000000022131367147361400153140ustar00rootroot00000000000000function varargout = lzmaencode(varargin) % % output = lzmaencode(input) % or % [output, info] = lzmaencode(input) % % Compress a string or a numerical array using LZMA-compression % % This function depends on the ZMat toolbox (http://github.com/fangq/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the compressed byte stream stored in a uint8 vector % info: (optional) a struct storing the metadata of the input, see "help zmat" for details % % examples: % [bytes, info]=lzmaencode(eye(10)); % orig=lzmadecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) [varargout{1:nargout}]=zmat(varargin{1}, 1,'lzma',varargin{2:end}); return; else error('you must install ZMat toolbox to use this feature: http://github.com/fangq/zmat') end jsonlab-2.0/match_bracket.m000066400000000000000000000036731367147361400157750ustar00rootroot00000000000000function [endpos, maxlevel] = match_bracket(str,startpos,brackets) % % [endpos, maxlevel] = match_bracket(str,startpos,brackets) % % Looking for the position of a closing bracket token in a string % % authors:Qianqian Fang (q.fang neu.edu) % % input: % str: the full string to be searched % startpos: the index in the string as the start position to search; the % startpos must be at least 1 greater than the opening bracket position % brackets: (optional), a string of length 2, with the first character % being the opening token and the 2nd being the closing token. % if not given, brackets is set to '[]' to find matching square-brackets; % for example, '{}' looks for a matching closing curly-bracket in % the string key(pos(startpos,:end)) % % output: % endpos: if a matching bracket is found, return its position in the original % string % maxlevel: return the depth of the enclosed brackets between the searched pair, % includig the searching pair. For example, the matching closing-bracket % of the 1st square bracket (startpos=2) in '[[[]],[]]' returns a % position of 9, with a maximum depth of 3; searching for the closing % bracket for the 2nd square bracket (startpos=3) returns a position of % 5 and max-depth of 2. % % example: % str='[[ [1,2], 1], 10, [5,10] ]'; % [p1,dep]=match_bracket(str,3) % [p2,dep]=match_bracket(str,2) % [p3,dep]=match_bracket(str,3) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin<3) brackets='[]'; end count = str(startpos:end); flag=cumsum(count==brackets(1))-cumsum(count==brackets(2))+1; endpos = find(flag==0,1); maxlevel=max(flag(1:endpos)); endpos = endpos + startpos-1; jsonlab-2.0/mergestruct.m000066400000000000000000000013621367147361400155430ustar00rootroot00000000000000function s=mergestruct(s1,s2) % % s=mergestruct(s1,s2) % % merge two struct objects into one % % authors:Qianqian Fang (q.fang neu.edu) % date: 2012/12/22 % % input: % s1,s2: a struct object, s1 and s2 can not be arrays % % output: % s: the merged struct object. fields in s1 and s2 will be combined in s. % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(~isstruct(s1) || ~isstruct(s2)) error('input parameters contain non-struct'); end if(length(s1)>1 || length(s2)>1) error('can not merge struct arrays'); end fn=fieldnames(s2); s=s1; for i=1:length(fn) s.(fn{i})=s2.(fn{i}); end jsonlab-2.0/nestbracket2dim.m000066400000000000000000000045431367147361400162640ustar00rootroot00000000000000function [dims, maxlevel, count] = nestbracket2dim(str,brackets) % % [dims, maxlevel, count] = nestbracket2dim(str,brackets) % % Extracting the dimension vector of a JSON string formatted array % by analyzing the pairs of opening/closing bracket tokenss; this function % only returns valid dimension information when the array is an N-D array % % authors:Qianqian Fang (q.fang neu.edu) % % input: % str: a string-formatted JSON array using square-brackets for enclosing % elements and comma as separators between elements % brackets: (optional), a string of length 2, with the first character % being the opening token and the 2nd being the closing token. % if not given, brackets is set to '[]' to find matching square-brackets; % for example, '{}' looks for a matching closing curly-bracket in % the string key(pos(startpos,:end)) % % output: % dims: the speculated dimension vector with the length matching the maximum % depth of the embedded bracket pairs. When the input string encodes an % N-D array, the dims vector contains all integers; however, returning % an all-integer dims vector does not mean the array is rectangular. % maxlevel: return the depth of the enclosed brackets in the string, i.e. the % length of the dims vector. % count: the relative depth from the level 0 - scanning from the left % to right of the string, an opening token increases the level by 1 % and a closing token decreases the level by 1; a zero indicates % the positions of a matching bracket of the same level. % % example: % str='[[ [1,2,3], [4,2,1]], [ [10,1,0], [2,5,10]] ]'; % an N-D array % [dim,dep]=nestbracket2dim(str) % str='[[ [1,2,3], [4,2,1]], [ [10,1,0], [2,5]] ]'; % an invalid N-D array % [dim,dep]=nestbracket2dim(str) % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin<2) brackets='[]'; end str=str(str==brackets(1) | str==brackets(2) | str==','); count=cumsum(str==brackets(1)) - cumsum(str==brackets(2)); maxlevel=max(count); dims=histc(count,1:maxlevel); dims(1:end-1)=dims(1:end-1)*0.5; dims(2:end)=dims(2:end)./dims(1:end-1); dims=fliplr(dims); jsonlab-2.0/package.json000066400000000000000000000010301367147361400152770ustar00rootroot00000000000000{ "name": "jsonlab", "version": "2.0.0", "description": "An open-source MATLAB/Octave JSON encoder and decoder", "directories": { "example": "examples" }, "scripts": { "test": "test/run_jsonlab_test.m" }, "repository": { "type": "git", "url": "git+https://github.com/fangq/jsonlab.git" }, "author": "Qianqian Fang ", "license": "GPL-3.0-only OR BSD-3-Clause", "bugs": { "url": "https://github.com/fangq/jsonlab/issues" }, "homepage": "https://openjdata.org/jsonlab/" } jsonlab-2.0/savebj.m000066400000000000000000001022261367147361400144520ustar00rootroot00000000000000function json=savebj(rootname,obj,varargin) % % bjd=savebj(obj) % or % bjd=savebj(rootname,obj,filename) % bjd=savebj(rootname,obj,opt) % bjd=savebj(rootname,obj,'param1',value1,'param2',value2,...) % % Convert a MATLAB object (cell, struct, array, table, map, handles ...) % into a Binary JData (BJData v1 Draft-1), Universal Binary JSON (UBJSON, % Draft-12) or a MessagePack binary stream % % author: Qianqian Fang (q.fang neu.edu) % initially created on 2013/08/17 % % By default, this function creates BJD-compliant output. The BJD % specification is largely similar to UBJSON, with additional data types % including uint16(u), uint32(m), uint64(M) and half-precision float (h) % % Format specifications: % Binary JData (BJD): https://github.com/fangq/bjdata % UBJSON: https://github.com/ubjson/universal-binary-json % MessagePack: https://github.com/msgpack/msgpack % % input: % rootname: the name of the root-object, when set to '', the root name % is ignored, however, when opt.ForceRootName is set to 1 (see below), % the MATLAB variable name will be used as the root name. % obj: a MATLAB object (array, cell, cell array, struct, struct array, % class instance) % filename: a string for the file name to save the output UBJSON data % opt: a struct for additional options, ignore to use default values. % opt can have the following fields (first in [.|.] is the default) % % FileName [''|string]: a file name to save the output JSON data % ArrayToStruct[0|1]: when set to 0, savebj outputs 1D/2D % array in JSON array format; if sets to 1, an % array will be shown as a struct with fields % "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for % sparse arrays, the non-zero elements will be % saved to "_ArrayData_" field in triplet-format i.e. % (ix,iy,val) and "_ArrayIsSparse_":true will be added % with a value of 1; for a complex array, the % "_ArrayData_" array will include two rows % (4 for sparse) to record the real and imaginary % parts, and also "_ArrayIsComplex_":true is added. % Other annotations include "_ArrayShape_" and % "_ArrayOrder_", "_ArrayZipLevel_" etc. % NestArray [0|1]: If set to 1, use nested array constructs % to store N-dimensional arrays (compatible with % UBJSON specification Draft 12); if set to 0, % use the JData (v0.5) optimized N-D array header; % NestArray is automatically set to 1 when % MessagePack is set to 1 % ParseLogical [1|0]: if this is set to 1, logical array elem % will use true/false rather than 1/0. % SingletArray [0|1]: if this is set to 1, arrays with a single % numerical element will be shown without a square % bracket, unless it is the root object; if 0, square % brackets are forced for any numerical arrays. % SingletCell [1|0]: if 1, always enclose a cell with "[]" % even it has only one element; if 0, brackets % are ignored when a cell has only 1 element. % ForceRootName [0|1]: when set to 1 and rootname is empty, savebj % will use the name of the passed obj variable as the % root object name; if obj is an expression and % does not have a name, 'root' will be used; if this % is set to 0 and rootname is empty, the root level % will be merged down to the lower level. % JSONP [''|string]: to generate a JSONP output (JSON with padding), % for example, if opt.JSON='foo', the JSON data is % wrapped inside a function call as 'foo(...);' % UnpackHex [1|0]: conver the 0x[hex code] output by loadjson % back to the string form % Compression 'zlib', 'gzip', 'lzma', 'lzip', 'lz4' or 'lz4hc': specify array % compression method; currently only supports 6 methods. The % data compression only applicable to numerical arrays % in 3D or higher dimensions, or when ArrayToStruct % is 1 for 1D or 2D arrays. If one wants to % compress a long string, one must convert % it to uint8 or int8 array first. The compressed % array uses three extra fields % "_ArrayZipType_": the opt.Compression value. % "_ArrayZipSize_": a 1D interger array to % store the pre-compressed (but post-processed) % array dimensions, and % "_ArrayZipData_": the binary stream of % the compressed binary array data WITHOUT % 'base64' encoding % CompressArraySize [100|int]: only to compress an array if the total % element count is larger than this number. % CompressStringSize [400|int]: only to compress a string if the total % element count is larger than this number. % MessagePack [0|1]: output MessagePack (https://msgpack.org/) % binary stream instead of BJD/UBJSON % UBJSON [0|1]: 0: (default)-encode data based on BJData Draft 1 % (supports uint16(u)/uint32(m)/uint64(M)/half(h) markers) % 1: encode data based on UBJSON Draft 12 (without % u/m/M/h markers) % FormatVersion [2|float]: set the JSONLab output version; since % v2.0, JSONLab uses JData specification Draft 3 % for output format, it is incompatible with releases % older than v1.9.8; if old output is desired, % please set FormatVersion to 1.9 or earlier. % KeepType [0|1]: if set to 1, use the original data type to store % integers instead of converting to the integer type % of the minimum length without losing accuracy (default) % Debug [0|1]: output binary numbers in <%g> format for debugging % Append [0|1]: if set to 1, append a new object at the end of the file. % Endian ['n'|'b','l']: Endianness of the output file ('n': native, % 'b': big endian, 'l': little-endian) % PreEncode [1|0]: if set to 1, call jdataencode first to preprocess % the input data before saving % % opt can be replaced by a list of ('param',value) pairs. The param % string is equivallent to a field in opt and is case sensitive. % output: % bjd: a binary string in the UBJSON format (see http://ubjson.org) % % examples: % jsonmesh=struct('MeshVertex3',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... % 'MeshTet4',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... % 'MeshTri3',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... % 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... % 'MeshCreator','FangQ','MeshTitle','T6 Cube',... % 'SpecialData',[nan, inf, -inf]); % savebj(jsonmesh) % savebj('',jsonmesh,'meshdata.bjd') % savebj('mesh1',jsonmesh,'FileName','meshdata.msgpk','MessagePack',1) % savebj('',jsonmesh,'ubjson',1) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==1) varname=inputname(1); obj=rootname; rootname=varname; else varname=inputname(2); end if(length(varargin)==1 && ischar(varargin{1})) opt=struct('filename',varargin{1}); else opt=varargin2struct(varargin{:}); end opt.isoctave=isoctavemesh; opt.compression=jsonopt('Compression','',opt); opt.nestarray=jsonopt('NestArray',0,opt); opt.formatversion=jsonopt('FormatVersion',2,opt); opt.compressarraysize=jsonopt('CompressArraySize',100,opt); opt.compressstringsize=jsonopt('CompressStringSize',opt.compressarraysize*4,opt); opt.singletcell=jsonopt('SingletCell',1,opt); opt.singletarray=jsonopt('SingletArray',0,opt); opt.arraytostruct=jsonopt('ArrayToStruct',0,opt); opt.debug=jsonopt('Debug',0,opt); opt.messagepack=jsonopt('MessagePack',0,opt); opt.num2cell_=0; opt.ubjson=bitand(jsonopt('UBJSON',0,opt), ~opt.messagepack); opt.keeptype=jsonopt('KeepType',0,opt); opt.nosubstruct_=0; if(jsonopt('PreEncode',1,opt)) obj=jdataencode(obj,'Base64',0,'UseArrayZipSize',opt.messagepack,opt); end dozip=opt.compression; if(~isempty(dozip)) if(isempty(strmatch(dozip,{'zlib','gzip','lzma','lzip','lz4','lz4hc'}))) error('compression method "%s" is not supported',dozip); end if(exist('zmat','file')~=2 && exist('zmat','file')~=3) try error(javachk('jvm')); try base64decode('test'); catch matlab.net.base64decode('test'); end catch error('java-based compression is not supported'); end end end if(~opt.messagepack) if(~opt.ubjson) opt.IM_='UiuImlML'; opt.IType_={'uint8','int8','uint16','int16','uint32','int32','uint64','int64'}; opt.IByte_=[1,1,2,2,4,4,8,8]; opt.FM_='hdD'; opt.FType_={'half','single','double'}; opt.FByte_=[2,4,8]; else opt.IM_='UiIlL'; opt.IType_={'uint8','int8','int16','int32','int64'}; opt.IByte_=[1,1,2,4,8]; opt.FM_='IdD'; opt.FType_={'int16','single','double'}; opt.FByte_=[2,4,8]; end opt.FTM_='FT'; opt.SM_='CS'; opt.ZM_='Z'; opt.OM_={'{','}'}; opt.AM_={'[',']'}; else opt.IM_=char([hex2dec('cc') hex2dec('d0') hex2dec('cd') hex2dec('d1') hex2dec('ce') hex2dec('d2') hex2dec('cf') hex2dec('d3')]); opt.IType_={'uint8','int8','uint16','int16','uint32','int32','uint64','int64'}; opt.IByte_=[1,1,2,2,4,4,8,8]; opt.FM_=char([hex2dec('cd') hex2dec('ca') hex2dec('cb')]); % MsgPack does not have half-precision, map to uint16 opt.FType_={'int16','single','double'}; opt.FByte_=[2,4,8]; opt.FTM_=char([hex2dec('c2') hex2dec('c3')]); opt.SM_=char([hex2dec('a1') hex2dec('db')]); opt.ZM_=char(hex2dec('c0')); opt.OM_={char(hex2dec('df')),''}; opt.AM_={char(hex2dec('dd')),''}; end rootisarray=0; rootlevel=1; forceroot=jsonopt('ForceRootName',0,opt); if((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || ... iscell(obj) || isobject(obj)) && isempty(rootname) && forceroot==0) rootisarray=1; rootlevel=0; else if(isempty(rootname)) rootname=varname; end end if((isstruct(obj) || iscell(obj))&& isempty(rootname) && forceroot) rootname='root'; end json=obj2ubjson(rootname,obj,rootlevel,opt); if(~rootisarray) if(opt.messagepack) json=[char(129) json opt.OM_{2}]; else json=[opt.OM_{1} json opt.OM_{2}]; end end jsonp=jsonopt('JSONP','',opt); if(~isempty(jsonp)) json=[jsonp '(' json ')']; end % save to a file if FileName is set, suggested by Patrick Rapin filename=jsonopt('FileName','',opt); if(~isempty(filename)) encoding = jsonopt('Encoding','',opt); endian = jsonopt('Endian','n',opt); writemode='w'; if(jsonopt('Append',0,opt)) writemode='a'; end if(~exist('OCTAVE_VERSION','builtin')) fid = fopen(filename, writemode, endian, encoding); else fid = fopen(filename, writemode, endian); end fwrite(fid,json); fclose(fid); end %%------------------------------------------------------------------------- function txt=obj2ubjson(name,item,level,varargin) if(iscell(item) || isa(item,'string')) txt=cell2ubjson(name,item,level,varargin{:}); elseif(isstruct(item)) txt=struct2ubjson(name,item,level,varargin{:}); elseif(isnumeric(item) || islogical(item)) txt=mat2ubjson(name,item,level,varargin{:}); elseif(ischar(item)) if(numel(item)>=varargin{1}.compressstringsize) txt=mat2ubjson(name,item,level,varargin{:}); else txt=str2ubjson(name,item,level,varargin{:}); end elseif(isa(item,'function_handle')) txt=struct2ubjson(name,functions(item),level,varargin{:}); elseif(isa(item,'containers.Map')) txt=map2ubjson(name,item,level,varargin{:}); elseif(isa(item,'categorical')) txt=cell2ubjson(name,cellstr(item),level,varargin{:}); elseif(isa(item,'table')) txt=matlabtable2ubjson(name,item,level,varargin{:}); elseif(isa(item,'graph') || isa(item,'digraph')) txt=struct2ubjson(name,jdataencode(item),level,varargin{:}); elseif(isobject(item)) txt=matlabobject2ubjson(name,item,level,varargin{:}); else txt=any2ubjson(name,item,level,varargin{:}); end %%------------------------------------------------------------------------- function txt=cell2ubjson(name,item,level,varargin) txt=''; if(~iscell(item) && ~isa(item,'string')) error('input is not a cell'); end isnum2cell=varargin{1}.num2cell_; if(isnum2cell) item=squeeze(item); else format=varargin{1}.formatversion; if(format>1.9 && ~isvector(item)) item=permute(item,ndims(item):-1:1); end end dim=size(item); if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now item=reshape(item,dim(1),numel(item)/dim(1)); dim=size(item); end bracketlevel=~varargin{1}.singletcell; Zmarker=varargin{1}.ZM_; Imarker=varargin{1}.IM_; Amarker=varargin{1}.AM_; if(~strcmp(Amarker{1},'[')) am0=Imsgpk_(dim(2),220,144,varargin{:}); else am0=Amarker{1}; end len=numel(item); % let's handle 1D cell first if(len>bracketlevel) if(~isempty(name)) txt=[N_(decodevarname(name,varargin{:}),varargin{:}) am0]; name=''; else txt=am0; end elseif(len==0) if(~isempty(name)) txt=[N_(decodevarname(name,varargin{:}),varargin{:}) Zmarker]; name=''; else txt=Zmarker; end end if(~strcmp(Amarker{1},'[')) am0=Imsgpk_(dim(1),220,144,varargin{:}); end for j=1:dim(2) if(dim(1)>1) txt=[txt am0]; end for i=1:dim(1) txt=[txt char(obj2ubjson(name,item{i,j},level+(len>bracketlevel),varargin{:}))]; end if(dim(1)>1) txt=[txt Amarker{2}]; end end if(len>bracketlevel) txt=[txt Amarker{2}]; end %%------------------------------------------------------------------------- function txt=struct2ubjson(name,item,level,varargin) txt=''; if(~isstruct(item)) error('input is not a struct'); end dim=size(item); if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now item=reshape(item,dim(1),numel(item)/dim(1)); dim=size(item); end len=numel(item); forcearray= (len>1 || (varargin{1}.singletarray==1 && level>0)); Imarker=varargin{1}.IM_; Amarker=varargin{1}.AM_; Omarker=varargin{1}.OM_; if(isfield(item,encodevarname('_ArrayType_',varargin{:}))) varargin{1}.nosubstruct_=1; end if(~strcmp(Amarker{1},'[')) am0=Imsgpk_(dim(2),220,144,varargin{:}); else am0=Amarker{1}; end if(~isempty(name)) if(forcearray) txt=[N_(decodevarname(name,varargin{:}),varargin{:}) am0]; end else if(forcearray) txt=am0; end end if(~strcmp(Amarker{1},'[')) am0=Imsgpk_(dim(1),220,144,varargin{:}); end for j=1:dim(2) if(dim(1)>1) txt=[txt am0]; end for i=1:dim(1) names = fieldnames(item(i,j)); if(~strcmp(Omarker{1},'{')) om0=Imsgpk_(length(names),222,128,varargin{:}); else om0=Omarker{1}; end if(~isempty(name) && len==1 && ~forcearray) txt=[txt N_(decodevarname(name,varargin{:}),varargin{:}) om0]; else txt=[txt om0]; end if(~isempty(names)) for e=1:length(names) txt=[txt obj2ubjson(names{e},item(i,j).(names{e}),... level+(dim(1)>1)+1+forcearray,varargin{:})]; end end txt=[txt Omarker{2}]; end if(dim(1)>1) txt=[txt Amarker{2}]; end end if(forcearray) txt=[txt Amarker{2}]; end %%------------------------------------------------------------------------- function txt=map2ubjson(name,item,level,varargin) txt=''; if(~isa(item,'containers.Map')) error('input is not a struct'); end dim=size(item); names = keys(item); val= values(item); Omarker=varargin{1}.OM_; if(~strcmp(Omarker{1},'{')) om0=Imsgpk_(length(names),222,128,varargin{:}); else om0=Omarker{1}; end len=prod(dim); forcearray= (len>1 || (varargin{1}.singletarray==1 && level>0)); if(~isempty(name)) if(forcearray) txt=[N_(decodevarname(name,varargin{:}),varargin{:}) om0]; end else if(forcearray) txt=om0; end end for i=1:dim(1) if(~isempty(names{i})) txt=[txt obj2ubjson(names{i},val{i},... level+(dim(1)>1),varargin{:})]; end end if(forcearray) txt=[txt Omarker{2}]; end %%------------------------------------------------------------------------- function txt=str2ubjson(name,item,level,varargin) txt=''; if(~ischar(item)) error('input is not a string'); end item=reshape(item, max(size(item),[1 0])); len=size(item,1); Amarker=varargin{1}.AM_; if(~strcmp(Amarker{1},'[')) am0=Imsgpk_(len,220,144,varargin{:}); else am0=Amarker{1}; end if(~isempty(name)) if(len>1) txt=[N_(decodevarname(name,varargin{:}),varargin{:}) am0]; end else if(len>1) txt=am0; end end for e=1:len val=item(e,:); if(len==1) obj=[N_(decodevarname(name,varargin{:}),varargin{:}) '' '',S_(val,varargin{:}),'']; if(isempty(name)) obj=['',S_(val,varargin{:}),'']; end txt=[txt,'',obj]; else txt=[txt,'',['',S_(val,varargin{:}),'']]; end end if(len>1) txt=[txt Amarker{2}]; end %%------------------------------------------------------------------------- function txt=mat2ubjson(name,item,level,varargin) if(~isnumeric(item) && ~islogical(item) && ~ischar(item)) error('input is not an array'); end dozip=varargin{1}.compression; zipsize=varargin{1}.compressarraysize; format=varargin{1}.formatversion; Zmarker=varargin{1}.ZM_; FTmarker=varargin{1}.FTM_; Imarker=varargin{1}.IM_; Omarker=varargin{1}.OM_; isnest=varargin{1}.nestarray; ismsgpack=varargin{1}.messagepack; opt=varargin{1}; if(ismsgpack) isnest=1; end if(~varargin{1}.nosubstruct_ && ((length(size(item))>2 && isnest==0) || ... issparse(item) || ~isreal(item) || varargin{1}.arraytostruct || ... (~isempty(dozip) && numel(item)>zipsize)) ) cid=I_(uint32(max(size(item))),varargin{:}); if(isempty(name)) txt=[Omarker{1} N_('_ArrayType_',opt),S_(class(item),opt),N_('_ArraySize_',opt),I_a(size(item),cid(1),varargin{:}) ]; else if(isempty(item)) txt=[N_(decodevarname(name,varargin{:}),opt),Zmarker]; return; else txt=[N_(decodevarname(name,varargin{:}),opt),Omarker{1},N_('_ArrayType_',opt),S_(class(item),opt),N_('_ArraySize_',opt),I_a(size(item),cid(1),varargin{:})]; end end childcount=2; else if(isempty(name)) txt=matdata2ubjson(item,level+1,varargin{:}); else if(numel(item)==1 && varargin{1}.singletarray==0) numtxt=matdata2ubjson(item,level+1,varargin{:}); txt=[N_(decodevarname(name,varargin{:}),opt) char(numtxt)]; else txt=[N_(decodevarname(name,varargin{:}),opt),char(matdata2ubjson(item,level+1,varargin{:}))]; end end return; end if(issparse(item)) [ix,iy]=find(item); data=full(item(find(item))); if(~isreal(item)) data=[real(data(:)),imag(data(:))]; if(size(item,1)==1) % Kludge to have data's 'transposedness' match item's. % (Necessary for complex row vector handling below.) data=data'; end txt=[txt,N_('_ArrayIsComplex_',opt),FTmarker(2)]; childcount=childcount+1; end txt=[txt,N_('_ArrayIsSparse_',opt),FTmarker(2)]; childcount=childcount+1; if(~isempty(dozip) && numel(data*2)>zipsize) if(size(item,1)==1) % Row vector, store only column indices. fulldata=[iy(:),data']; elseif(size(item,2)==1) % Column vector, store only row indices. fulldata=[ix,data]; else % General case, store row and column indices. fulldata=[ix,iy,data]; end cid=I_(uint32(max(size(fulldata))),varargin{:}); txt=[txt, N_('_ArrayZipSize_',opt),I_a(size(fulldata),cid(1),varargin{:})]; txt=[txt, N_('_ArrayZipType_',opt),S_(dozip,opt)]; compfun=str2func([dozip 'encode']); txt=[txt,N_('_ArrayZipData_',opt), I_a(compfun(typecast(fulldata(:),'uint8')),Imarker(1),varargin{:})]; childcount=childcount+3; else if(size(item,1)==1) % Row vector, store only column indices. fulldata=[iy(:),data']; elseif(size(item,2)==1) % Column vector, store only row indices. fulldata=[ix,data]; else % General case, store row and column indices. fulldata=[ix,iy,data]; end if(ismsgpack) cid=I_(uint32(max(size(fulldata))),varargin{:}); txt=[txt,N_('_ArrayZipSize_',opt),I_a(size(fulldata),cid(1),varargin{:})]; childcount=childcount+1; end varargin{:}.ArrayToStruct=0; txt=[txt,N_('_ArrayData_',opt),... cell2ubjson('',num2cell(fulldata',2)',level+2,varargin{:})]; childcount=childcount+1; end else if(format>1.9) item=permute(item,ndims(item):-1:1); end if(~isempty(dozip) && numel(item)>zipsize) if(isreal(item)) fulldata=item(:)'; if(islogical(fulldata) || ischar(fulldata)) fulldata=uint8(fulldata); end else txt=[txt,N_('_ArrayIsComplex_',opt),FTmarker(2)]; childcount=childcount+1; fulldata=[real(item(:)) imag(item(:))]; end cid=I_(uint32(max(size(fulldata))),varargin{:}); txt=[txt, N_('_ArrayZipSize_',opt),I_a(size(fulldata),cid(1),varargin{:})]; txt=[txt, N_('_ArrayZipType_',opt),S_(dozip,opt)]; compfun=str2func([dozip 'encode']); txt=[txt,N_('_ArrayZipData_',opt), I_a(compfun(typecast(fulldata(:),'uint8')),Imarker(1),varargin{:})]; childcount=childcount+3; else if(ismsgpack) cid=I_(uint32(length(item(:))),varargin{:}); txt=[txt,N_('_ArrayZipSize_',opt),I_a([~isreal(item)+1 length(item(:))],cid(1),varargin{:})]; childcount=childcount+1; end if(isreal(item)) txt=[txt,N_('_ArrayData_',opt),... matdata2ubjson(item(:)',level+2,varargin{:})]; childcount=childcount+1; else txt=[txt,N_('_ArrayIsComplex_',opt),FTmarker(2)]; txt=[txt,N_('_ArrayData_',opt),... matdata2ubjson([real(item(:)) imag(item(:))]',level+2,varargin{:})]; childcount=childcount+2; end end end if(Omarker{1}~='{') idx=find(txt==Omarker{1},1,'first'); if(~isempty(idx)) txt=[txt(1:idx-1) Imsgpk_(childcount,222,128,varargin{:}) txt(idx+1:end)]; end end txt=[txt,Omarker{2}]; %%------------------------------------------------------------------------- function txt=matlabtable2ubjson(name,item,level,varargin) st=containers.Map(); st('_TableRecords_')=table2cell(item); st('_TableRows_')=item.Properties.RowNames'; st('_TableCols_')=item.Properties.VariableNames; if(isempty(name)) txt=map2ubjson(name,st,level,varargin{:}); else temp=struct(name,struct()); temp.(name)=st; txt=map2ubjson(name,temp.(name),level,varargin{:}); end %%------------------------------------------------------------------------- function txt=matlabobject2ubjson(name,item,level,varargin) try if numel(item) == 0 %empty object st = struct(); elseif numel(item) == 1 % txt = str2ubjson(name, char(item), level, varargin(:)); return else propertynames = properties(item); for p = 1:numel(propertynames) for o = numel(item):-1:1 % aray of objects st(o).(propertynames{p}) = item(o).(propertynames{p}); end end end txt = struct2ubjson(name,st,level,varargin{:}); catch txt = any2ubjson(name,item, level, varargin(:)); end %%------------------------------------------------------------------------- function txt=matdata2ubjson(mat,level,varargin) Zmarker=varargin{1}.ZM_; if(isempty(mat)) txt=Zmarker; return; end FTmarker=varargin{1}.FTM_; Imarker=varargin{1}.IM_; Fmarker=varargin{1}.FM_; Amarker=varargin{1}.AM_; isnest=varargin{:}.nestarray; ismsgpack=varargin{1}.messagepack; format=varargin{1}.formatversion; isnum2cell=varargin{1}.num2cell_; if(ismsgpack) isnest=1; end if(~isvector(mat) && isnest==1) if(format>1.9 && isnum2cell==0) mat=permute(mat,ndims(mat):-1:1); end varargin{1}.num2cell_=1; end if(isa(mat,'integer') || isinteger(mat) || (~varargin{1}.keeptype && isfloat(mat) && all(mod(mat(:),1) == 0))) if(~isvector(mat) && isnest==1) txt=cell2ubjson('',num2cell(mat,1),level,varargin{:}); elseif(~ismsgpack || size(mat,1)==1) if(varargin{1}.keeptype) itype=class(mat); idx=find(ismember(varargin{1}.IType_,itype)); if(isempty(idx)) idx=find(ismember(varargin{1}.IType_,itype(2:end))); end type=Imarker(idx); if(numel(mat)==1) varargin{1}.inttype_=idx; end elseif(~any(mat<0)) cid=varargin{1}.IType_; type=Imarker(end); maxdata=max(double(mat(:))); for i=1:length(cid) if(maxdata==cast(maxdata,cid{i})) type=Imarker(i); break; end end else cid=varargin{1}.IType_; type=Imarker(end); mindata=min(double(mat(:))); maxdata=max(double(mat(:))); for i=1:length(cid) if(maxdata==cast(maxdata,cid{i}) && mindata==cast(mindata,cid{i})) type=Imarker(i); break; end end end if(numel(mat)==1) if(mat<0) txt=I_(int64(mat),varargin{:}); else txt=I_(uint64(mat),varargin{:}); end else txt=I_a(mat(:),type,size(mat),varargin{:}); end else txt=cell2ubjson('',num2cell(mat,2),level,varargin{:}); end elseif(islogical(mat)) logicalval=FTmarker; if(numel(mat)==1) txt=logicalval(mat+1); else if(~isvector(mat) && isnest==1) txt=cell2ubjson('',num2cell(uint8(mat),1),level,varargin{:}); else txt=I_a(uint8(mat(:)),Imarker(1),size(mat),varargin{:}); end end else am0=Amarker{1}; if(Amarker{1}~='[') am0=char(145); end if(numel(mat)==1) txt=[am0 D_(mat,varargin{:}) Amarker{2}]; else if(~isvector(mat) && isnest==1) txt=cell2ubjson('',num2cell(mat,1),level,varargin{:}); else txt=D_a(mat(:),Fmarker(3),size(mat),varargin{:}); end end end %%------------------------------------------------------------------------- function val=N_(str,varargin) ismsgpack=varargin{1}.messagepack; if(~ismsgpack) val=[I_(int32(length(str)),varargin{:}) str]; else val=S_(str,varargin{:}); end %%------------------------------------------------------------------------- function val=S_(str,varargin) ismsgpack=varargin{1}.messagepack; Smarker=varargin{1}.SM_; if(length(str)==1) val=[Smarker(1) str]; else if(ismsgpack) val=[Imsgpk_(length(str),218,160,varargin{:}) str]; else val=['S' I_(int32(length(str)),varargin{:}) str]; end end %%------------------------------------------------------------------------- function val=Imsgpk_(num,base1,base0,varargin) if(num<16) val=char(uint8(num)+uint8(base0)); return; end val=I_(uint32(num),varargin{:}); if(val(1)>char(210)) num=uint32(num); val=[char(210) data2byte(swapbytes(cast(num,'uint32')),'uint8')]; elseif(val(1)',num)]; else val=[Imarker(varargin{1}.inttype_) data2byte(swapbytes(cast(num,cid{varargin{1}.inttype_})),'uint8')]; end return; end if(Imarker(1)~='U') if(num>=0 && num<127) val=uint8(num); return; end if(num<0 && num>=-31) val=typecast(int8(num), 'uint8'); return; end end if(Imarker(1)~='U' && num<0 && num<127) val=data2byte((swapbytes(cast(num,'uint8')) & 127),'uint8'); return; end key=Imarker; for i=1:length(cid) if(num==cast(num,cid{i})) if(isdebug) val=[key(i) sprintf('<%.0f>',num)]; else val=[key(i) data2byte(swapbytes(cast(num,cid{i})),'uint8')]; end return; end end val=S_(sprintf('%.0f',num),varargin{:}); if(Imarker(1)=='U') val(1)='H'; end %%------------------------------------------------------------------------- function val=D_(num, varargin) if(~isfloat(num)) error('input is not a float'); end isdebug=varargin{1}.debug; if(isdebug) output=sprintf('<%g>',num); else output=data2byte(swapbytes(num),'uint8'); end Fmarker=varargin{1}.FM_; if(isa(num,'half')) val=[Fmarker(1) output(:)']; elseif(isa(num,'single')) val=[Fmarker(2) output(:)']; else val=[Fmarker(3) output(:)']; end %%------------------------------------------------------------------------- function data=I_a(num,type,dim,varargin) if(isstruct(dim)) varargin={dim}; end Imarker=varargin{1}.IM_; Amarker=varargin{1}.AM_; if(Imarker(1)~='U' && type<=127) type=char(204); end id=find(ismember(Imarker,type)); if(id==0) error('unsupported integer array'); end % based on UBJSON specs, all integer types are stored in big endian format cid=varargin{1}.IType_; data=data2byte(swapbytes(cast(num,cid{id})),'uint8'); blen=varargin{1}.IByte_(id); isnest=varargin{1}.nestarray; isdebug=varargin{1}.debug; if(isdebug) output=sprintf('<%g>',num); else output=data(:); end if(isnest==0 && numel(num)>1 && Imarker(1)=='U') if(nargin>=4 && ~isstruct(dim) && (length(dim)==1 || (length(dim)>=2 && prod(dim)~=dim(2)))) cid=I_(uint32(max(dim)),varargin{:}); data=['$' type '#' I_a(dim,cid(1),varargin{:}) output(:)']; else data=['$' type '#' I_(int32(numel(data)/blen),varargin{:}) output(:)']; end data=['[' data(:)']; else am0=Amarker{1}; if(Imarker(1)~='U') Amarker={char(hex2dec('dd')),''}; am0=Imsgpk_(numel(num),220,144,varargin{:}); end if(isdebug) data=sprintf([type '<%g>'],num); else data=reshape(data,blen,numel(data)/blen); data(2:blen+1,:)=data; data(1,:)=type; end data=[am0 data(:)' Amarker{2}]; end %%------------------------------------------------------------------------- function data=D_a(num,type,dim,varargin) Fmarker=varargin{1}.FM_; Amarker=varargin{1}.AM_; id=find(ismember(Fmarker,type)); if(id==0) error('unsupported float array'); end data=data2byte(swapbytes(cast(num,varargin{1}.FType_{id})),'uint8'); blen=varargin{1}.FByte_(id); isnest=varargin{1}.nestarray; isdebug=varargin{1}.debug; if(isdebug) output=sprintf('<%g>',num); else output=data(:); end if(isnest==0 && numel(num)>1 && Fmarker(end)=='D') if(nargin>=4 && (length(dim)==1 || (length(dim)>=2 && prod(dim)~=dim(2)))) cid=I_(uint32(max(dim)),varargin{:}); data=['$' type '#' I_a(dim,cid(1),varargin{:}) output(:)']; else data=['$' type '#' I_(int32(numel(data)/blen),varargin{:}) output(:)']; end data=['[' data]; else am0=Amarker{1}; if(Fmarker(end)~='D') Amarker={char(hex2dec('dd')),''}; am0=Imsgpk_(numel(num),220,144,varargin{:}); end if(isdebug) data=sprintf([type '<%g>'],num); else data=reshape(data,blen,length(data)/blen); data(2:(blen+1),:)=data; data(1,:)=type; end data=[am0 data(:)' Amarker{2}]; end %%------------------------------------------------------------------------- function txt=any2ubjson(name,item,level,varargin) st=containers.Map(); st('_DataInfo_')=struct('MATLABObjectClass',class(item),'MATLABObjectSize',size(item)); st('_ByteStream_')=getByteStreamFromArray(item); if(isempty(name)) txt=map2ubjson(name,st,level,varargin{:}); else temp=struct(name,struct()); temp.(name)=st; txt=map2ubjson(name,temp.(name),level,varargin{:}); end %%------------------------------------------------------------------------- function bytes=data2byte(varargin) bytes=typecast(varargin{:}); bytes=char(bytes(:)'); jsonlab-2.0/savejson.m000066400000000000000000000670501367147361400150350ustar00rootroot00000000000000function json=savejson(rootname,obj,varargin) % % json=savejson(obj) % or % json=savejson(rootname,obj,filename) % json=savejson(rootname,obj,opt) % json=savejson(rootname,obj,'param1',value1,'param2',value2,...) % % convert a MATLAB object (cell, struct or array) into a JSON (JavaScript % Object Notation) string % % author: Qianqian Fang (q.fang neu.edu) % initially created on 2011/09/09 % % input: % rootname: the name of the root-object, when set to '', the root name % is ignored, however, when opt.ForceRootName is set to 1 (see below), % the MATLAB variable name will be used as the root name. % obj: a MATLAB object (array, cell, cell array, struct, struct array, % class instance). % filename: a string for the file name to save the output JSON data. % opt: a struct for additional options, ignore to use default values. % opt can have the following fields (first in [.|.] is the default) % % FileName [''|string]: a file name to save the output JSON data % FloatFormat ['%.10g'|string]: format to show each numeric element % of a 1D/2D array; % IntFormat ['%.0f'|string]: format to display integer elements % of a 1D/2D array; % ArrayIndent [1|0]: if 1, output explicit data array with % precedent indentation; if 0, no indentation % ArrayToStruct[0|1]: when set to 0, savejson outputs 1D/2D % array in JSON array format; if sets to 1, an % array will be shown as a struct with fields % "_ArrayType_", "_ArraySize_" and "_ArrayData_"; for % sparse arrays, the non-zero elements will be % saved to _ArrayData_ field in triplet-format i.e. % (ix,iy,val) and "_ArrayIsSparse_" will be added % with a value of 1; for a complex array, the % _ArrayData_ array will include two columns % (4 for sparse) to record the real and imaginary % parts, and also "_ArrayIsComplex_":1 is added. % NestArray [0|1]: If set to 1, use nested array constructs % to store N-dimensional arrays; if set to 0, % use the annotated array format defined in the % JData Specification (Draft 1 or later). % ParseLogical [0|1]: if this is set to 1, logical array elem % will use true/false rather than 1/0. % SingletArray [0|1]: if this is set to 1, arrays with a single % numerical element will be shown without a square % bracket, unless it is the root object; if 0, square % brackets are forced for any numerical arrays. % SingletCell [1|0]: if 1, always enclose a cell with "[]" % even it has only one element; if 0, brackets % are ignored when a cell has only 1 element. % ForceRootName [0|1]: when set to 1 and rootname is empty, savejson % will use the name of the passed obj variable as the % root object name; if obj is an expression and % does not have a name, 'root' will be used; if this % is set to 0 and rootname is empty, the root level % will be merged down to the lower level. % Inf ['"$1_Inf_"'|string]: a customized regular expression pattern % to represent +/-Inf. The matched pattern is '([-+]*)Inf' % and $1 represents the sign. For those who want to use % 1e999 to represent Inf, they can set opt.Inf to '$11e999' % NaN ['"_NaN_"'|string]: a customized regular expression pattern % to represent NaN % JSONP [''|string]: to generate a JSONP output (JSON with padding), % for example, if opt.JSONP='foo', the JSON data is % wrapped inside a function call as 'foo(...);' % UnpackHex [1|0]: conver the 0x[hex code] output by loadjson % back to the string form % SaveBinary [0|1]: 1 - save the JSON file in binary mode; 0 - text mode. % Compact [0|1]: 1- out compact JSON format (remove all newlines and tabs) % Compression 'zlib', 'gzip', 'lzma', 'lzip', 'lz4' or 'lz4hc': specify array % compression method; currently only supports 6 methods. The % data compression only applicable to numerical arrays % in 3D or higher dimensions, or when ArrayToStruct % is 1 for 1D or 2D arrays. If one wants to % compress a long string, one must convert % it to uint8 or int8 array first. The compressed % array uses three extra fields % "_ArrayZipType_": the opt.Compression value. % "_ArrayZipSize_": a 1D interger array to % store the pre-compressed (but post-processed) % array dimensions, and % "_ArrayZipData_": the "base64" encoded % compressed binary array data. % CompressArraySize [100|int]: only to compress an array if the total % element count is larger than this number. % CompressStringSize [400|int]: only to compress a string if the total % element count is larger than this number. % FormatVersion [2|float]: set the JSONLab output version; since % v2.0, JSONLab uses JData specification Draft 1 % for output format, it is incompatible with all % previous releases; if old output is desired, % please set FormatVersion to 1.9 or earlier. % Encoding ['']: json file encoding. Support all encodings of % fopen() function % Append [0|1]: if set to 1, append a new object at the end of the file. % Endian ['n'|'b','l']: Endianness of the output file ('n': native, % 'b': big endian, 'l': little-endian) % PreEncode [1|0]: if set to 1, call jdataencode first to preprocess % the input data before saving % % opt can be replaced by a list of ('param',value) pairs. The param % string is equivallent to a field in opt and is case sensitive. % output: % json: a string in the JSON format (see http://json.org) % % examples: % jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... % 'MeshElem',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... % 'MeshSurf',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... % 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... % 'MeshCreator','FangQ','MeshTitle','T6 Cube',... % 'SpecialData',[nan, inf, -inf]); % savejson('jmesh',jsonmesh) % savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g') % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==1) varname=inputname(1); obj=rootname; rootname=varname; else varname=inputname(2); end if(length(varargin)==1 && ischar(varargin{1})) opt=struct('filename',varargin{1}); else opt=varargin2struct(varargin{:}); end opt.isoctave=isoctavemesh; opt.compression=jsonopt('Compression','',opt); opt.nestarray=jsonopt('NestArray',0,opt); opt.compact=jsonopt('Compact',0,opt); opt.singletcell=jsonopt('SingletCell',1,opt); opt.singletarray=jsonopt('SingletArray',0,opt); opt.formatversion=jsonopt('FormatVersion',2,opt); opt.compressarraysize=jsonopt('CompressArraySize',100,opt); opt.compressstringsize=jsonopt('CompressStringSize',opt.compressarraysize*4,opt); opt.intformat=jsonopt('IntFormat','%.0f',opt); opt.floatformat=jsonopt('FloatFormat','%.10g',opt); opt.unpackhex=jsonopt('UnpackHex',1,opt); opt.arraytostruct=jsonopt('ArrayToStruct',0,opt); opt.parselogical=jsonopt('ParseLogical',0,opt); opt.arrayindent=jsonopt('ArrayIndent',1,opt); opt.inf=jsonopt('Inf','"$1_Inf_"',opt); opt.nan=jsonopt('NaN','"_NaN_"',opt); opt.num2cell_=0; opt.nosubstruct_=0; if(jsonopt('PreEncode',1,opt)) obj=jdataencode(obj,'Base64',1,'UseArrayZipSize',0,opt); end dozip=opt.compression; if(~isempty(dozip)) if(isempty(strmatch(dozip,{'zlib','gzip','lzma','lzip','lz4','lz4hc'}))) error('compression method "%s" is not supported',dozip); end if(exist('zmat','file')~=2 && exist('zmat','file')~=3) try error(javachk('jvm')); try base64decode('test'); catch matlab.net.base64decode('test'); end catch error('java-based compression is not supported'); end end opt.Compression=dozip; end rootisarray=0; rootlevel=1; forceroot=jsonopt('ForceRootName',0,opt); if((isnumeric(obj) || islogical(obj) || ischar(obj) || isstruct(obj) || ... iscell(obj) || isobject(obj) ) && isempty(rootname) && forceroot==0) rootisarray=1; rootlevel=0; else if(isempty(rootname)) rootname=varname; end end if(isa(obj,'containers.Map') && ~strcmp(obj.KeyType,'char')) rootisarray=0; end if((isstruct(obj) || iscell(obj))&& isempty(rootname) && forceroot) rootname='root'; end whitespaces=struct('tab',sprintf('\t'),'newline',sprintf('\n'),'sep',sprintf(',\n')); if(opt.compact==1) whitespaces=struct('tab','','newline','','sep',','); end if(~isfield(opt,'whitespaces_')) opt.whitespaces_=whitespaces; end nl=whitespaces.newline; json=obj2json(rootname,obj,rootlevel,opt); if(rootisarray) json=sprintf('%s%s',json,nl); else json=sprintf('{%s%s%s}\n',nl,json,nl); end jsonp=jsonopt('JSONP','',opt); if(~isempty(jsonp)) json=sprintf('%s(%s);%s',jsonp,json,nl); end % save to a file if FileName is set, suggested by Patrick Rapin filename=jsonopt('FileName','',opt); if(~isempty(filename)) encoding = jsonopt('Encoding','',opt); endian = jsonopt('Endian','n',opt); mode = 'w'; if(jsonopt('Append',0,opt)) mode='a'; end if(jsonopt('SaveBinary',0,opt)==1) if(isempty(encoding)) fid = fopen(filename, [mode 'b'],endian,encoding); else fid = fopen(filename, [mode 'b'],endian); end fwrite(fid,json); else if(isempty(encoding)) fid = fopen(filename,[mode 't'],endian); else fid = fopen(filename,[mode 't'],endian,encoding); end fwrite(fid,json,'char'); end fclose(fid); end %%------------------------------------------------------------------------- function txt=obj2json(name,item,level,varargin) if(iscell(item) || isa(item,'string')) txt=cell2json(name,item,level,varargin{:}); elseif(isstruct(item)) txt=struct2json(name,item,level,varargin{:}); elseif(isnumeric(item) || islogical(item)) txt=mat2json(name,item,level,varargin{:}); elseif(ischar(item)) if(numel(item)>=varargin{1}.compressstringsize) txt=mat2json(name,item,level,varargin{:}); else txt=str2json(name,item,level,varargin{:}); end elseif(isa(item,'function_handle')) txt=struct2json(name,functions(item),level,varargin{:}); elseif(isa(item,'containers.Map')) txt=map2json(name,item,level,varargin{:}); elseif(isa(item,'categorical')) txt=cell2json(name,cellstr(item),level,varargin{:}); elseif(isa(item,'table')) txt=matlabtable2json(name,item,level,varargin{:}); elseif(isa(item,'graph') || isa(item,'digraph')) txt=struct2json(name,jdataencode(item),level,varargin{:}); elseif(isobject(item)) txt=matlabobject2json(name,item,level,varargin{:}); else txt=any2json(name,item,level,varargin{:}); end %%------------------------------------------------------------------------- function txt=cell2json(name,item,level,varargin) txt={}; if(~iscell(item) && ~isa(item,'string')) error('input is not a cell or string array'); end if(isa(item,'string')) level=level-1; end isnum2cell=varargin{1}.num2cell_; if(isnum2cell) item=squeeze(item); else format=varargin{1}.formatversion; if(format>1.9 && ~isvector(item)) item=permute(item,ndims(item):-1:1); end end dim=size(item); if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now item=reshape(item,dim(1),numel(item)/dim(1)); dim=size(item); end len=numel(item); ws=varargin{1}.whitespaces_; padding0=repmat(ws.tab,1,level); padding2=repmat(ws.tab,1,level+1); nl=ws.newline; bracketlevel=~varargin{1}.singletcell; if(len>bracketlevel) if(~isa(item,'string')) if(~isempty(name)) txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":[', nl}; name=''; else txt={padding0, '[', nl}; end end elseif(len==0) if(~isempty(name)) txt={padding0, '"' decodevarname(name,varargin{1}.unpackhex) '":[]'}; name=''; else txt={padding0, '[]'}; end end for j=1:dim(2) if(dim(1)>1) txt(end+1:end+3)={padding2,'[',nl}; end for i=1:dim(1) txt{end+1}=obj2json(name,item{i,j},level+(dim(1)>1)+(len>bracketlevel),varargin{:}); if(i1) txt(end+1:end+3)={nl,padding2,']'}; end if(jbracketlevel && ~isa(item,'string')) txt(end+1:end+3)={nl,padding0,']'}; end txt = sprintf('%s',txt{:}); %%------------------------------------------------------------------------- function txt=struct2json(name,item,level,varargin) txt={}; if(~isstruct(item)) error('input is not a struct'); end dim=size(item); if(ndims(squeeze(item))>2) % for 3D or higher dimensions, flatten to 2D for now item=reshape(item,dim(1),numel(item)/dim(1)); dim=size(item); end len=numel(item); forcearray= (len>1 || (varargin{1}.singletarray==1 && level>0)); ws=varargin{1}.whitespaces_; padding0=repmat(ws.tab,1,level); padding2=repmat(ws.tab,1,level+1); padding1=repmat(ws.tab,1,level+(dim(1)>1)+forcearray); nl=ws.newline; if(isfield(item,encodevarname('_ArrayType_',varargin{1}.unpackhex))) varargin{1}.nosubstruct_=1; end if(isempty(item)) if(~isempty(name)) txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":[]'}; else txt={padding0, '[]'}; end txt = sprintf('%s',txt{:}); return; end if(~isempty(name)) if(forcearray) txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":[', nl}; end else if(forcearray) txt={padding0, '[', nl}; end end for j=1:dim(2) if(dim(1)>1) txt(end+1:end+3)={padding2,'[',nl}; end for i=1:dim(1) names = fieldnames(item(i,j)); if(~isempty(name) && len==1 && ~forcearray) txt(end+1:end+5)={padding1, '"', decodevarname(name,varargin{1}.unpackhex),'":{', nl}; else txt(end+1:end+3)={padding1, '{', nl}; end if(~isempty(names)) for e=1:length(names) if(varargin{1}.nosubstruct_ && ischar(item(i,j).(names{e})) || ... strcmp(names{e},encodevarname('_ByteStream_'))) txt{end+1}=str2json(names{e},item(i,j).(names{e}),... level+(dim(1)>1)+1+forcearray,varargin{:}); else txt{end+1}=obj2json(names{e},item(i,j).(names{e}),... level+(dim(1)>1)+1+forcearray,varargin{:}); end if(e1) txt(end+1:end+3)={nl,padding2,']'}; end if(j1 || (varargin{1}.singletarray==1 && level>0)); ws=varargin{1}.whitespaces_; padding0=repmat(ws.tab,1,level); nl=ws.newline; if(isempty(item)) if(~isempty(name)) txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":[]'}; else txt={padding0, '[]'}; end txt = sprintf('%s',txt{:}); return; end if(~isempty(name)) if(forcearray) txt={padding0, '"', decodevarname(name,varargin{1}.unpackhex),'":{', nl}; end else if(forcearray) txt={padding0, '{', nl}; end end for i=1:dim(1) if(~isempty(names{i})) txt{end+1}=obj2json(names{i},val{i},... level+(dim(1)>1),varargin{:}); if(i1) txt={padding1, '"', decodevarname(name,varargin{1}.unpackhex),'":[', nl}; end else if(len>1) txt={padding1, '[', nl}; end end for e=1:len if(strcmp('_ArrayZipData_',decodevarname(name,varargin{1}.unpackhex))==0) val=escapejsonstring(item(e,:),varargin{:}); else val=item(e,:); end if(len==1) obj=['"' decodevarname(name,varargin{1}.unpackhex) '":' '"',val,'"']; if(isempty(name)) obj=['"',val,'"']; end txt(end+1:end+2)={padding1, obj}; else txt(end+1:end+4)={padding0,'"',val,'"'}; end if(e==len) sep=''; end txt{end+1}=sep; end if(len>1) txt(end+1:end+3)={nl,padding1,']'}; end txt = sprintf('%s',txt{:}); %%------------------------------------------------------------------------- function txt=mat2json(name,item,level,varargin) if(~isnumeric(item) && ~islogical(item) && ~ischar(item)) error('input is not an array'); end ws=varargin{1}.whitespaces_; padding1=repmat(ws.tab,1,level); padding0=repmat(ws.tab,1,level+1); nl=ws.newline; sep=ws.sep; dozip=varargin{1}.compression; zipsize=varargin{1}.compressarraysize; format=varargin{1}.formatversion; isnest=varargin{1}.nestarray; if(~varargin{1}.nosubstruct_ && ( ((isnest==0) && length(size(item))>2) || issparse(item) || ~isreal(item) || ... (isempty(item) && any(size(item))) || varargin{1}.arraytostruct || (~isempty(dozip) && numel(item)>zipsize))) if(isempty(name)) txt=sprintf('%s{%s%s"_ArrayType_":"%s",%s%s"_ArraySize_":%s,%s',... padding1,nl,padding0,class(item),nl,padding0,regexprep(mat2str(size(item)),'\s+',','),nl); else txt=sprintf('%s"%s":{%s%s"_ArrayType_":"%s",%s%s"_ArraySize_":%s,%s',... padding1,decodevarname(name,varargin{1}.unpackhex),nl,padding0,class(item),nl,padding0,regexprep(mat2str(size(item)),'\s+',','),nl); end else numtxt=matdata2json(item,level+1,varargin{:}); if(isempty(name)) txt=sprintf('%s%s',padding1,numtxt); else if(numel(item)==1 && varargin{1}.singletarray==0) txt=sprintf('%s"%s":%s',padding1,decodevarname(name,varargin{1}.unpackhex),numtxt); else txt=sprintf('%s"%s":%s',padding1,decodevarname(name,varargin{1}.unpackhex),numtxt); end end return; end dataformat='%s%s%s%s%s'; if(issparse(item)) [ix,iy]=find(item); data=full(item(find(item))); if(~isreal(item)) data=[real(data(:)),imag(data(:))]; if(size(item,1)==1) % Kludge to have data's 'transposedness' match item's. % (Necessary for complex row vector handling below.) data=data'; end txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_":','true', sep); end txt=sprintf(dataformat,txt,padding0,'"_ArrayIsSparse_":','true', sep); if(~isempty(dozip) && numel(data*2)>zipsize) if(size(item,1)==1) % Row vector, store only column indices. fulldata=[iy(:),data']; elseif(size(item,2)==1) % Column vector, store only row indices. fulldata=[ix,data]; else % General case, store row and column indices. fulldata=[ix,iy,data]; end txt=sprintf(dataformat,txt,padding0,'"_ArrayZipSize_":',regexprep(mat2str(size(fulldata)),'\s+',','), sep); txt=sprintf(dataformat,txt,padding0,'"_ArrayZipType_":"',dozip, ['"' sep]); compfun=str2func([dozip 'encode']); txt=sprintf(dataformat,txt,padding0,'"_ArrayZipData_":"',base64encode(compfun(typecast(fulldata(:),'uint8'))),['"' nl]); else if(size(item,1)==1) % Row vector, store only column indices. fulldata=[iy(:),data']; elseif(size(item,2)==1) % Column vector, store only row indices. fulldata=[ix,data]; else % General case, store row and column indices. fulldata=[ix,iy,data]; end txt=sprintf(dataformat,txt,padding0,'"_ArrayData_":',... matdata2json(fulldata',level+2,varargin{:}), nl); end else if(format>1.9) item=permute(item,ndims(item):-1:1); end if(~isempty(dozip) && numel(item)>zipsize) if(isreal(item)) fulldata=item(:)'; if(islogical(fulldata) || ischar(fulldata)) fulldata=uint8(fulldata); end else txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_":','true', sep); fulldata=[real(item(:)) imag(item(:))]'; end txt=sprintf(dataformat,txt,padding0,'"_ArrayZipSize_":',regexprep(mat2str(size(fulldata)),'\s+',','), sep); txt=sprintf(dataformat,txt,padding0,'"_ArrayZipType_":"',dozip, ['"' sep]); compfun=str2func([dozip 'encode']); txt=sprintf(dataformat,txt,padding0,'"_ArrayZipData_":"',char(base64encode(compfun(typecast(fulldata(:),'uint8')))),['"' nl]); else if(isreal(item)) txt=sprintf(dataformat,txt,padding0,'"_ArrayData_":',... matdata2json(item(:)',level+2,varargin{:}), nl); else txt=sprintf(dataformat,txt,padding0,'"_ArrayIsComplex_":','true', sep); txt=sprintf(dataformat,txt,padding0,'"_ArrayData_":',... matdata2json([real(item(:)) imag(item(:))]',level+2,varargin{:}), nl); end end end txt=sprintf('%s%s%s',txt,padding1,'}'); %%------------------------------------------------------------------------- function txt=matlabobject2json(name,item,level,varargin) try if numel(item) == 0 %empty object st = struct(); elseif numel(item) == 1 % txt = str2json(name, char(item), level, varargin(:)); return else propertynames = properties(item); for p = 1:numel(propertynames) for o = numel(item):-1:1 % aray of objects st(o).(propertynames{p}) = item(o).(propertynames{p}); end end end txt=struct2json(name,st,level,varargin{:}); catch txt = any2json(name,item, level, varargin(:)); end %%------------------------------------------------------------------------- function txt=matlabtable2json(name,item,level,varargin) st=containers.Map(); st('_TableRecords_')=table2cell(item); st('_TableRows_')=item.Properties.RowNames'; st('_TableCols_')=item.Properties.VariableNames; if(isempty(name)) txt=map2json(name,st,level,varargin{:}); else temp=struct(name,struct()); temp.(name)=st; txt=map2json(name,temp.(name),level,varargin{:}); end %%------------------------------------------------------------------------- function txt=matdata2json(mat,level,varargin) ws=varargin{1}.whitespaces_; tab=ws.tab; nl=ws.newline; isnest=varargin{1}.nestarray; format=varargin{1}.formatversion; isnum2cell=varargin{1}.num2cell_; if(~isvector(mat) && isnest==1) if(format>1.9 && isnum2cell==0) mat=permute(mat,ndims(mat):-1:1); end varargin{1}.num2cell_=1; txt=cell2json('',num2cell(mat,1),level-1,varargin{:}); return; else if(isnest) if(isnum2cell) mat=mat(:).'; end end end if(size(mat,1)==1) pre=''; post=''; level=level-1; else pre=sprintf('[%s',nl); post=sprintf('%s%s]',nl,repmat(tab,1,level-1)); end if(isempty(mat)) txt='[]'; return; end if(isinteger(mat)) floatformat=varargin{1}.intformat; else floatformat=varargin{1}.floatformat; end if(numel(mat)==1 && varargin{1}.singletarray==0 && level>0) formatstr=[repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf(',%s',nl)]]; else formatstr=['[' repmat([floatformat ','],1,size(mat,2)-1) [floatformat sprintf('],%s',nl)]]; end if(nargin>=2 && size(mat,1)>1 && varargin{1}.arrayindent==1) formatstr=[repmat(tab,1,level) formatstr]; end txt=sprintf(formatstr,permute(mat,ndims(mat):-1:1)); txt(end-length(nl):end)=[]; if(islogical(mat) && (numel(mat)==1 || varargin{1}.parselogical==1)) txt=regexprep(txt,'1','true'); txt=regexprep(txt,'0','false'); end txt=[pre txt post]; if(any(isinf(mat(:)))) txt=regexprep(txt,'([-+]*)Inf',varargin{1}.inf); end if(any(isnan(mat(:)))) txt=regexprep(txt,'NaN',varargin{1}.nan); end %%------------------------------------------------------------------------- function txt=any2json(name,item,level,varargin) st=containers.Map(); st('_DataInfo_')=struct('MATLABObjectName',name, 'MATLABObjectClass',class(item),'MATLABObjectSize',size(item)); st('_ByteStream_')=char(base64encode(getByteStreamFromArray(item))); if(isempty(name)) txt=map2json(name,st,level,varargin{:}); else temp=struct(name,struct()); temp.(name)=st; txt=map2json(name,temp.(name),level,varargin{:}); end %%------------------------------------------------------------------------- function newstr=escapejsonstring(str,varargin) newstr=str; if(isempty(str) || isempty(regexp(str,'\W', 'once'))) return; end isoct=varargin{1}.isoctave; if(isoct) vv=sscanf(OCTAVE_VERSION,'%f'); if(vv(1)>=3.8) isoct=0; end end if(isoct) escapechars={'\\','\"','\/','\a','\f','\n','\r','\t','\v'}; for i=1:length(escapechars) newstr=regexprep(newstr,escapechars{i},escapechars{i}); end newstr=regexprep(newstr,'\\\\(u[0-9a-fA-F]{4}[^0-9a-fA-F]*)','\$1'); else escapechars={'\\','\"','\/','\a','\b','\f','\n','\r','\t','\v'}; esc={'\\\\','\\"','\\/','\\a','\\b','\\f','\\n','\\r','\\t','\\v'}; for i=1:length(escapechars) newstr=regexprep(newstr,escapechars{i},esc{i}); end newstr=regexprep(newstr,'\\\\(u[0-9a-fA-F]{4}[^0-9a-fA-F]*)','\\$1'); end jsonlab-2.0/savemsgpack.m000066400000000000000000000017731367147361400155110ustar00rootroot00000000000000function msgpk=savemsgpack(rootname,obj,varargin) % % msgpk=savemsgpack(obj) % or % msgpk=savemsgpack(rootname,obj,filename) % msgpk=savemsgpack(rootname,obj,opt) % msgpk=savemsgpack(rootname,obj,'param1',value1,'param2',value2,...) % % convert a MATLAB object (cell, struct, array, table, map, handles ...) % into a MessagePack binary stream % % author: Qianqian Fang (q.fang neu.edu) % initially created on 2019/05/20 % % This function is the same as calling savebj(...,'MessagePack',1) % % Please type "help savebj" for details for the supported inputs and outputs. % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==1) msgpk=savebj('',rootname,'MessagePack',1); elseif(length(varargin)==1 && ischar(varargin{1})) msgpk=savebj(rootname,obj,'FileName',varargin{1},'MessagePack',1); else msgpk=savebj(rootname,obj,varargin{:},'MessagePack',1); end jsonlab-2.0/saveubjson.m000066400000000000000000000060411367147361400153550ustar00rootroot00000000000000function ubj=saveubjson(rootname,obj,varargin) % % ubj=saveubjson(obj) % or % ubj=saveubjson(rootname,obj,filename) % ubj=saveubjson(rootname,obj,opt) % ubj=saveubjson(rootname,obj,'param1',value1,'param2',value2,...) % % Convert a MATLAB object (cell, struct, array, table, map, handles ...) % into a Universal Binary JSON (UBJSON, Draft 12) or a MessagePack binary stream % % author: Qianqian Fang (q.fang neu.edu) % initially created on 2013/08/17 % % Format specifications: % Binary JData (BJData):https://github.com/fangq/bjdata % UBJSON: https://github.com/ubjson/universal-binary-json % MessagePack: https://github.com/msgpack/msgpack % % This function is the same as calling "savebj(...,'ubjson',1)". By , % default this function creates UBJSON-compliant output without the % newly added uint16(u), uint32(m), uint64(M) and half-precision float (h) % data types. % % This function by default still enables an optimized ND-array format for efficient % array storage. To ensure the output compatible to UBJSON Draft-12, one should use % "saveubjson(...,'NestArray',1)" or "savebj(...,'ubjson',1,'NestArray',1)" % % input: % rootname: the name of the root-object, when set to '', the root name % is ignored, however, when opt.ForceRootName is set to 1 (see below), % the MATLAB variable name will be used as the root name. % obj: a MATLAB object (array, cell, cell array, struct, struct array, % class instance) % filename: a string for the file name to save the output UBJSON data % opt: a struct for additional options, ignore to use default values. % opt can have the following fields (first in [.|.] is the default) % % opt can be replaced by a list of ('param',value) pairs. The param % string is equivallent to a field in opt and is case sensitive. % % Please type "help savebj" for details for all supported options. % % output: % json: a binary string in the UBJSON format (see http://ubjson.org) % % examples: % jsonmesh=struct('MeshVertex3',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],... % 'MeshTet4',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],... % 'MeshTri3',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;... % 2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],... % 'MeshCreator','FangQ','MeshTitle','T6 Cube',... % 'SpecialData',[nan, inf, -inf]); % saveubjson(jsonmesh) % saveubjson('',jsonmesh,'meshdata.ubj') % saveubjson('mesh1',jsonmesh,'FileName','meshdata.msgpk','MessagePack',1) % saveubjson('',jsonmesh,'KeepType',1) % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==1) ubj=savebj('',rootname,'ubjson',1); elseif(length(varargin)==1 && ischar(varargin{1})) ubj=savebj(rootname,obj,'FileName',varargin{1},'ubjson',1); else ubj=savebj(rootname,obj,varargin{:},'ubjson',1); end jsonlab-2.0/test/000077500000000000000000000000001367147361400137765ustar00rootroot00000000000000jsonlab-2.0/test/run_jsonlab_test.m000066400000000000000000000453001367147361400175310ustar00rootroot00000000000000function run_jsonlab_test(tests) % % run_jsonlab_test % or % run_jsonlab_test(tests) % run_jsonlab_test({'js','jso','bj','bjo'}) % % Unit testing for JSONLab JSON, BJData/UBJSON encoders and decoders % % authors:Qianqian Fang (q.fang neu.edu) % date: 2020/06/08 % % input: % tests: is a cell array of strings, possible elements include % 'js': test savejson/loadjson % 'jso': test savejson/loadjson special options % 'bj': test savebj/loadbj % 'bjo': test savebj/loadbj special options % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) tests={'js','jso','bj','bjo'}; end %% if(ismember('js',tests)) fprintf(sprintf('%s\n',char(ones(1,79)*61))); fprintf('Test JSON functions\n'); fprintf(sprintf('%s\n',char(ones(1,79)*61))); test_jsonlab('single integer',@savejson,5,'[5]'); test_jsonlab('single float',@savejson,3.14,'[3.14]'); test_jsonlab('nan',@savejson,nan,'["_NaN_"]'); test_jsonlab('inf',@savejson,inf,'["_Inf_"]'); test_jsonlab('-inf',@savejson,-inf,'["-_Inf_"]'); test_jsonlab('large integer',@savejson,uint64(2^64),'[18446744073709551616]'); test_jsonlab('large negative integer',@savejson,int64(-2^63),'[-9223372036854775808]'); test_jsonlab('boolean as 01',@savejson,[true,false],'[1,0]','compact',1); test_jsonlab('empty array',@savejson,[],'[]'); test_jsonlab('empty cell',@savejson,{},'[]'); test_jsonlab('empty string',@savejson,'','""','compact',1); test_jsonlab('string escape',@savejson,sprintf('jdata\n\b\ashall\tprevail\t"\"\\'),'"jdata\n\b\ashall\tprevail\t\"\"\\"'); if(exist('isstring')) test_jsonlab('string type',@savejson,string(sprintf('jdata\n\b\ashall\tprevail')),'"jdata\n\b\ashall\tprevail"','compact',1); test_jsonlab('string array',@savejson,[string('jdata');string('shall');string('prevail')],'["jdata","shall","prevail"]','compact',1); end test_jsonlab('row vector',@savejson,[1,2,3],'[1,2,3]'); test_jsonlab('column vector',@savejson,[1;2;3],'[[1],[2],[3]]','compact',1); test_jsonlab('mixed array',@savejson,{'a',1,0.9},'["a",1,0.9]','compact',1); test_jsonlab('char array',@savejson,['AC';'EG'],'["AC","EG"]','compact',1); test_jsonlab('maps',@savejson,struct('a',1,'b','test'),'{"a":1,"b":"test"}','compact',1); test_jsonlab('2d array',@savejson,[1,2,3;4,5,6],'[[1,2,3],[4,5,6]]','compact',1); test_jsonlab('3d (row-major) nested array',@savejson,reshape(1:(2*3*2),2,3,2),... '[[[1,7],[3,9],[5,11]],[[2,8],[4,10],[6,12]]]','compact',1,'nestarray',1); test_jsonlab('3d (column-major) nested array',@savejson,reshape(1:(2*3*2),2,3,2),... '[[[1,2],[3,4],[5,6]],[[7,8],[9,10],[11,12]]]','compact',1,'nestarray',1,'formatversion',1.9); test_jsonlab('3d annotated array',@savejson,reshape(int8(1:(2*3*2)),2,3,2),... '{"_ArrayType_":"int8","_ArraySize_":[2,3,2],"_ArrayData_":[1,7,3,9,5,11,2,8,4,10,6,12]}','compact',1); test_jsonlab('complex number',@savejson,single(2+4i),... '{"_ArrayType_":"single","_ArraySize_":[1,1],"_ArrayIsComplex_":true,"_ArrayData_":[[2],[4]]}','compact',1); test_jsonlab('empty sparse matrix',@savejson,sparse(2,3),... '{"_ArrayType_":"double","_ArraySize_":[2,3],"_ArrayIsSparse_":true,"_ArrayData_":[]}','compact',1); test_jsonlab('real sparse matrix',@savejson,sparse([0,3,0,1,4]'),... '{"_ArrayType_":"double","_ArraySize_":[5,1],"_ArrayIsSparse_":true,"_ArrayData_":[[2,4,5],[3,1,4]]}','compact',1); test_jsonlab('complex sparse matrix',@savejson,sparse([0,3i,0,1,4i].'),... '{"_ArrayType_":"double","_ArraySize_":[5,1],"_ArrayIsComplex_":true,"_ArrayIsSparse_":true,"_ArrayData_":[[2,4,5],[0,1,0],[3,0,4]]}','compact',1); test_jsonlab('heterogeneous cell',@savejson,{{1,{2,3}},{4,5},{6};{7},{8,9},{10}},... '[[[1,[2,3]],[4,5],[6]],[[7],[8,9],[10]]]','compact',1); test_jsonlab('struct array',@savejson,repmat(struct('i',1.1,'d','str'),[1,2]),... '[{"i":1.1,"d":"str"},{"i":1.1,"d":"str"}]','compact',1); test_jsonlab('encoded fieldnames',@savejson,struct(encodevarname('_i'),1,encodevarname('i_'),'str'),... '{"_i":1,"i_":"str"}','compact',1); if(exist('OCTAVE_VERSION','builtin')~=0) test_jsonlab('encoded fieldnames without decoding',@savejson,struct(encodevarname('_i'),1,encodevarname('i_'),'str'),... '{"_i":1,"i_":"str"}','compact',1,'UnpackHex',0); else test_jsonlab('encoded fieldnames without decoding',@savejson,struct(encodevarname('_i'),1,encodevarname('i_'),'str'),... '{"x0x5F_i":1,"i_":"str"}','compact',1,'UnpackHex',0); end if(exist('containers.Map')) test_jsonlab('containers.Map',@savejson,containers.Map({'Andy','^_^'},{true,'-_-'}),... '{"Andy":true,"^_^":"-_-"}','compact',1,'usemap',1); end if(exist('istable')) test_jsonlab('simple table',@savejson,table({'Andy','^_^'},{true,'-_-'}),... '{"_TableCols_":["Var1","Var2"],"_TableRows_":[],"_TableRecords_":[["Andy","^_^"],[true,"-_-"]]}','compact',1); end if(exist('bandwidth')) lband=2; uband=1; a=double(full(spdiags(true(4,lband+uband+1),-uband:lband,3,4))); a(a~=0)=find(a); test_jsonlab('lower band matrix',@savejson,tril(a),... '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayZipSize_":[2,3],"_ArrayShape_":["lowerband",1],"_ArrayData_":[1,5,9,0,2,6]}','compact',1,'usearrayshape',1); test_jsonlab('upper band matrix',@savejson,triu(a),... '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayZipSize_":[3,3],"_ArrayShape_":["upperband",2],"_ArrayData_":[7,11,0,4,8,12,1,5,9]}','compact',1,'usearrayshape',1); test_jsonlab('diag matrix',@savejson,tril(triu(a)),... '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayShape_":"diag","_ArrayData_":[1,5,9]}','compact',1,'usearrayshape',1); test_jsonlab('band matrix',@savejson,a,... '{"_ArrayType_":"double","_ArraySize_":[3,4],"_ArrayZipSize_":[4,3],"_ArrayShape_":["band",2,1],"_ArrayData_":[7,11,0,4,8,12,1,5,9,0,2,6]}','compact',1,'usearrayshape',1); a=a(:,1:3); a=uint8(tril(a)+tril(a)'); test_jsonlab('symmetric band matrix',@savejson,a,... '{"_ArrayType_":"uint8","_ArraySize_":[3,3],"_ArrayZipSize_":[2,3],"_ArrayShape_":["lowersymmband",1],"_ArrayData_":[2,10,18,0,2,6]}','compact',1,'usearrayshape',1); a(a==0)=1; test_jsonlab('lower triangular matrix',@savejson,tril(a),... '{"_ArrayType_":"uint8","_ArraySize_":[3,3],"_ArrayShape_":"lower","_ArrayData_":[2,2,10,1,6,18]}','compact',1,'usearrayshape',1); test_jsonlab('upper triangular matrix',@savejson,triu(a),... '{"_ArrayType_":"uint8","_ArraySize_":[3,3],"_ArrayShape_":"upper","_ArrayData_":[2,2,1,10,6,18]}','compact',1,'usearrayshape',1); end try val=zlibencode('test'); a=uint8(eye(5)); a(20,1)=1; test_jsonlab('zlib/zip compression (level 6)',@savejson,a,... sprintf('{"_ArrayType_":"uint8","_ArraySize_":[20,5],"_ArrayZipSize_":[1,100],"_ArrayZipType_":"zlib","_ArrayZipData_":"eJxjZAABRhwkxQBsDAACIQAH\n"}'),... 'compact',1, 'Compression','zlib','CompressArraySize',0) % nestarray for 4-D or above is not working test_jsonlab('gzip compression (level 6)',@savejson,a,... sprintf('{"_ArrayType_":"uint8","_ArraySize_":[20,5],"_ArrayZipSize_":[1,100],"_ArrayZipType_":"gzip","_ArrayZipData_":"H4sIAAAAAAAAA2NkAAFGHCTFAGwMAF9Xq6VkAAAA\n"}'),... 'compact',1, 'Compression','gzip','CompressArraySize',0) % nestarray for 4-D or above is not working test_jsonlab('lzma compression (level 5)',@savejson,a,... sprintf('{"_ArrayType_":"uint8","_ArraySize_":[20,5],"_ArrayZipSize_":[1,100],"_ArrayZipType_":"lzma","_ArrayZipData_":"XQAAEABkAAAAAAAAAAAAgD1IirvlZSEY7DH///taoAA=\n"}'),... 'compact',1, 'Compression','lzma','CompressArraySize',0) % nestarray for 4-D or above is not working catch end end %% if(ismember('jso',tests)) fprintf(sprintf('%s\n',char(ones(1,79)*61))); fprintf('Test JSON function options\n'); fprintf(sprintf('%s\n',char(ones(1,79)*61))); test_jsonlab('boolean',@savejson,[true,false],'[true,false]','compact',1,'ParseLogical',1); test_jsonlab('nan option',@savejson,nan,'["_nan_"]','NaN','"_nan_"'); test_jsonlab('inf option',@savejson,-inf,'["-inf"]','Inf','"$1inf"'); test_jsonlab('output int format',@savejson,uint8(5),'[ 5]','IntFormat','%3d'); test_jsonlab('output float format',@savejson,pi,'[3.142]','FloatFormat','%5.3f'); test_jsonlab('remove singlet array',@savejson,{struct('a',1),5},'[{"a":1},5]','compact',1,'SingletArray',0); test_jsonlab('keep singlet array',@savejson,{struct('a',1),5},'[[{"a":[1]}],[5]]','compact',1,'SingletArray',1); end %% if(ismember('bj',tests)) fprintf(sprintf('%s\n',char(ones(1,79)*61))); fprintf('Test Binary JSON functions\n'); fprintf(sprintf('%s\n',char(ones(1,79)*61))); test_jsonlab('uint8 integer',@savebj,2^8-1,'U<255>','debug',1); test_jsonlab('uint16 integer',@savebj,2^8,'u<256>','debug',1); test_jsonlab('int8 integer',@savebj,-2^7,'i<-128>','debug',1); test_jsonlab('int16 integer',@savebj,-2^7-1,'I<-129>','debug',1); test_jsonlab('int32 integer',@savebj,-2^15-1,'l<-32769>','debug',1); test_jsonlab('uint16 integer',@savebj,2^16-1,'u<65535>','debug',1); test_jsonlab('uint32 integer',@savebj,2^16,'m<65536>','debug',1); test_jsonlab('uint32 integer',@savebj,2^32-1,'m<4294967295>','debug',1); test_jsonlab('int32 integer',@savebj,-2^31,'l<-2147483648>','debug',1); test_jsonlab('single float',@savebj,3.14,'[D<3.14>]','debug',1); test_jsonlab('nan',@savebj,nan,'[D]','debug',1); test_jsonlab('inf',@savebj,inf,'[D]','debug',1); test_jsonlab('-inf',@savebj,-inf,'[D<-Inf>]','debug',1); test_jsonlab('uint64 integer',@savebj,uint64(2^64),'M<18446744073709551616>','debug',1); test_jsonlab('int64 negative integer',@savebj,int64(-2^63),'L<-9223372036854775808>','debug',1); test_jsonlab('boolean as 01',@savebj,[true,false],'[U<1>U<0>]','debug',1,'nestarray',1); test_jsonlab('empty array',@savebj,[],'Z','debug',1); test_jsonlab('empty cell',@savebj,{},'Z','debug',1); test_jsonlab('empty string',@savebj,'','SU<0>','debug',1); test_jsonlab('skip no-op before marker and after value',@savebj,loadbj(char(['NN[NU' char(5) 'NNNU' char(1) ']'])),'[$U#U<2><5><1>','debug',1); test_jsonlab('string escape',@savebj,sprintf('jdata\n\b\ashall\tprevail\t"\"\\'),sprintf('SU<25>jdata\n\b\ashall\tprevail\t\"\"\\'),'debug',1); if(exist('isstring')) test_jsonlab('string type',@savebj,string(sprintf('jdata\n\b\ashall\tprevail')),sprintf('[SU<21>jdata\n\b\ashall\tprevail]'),'debug',1); test_jsonlab('string array',@savebj,[string('jdata');string('shall');string('prevail')],'[[SU<5>jdataSU<5>shallSU<7>prevail]]','debug',1); end test_jsonlab('row vector',@savebj,[1,2,3],'[$U#U<3><1><2><3>','debug',1); test_jsonlab('column vector',@savebj,[1;2;3],'[$U#[$U#U<2><3><1><1><2><3>','debug',1); test_jsonlab('mixed array',@savebj,{'a',1,0.9},'[CaU<1>[D<0.9>]]','debug',1); test_jsonlab('char array',@savebj,['AC';'EG'],'[SU<2>ACSU<2>EG]','debug',1); test_jsonlab('maps',@savebj,struct('a',1,'b','test'),'{U<1>aU<1>U<1>bSU<4>test}','debug',1); test_jsonlab('2d array',@savebj,[1,2,3;4,5,6],'[$U#[$U#U<2><2><3><1><4><2><5><3><6>','debug',1); test_jsonlab('3d (row-major) nested array',@savebj,reshape(1:(2*3*2),2,3,2),... '[[[U<1>U<7>][U<3>U<9>][U<5>U<11>]][[U<2>U<8>][U<4>U<10>][U<6>U<12>]]]','debug',1,'nestarray',1); test_jsonlab('3d (column-major) nested array',@savebj,reshape(1:(2*3*2),2,3,2),... '[[[U<1>U<2>][U<3>U<4>][U<5>U<6>]][[U<7>U<8>][U<9>U<10>][U<11>U<12>]]]','debug',1,'nestarray',1,'formatversion',1.9); test_jsonlab('3d annotated array',@savebj,reshape(int8(1:(2*3*2)),2,3,2),... '{U<11>_ArrayType_SU<4>int8U<11>_ArraySize_[$U#U<3><2><3><2>U<11>_ArrayData_[$U#U<12><1><7><3><9><5><11><2><8><4><10><6><12>}','debug',1); test_jsonlab('complex number',@savebj,single(2+4i),... '{U<11>_ArrayType_SU<6>singleU<11>_ArraySize_[$U#U<2><1><1>U<16>_ArrayIsComplex_TU<11>_ArrayData_[$U#[$U#U<2><2><1><2><4>}','debug',1); test_jsonlab('empty sparse matrix',@savebj,sparse(2,3),... '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><2><3>U<15>_ArrayIsSparse_TU<11>_ArrayData_Z}','debug',1); test_jsonlab('real sparse matrix',@savebj,sparse([0,3,0,1,4]'),... '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><5><1>U<15>_ArrayIsSparse_TU<11>_ArrayData_[$U#[$U#U<2><2><3><2><3><4><1><5><4>}','debug',1); test_jsonlab('complex sparse matrix',@savebj,sparse([0,3i,0,1,4i].'),... '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><5><1>U<16>_ArrayIsComplex_TU<15>_ArrayIsSparse_TU<11>_ArrayData_[$U#[$U#U<2><3><3><2><0><3><4><1><0><5><0><4>}','debug',1); test_jsonlab('heterogeneous cell',@savebj,{{1,{2,3}},{4,5},{6};{7},{8,9},{10}},... '[[[U<1>[U<2>U<3>]][U<4>U<5>][U<6>]][[U<7>][U<8>U<9>][U<10>]]]','debug',1); test_jsonlab('struct array',@savebj,repmat(struct('i',1.1,'d','str'),[1,2]),... '[{U<1>i[D<1.1>]U<1>dSU<3>str}{U<1>i[D<1.1>]U<1>dSU<3>str}]','debug',1); test_jsonlab('encoded fieldnames',@savebj,struct(encodevarname('_i'),1,encodevarname('i_'),'str'),... '{U<2>_iU<1>U<2>i_SU<3>str}','debug',1); if(exist('OCTAVE_VERSION','builtin')~=0) test_jsonlab('encoded fieldnames without decoding',@savebj,struct(encodevarname('_i'),1,encodevarname('i_'),'str'),... '{U<2>_iU<1>U<2>i_SU<3>str}','debug',1,'UnpackHex',0); else test_jsonlab('encoded fieldnames without decoding',@savebj,struct(encodevarname('_i'),1,encodevarname('i_'),'str'),... '{U<7>x0x5F_iU<1>U<2>i_SU<3>str}','debug',1,'UnpackHex',0); end if(exist('containers.Map')) test_jsonlab('containers.Map',@savebj,containers.Map({'Andy','^_^'},{true,'-_-'}),... '{U<4>AndyTU<3>^_^SU<3>-_-}','debug',1,'usemap',1); end if(exist('istable')) test_jsonlab('simple table',@savebj,table({'Andy','^_^'},{true,'-_-'}),... '{U<11>_TableCols_[SU<4>Var1SU<4>Var2]U<11>_TableRows_ZU<14>_TableRecords_[[SU<4>AndySU<3>^_^][TSU<3>-_-]]}','debug',1); end if(exist('bandwidth')) lband=2; uband=1; a=double(full(spdiags(true(4,lband+uband+1),-uband:lband,3,4))); a(a~=0)=find(a); test_jsonlab('lower band matrix',@savebj,tril(a),... '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<14>_ArrayZipSize_[$U#U<2><2><3>U<12>_ArrayShape_[SU<9>lowerbandU<1>]U<11>_ArrayData_[$U#U<6><1><5><9><0><2><6>}','debug',1,'usearrayshape',1); test_jsonlab('upper band matrix',@savebj,triu(a),... '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<14>_ArrayZipSize_[$U#U<2><3><3>U<12>_ArrayShape_[SU<9>upperbandU<2>]U<11>_ArrayData_[$U#U<9><7><11><0><4><8><12><1><5><9>}','debug',1,'usearrayshape',1); test_jsonlab('diag matrix',@savebj,tril(triu(a)),... '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<12>_ArrayShape_SU<4>diagU<11>_ArrayData_[$U#U<3><1><5><9>}','debug',1,'usearrayshape',1); test_jsonlab('band matrix',@savebj,a,... '{U<11>_ArrayType_SU<6>doubleU<11>_ArraySize_[$U#U<2><3><4>U<14>_ArrayZipSize_[$U#U<2><4><3>U<12>_ArrayShape_[SU<4>bandU<2>U<1>]U<11>_ArrayData_[$U#U<12><7><11><0><4><8><12><1><5><9><0><2><6>}','debug',1,'usearrayshape',1); a=a(:,1:3); a=uint8(tril(a)+tril(a)'); test_jsonlab('symmetric band matrix',@savebj,a,... '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><3><3>U<14>_ArrayZipSize_[$U#U<2><2><3>U<12>_ArrayShape_[SU<13>lowersymmbandU<1>]U<11>_ArrayData_[$U#U<6><2><10><18><0><2><6>}','debug',1,'usearrayshape',1); a(a==0)=1; test_jsonlab('lower triangular matrix',@savebj,tril(a),... '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><3><3>U<12>_ArrayShape_SU<5>lowerU<11>_ArrayData_[$U#U<6><2><2><10><1><6><18>}','debug',1,'usearrayshape',1); test_jsonlab('upper triangular matrix',@savebj,triu(a),... '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><3><3>U<12>_ArrayShape_SU<5>upperU<11>_ArrayData_[$U#U<6><2><2><1><10><6><18>}','debug',1,'usearrayshape',1); end try val=zlibencode('test'); a=uint8(eye(5)); a(20,1)=1; test_jsonlab('zlib/zip compression (level 6)',@savebj,a,... '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><20><5>U<14>_ArrayZipSize_[$U#U<2><1><100>U<14>_ArrayZipType_SU<4>zlibU<14>_ArrayZipData_[$U#U<18><120><156><99><100><0><1><70><28><36><197><0><108><12><0><2><33><0><7>}',... 'debug',1, 'Compression','zlib','CompressArraySize',0) % nestarray for 4-D or above is not working test_jsonlab('gzip compression (level 6)',@savebj,a,... '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><20><5>U<14>_ArrayZipSize_[$U#U<2><1><100>U<14>_ArrayZipType_SU<4>gzipU<14>_ArrayZipData_[$U#U<30><31><139><8><0><0><0><0><0><0><3><99><100><0><1><70><28><36><197><0><108><12><0><95><87><171><165><100><0><0><0>}',... 'debug',1, 'Compression','gzip','CompressArraySize',0) % nestarray for 4-D or above is not working test_jsonlab('lzma compression (level 5)',@savebj,a,... '{U<11>_ArrayType_SU<5>uint8U<11>_ArraySize_[$U#U<2><20><5>U<14>_ArrayZipSize_[$U#U<2><1><100>U<14>_ArrayZipType_SU<4>lzmaU<14>_ArrayZipData_[$U#U<32><93><0><0><16><0><100><0><0><0><0><0><0><0><0><0><128><61><72><138><187><229><101><33><24><236><49><255><255><251><90><160><0>}',... 'debug',1, 'Compression','lzma','CompressArraySize',0) % nestarray for 4-D or above is not working catch end end %% if(ismember('bjo',tests)) fprintf(sprintf('%s\n',char(ones(1,79)*61))); fprintf('Test Binary JSON function options\n'); fprintf(sprintf('%s\n',char(ones(1,79)*61))); test_jsonlab('remove ubjson optimized array header',@savebj,[1,2,3],'[U<1>U<2>U<3>]','debug',1,'nestarray',1); test_jsonlab('limit to ubjson signed integer',@savebj,256,'I<256>','debug',1,'ubjson',1); test_jsonlab('limit to ubjson integer markers',@savebj,2^32-1,'L<4294967295>','debug',1,'ubjson',1); test_jsonlab('H marker for out of bound integer',@savebj,2^64-1,'HU<20>18446744073709551616','debug',1,'ubjson',1); test_jsonlab('do not downcast integers to the shortest format',@savebj,int32(5),'l<5>','debug',1,'keeptype',1); test_jsonlab('do not downcast integer array to the shortest format',@savebj,int32([5,6]),'[$l#U<2><5><6>','debug',1,'keeptype',1); end jsonlab-2.0/test/test_jsonlab.m000066400000000000000000000021421367147361400166420ustar00rootroot00000000000000function test_jsonlab(testname,fhandle,input,expected,varargin) res=fhandle('',input,varargin{:}); if(~isequal(strtrim(res),expected)) warning('Test %s: failed: expected ''%s'', obtained ''%s''',testname,expected,res); else fprintf(1,'Testing %s: ok\n\toutput:''%s''\n',testname,strtrim(res)); if(regexp(res,'^[\[\{A-Za-z]')) handleinfo=functions(fhandle); loadfunname=regexprep(handleinfo.function,'^save','load'); loadfun=str2func(loadfunname); if(strcmp(loadfunname,'loadbj')) newres=loadfun(fhandle('',input,varargin{:},'debug',0),varargin{:}); else newres=loadfun(res,varargin{:}); end if(exist('isequaln')) try if(isequaln(newres,input)) fprintf(1,'\t%s successfully restored the input\n',loadfunname); end catch end else try if(newres==input) fprintf(1,'\t%s successfully restored the input\n',loadfunname); end catch end end end endjsonlab-2.0/varargin2struct.m000066400000000000000000000021201367147361400163300ustar00rootroot00000000000000function opt=varargin2struct(varargin) % % opt=varargin2struct('param1',value1,'param2',value2,...) % or % opt=varargin2struct(...,optstruct,...) % % convert a series of input parameters into a structure % % authors:Qianqian Fang (q.fang neu.edu) % date: 2012/12/22 % % input: % 'param', value: the input parameters should be pairs of a string and a value % optstruct: if a parameter is a struct, the fields will be merged to the output struct % % output: % opt: a struct where opt.param1=value1, opt.param2=value2 ... % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % len=length(varargin); opt=struct; if(len==0) return; end i=1; while(i<=len) if(isstruct(varargin{i})) opt=mergestruct(opt,varargin{i}); elseif(ischar(varargin{i}) && i neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store ZLIB-compressed data % info (optional): a struct produced by the zmat/lz4hcencode function during % compression; if not given, the inputs/outputs will be treated as a % 1-D vector % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=zlibencode(eye(10)); % orig=zlibdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) if(nargin>1) [varargout{1:nargout}]=zmat(varargin{1},varargin{2:end}); else [varargout{1:nargout}]=zmat(varargin{1},0,'zlib',varargin{2:end}); end return; elseif(isoctavemesh) error('You must install the ZMat toolbox (http://github.com/fangq/zmat) to use this function in Octave'); end error(javachk('jvm')); if(ischar(varargin{1})) varargin{1}=uint8(varargin{1}); end input=typecast(varargin{1}(:)','uint8'); buffer = java.io.ByteArrayOutputStream(); zlib = java.util.zip.InflaterOutputStream(buffer); zlib.write(input, 0, numel(input)); zlib.close(); if(nargout>0) varargout{1} = typecast(buffer.toByteArray(), 'uint8')'; if(nargin>1 && isstruct(varargin{2}) && isfield(varargin{2},'type')) inputinfo=varargin{2}; varargout{1}=typecast(varargout{1},inputinfo.type); varargout{1}=reshape(varargout{1},inputinfo.size); end end jsonlab-2.0/zlibencode.m000066400000000000000000000033211367147361400153120ustar00rootroot00000000000000function varargout = zlibencode(varargin) % % output = zlibencode(input) % or % [output, info] = zlibencode(input) % % Compress a string or numerical array using the ZLIB-compression % % This function depends on JVM in MATLAB or, can optionally use the ZMat % toolbox (http://github.com/fangq/zmat) % % Copyright (c) 2012, Kota Yamaguchi % URL: https://www.mathworks.com/matlabcentral/fileexchange/39526-byte-encoding-utilities % % Modified by: Qianqian Fang (q.fang neu.edu) % % input: % input: the original data, can be a string, a numerical vector or array % % output: % output: the decompressed byte stream stored in a uint8 vector; if info is % given, output will restore the original data's type and dimensions % % examples: % [bytes, info]=zlibencode(eye(10)); % orig=zlibdecode(bytes,info); % % license: % BSD or GPL version 3, see LICENSE_{BSD,GPLv3}.txt files for details % % -- this function is part of JSONLab toolbox (http://iso2mesh.sf.net/cgi-bin/index.cgi?jsonlab) % if(nargin==0) error('you must provide at least 1 input'); end if(exist('zmat','file')==2 || exist('zmat','file')==3) [varargout{1:nargout}]=zmat(varargin{1},1,'zlib'); return; elseif(isoctavemesh) error('You must install the ZMat toolbox (http://github.com/fangq/zmat) to use this function in Octave'); end error(javachk('jvm')); input=typecast(varargin{1}(:)','uint8'); buffer = java.io.ByteArrayOutputStream(); zlib = java.util.zip.DeflaterOutputStream(buffer); zlib.write(input, 0, numel(input)); zlib.close(); varargout{1} = typecast(buffer.toByteArray(), 'uint8')'; if(nargout>1) varargout{2}=struct('type',class(varargin{1}),'size',size(varargin{1}),'method','gzip','status',0); end