pax_global_header00006660000000000000000000000064146013441540014514gustar00rootroot0000000000000052 comment=51d5c6568946f5e75043ef73a3bb8159e080398e jsonlab-2.9.8/000077500000000000000000000000001460134415400131645ustar00rootroot00000000000000jsonlab-2.9.8/.github/000077500000000000000000000000001460134415400145245ustar00rootroot00000000000000jsonlab-2.9.8/.github/workflows/000077500000000000000000000000001460134415400165615ustar00rootroot00000000000000jsonlab-2.9.8/.github/workflows/run_test.yml000066400000000000000000000037101460134415400211500ustar00rootroot00000000000000name: JSONLab CI on: [push, pull_request] jobs: octave_test: name: Octave tests strategy: # provided octave versions: ubuntu-20.04 = 5.2, ubuntu-22.04 = 6.4, macos-11 = 8.1, windows-2019 = 7.3 matrix: os: [ubuntu-20.04, ubuntu-22.04, macos-12, windows-2019] runs-on: ${{ matrix.os }} defaults: run: shell: bash steps: - name: Checkout repo uses: actions/checkout@v3 with: submodules: 'recursive' - name: Install dependencies run: | [[ "$RUNNER_OS" == "Linux" ]] && sudo apt-get update && sudo apt-get install -y octave if [[ "$RUNNER_OS" == "macOS" ]]; then brew install octave fi if [[ "$RUNNER_OS" == "Windows" ]]; then curl --retry 3 -kL http://cdimage.debian.org/mirror/gnu.org/gnu/octave/windows/octave-7.3.0-w64-64.7z --output octave_7.3.0.7z 7z x octave_7.3.0.7z -ooctave -y echo "$PWD/octave/octave-7.3.0-w64-64/mingw64/bin" >> $GITHUB_PATH fi - name: Run octave test run: | octave-cli --version octave-cli --eval "addpath(pwd);cd test;run_jsonlab_test" octave-cli --eval "addpath(pwd);cd examples; demo_jsonlab_basic; jsonlab_selftest" matlab_test: name: MATLAB test strategy: matrix: os: [ubuntu-20.04, macos-11, windows-2019] runs-on: ${{ matrix.os }} steps: - name: Checkout repo uses: actions/checkout@v3 with: submodules: 'recursive' - name: Set up MATLAB uses: matlab-actions/setup-matlab@v1 with: release: R2022a - name: Run MATLAB test uses: matlab-actions/run-command@v1 with: command: addpath(pwd);cd test;run_jsonlab_test - name: Run MATLAB examples uses: matlab-actions/run-command@v1 with: command: addpath(pwd);cd examples; demo_jsonlab_basic; jsonlab_selftest jsonlab-2.9.8/.gitignore000066400000000000000000000006131460134415400151540ustar00rootroot00000000000000# 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.9.8/.miss_hit000066400000000000000000000004551460134415400150100ustar00rootroot00000000000000project_root suppress_rule: "redundant_brackets" suppress_rule: "line_length" suppress_rule: "file_length" suppress_rule: "copyright_notice" suppress_rule: "naming_functions" suppress_rule: "naming_parameters" suppress_rule: "naming_scripts" suppress_rule: "unicode" indent_function_file_body: false jsonlab-2.9.8/.travis.yml000066400000000000000000000020341460134415400152740ustar00rootroot00000000000000os: - linux language: - generic dist: - xenial jobs: include: - os: linux name: Octave 5.2 dist: focal env: - BADGE=Octave_5 - OCTAVE=octave-cli - os: linux name: Octave 4.2 dist: xenial env: - BADGE=Octave_4 - OCTAVE=octave-cli - os: linux name: Octave 3.8 dist: trusty env: - BADGE=Octave_3 - OCTAVE=octave-cli # - os: windows # name: Windows # env: # - BADGE=Windows # - os: osx # name: OSX # env: # - BADGE=OSX before_install: - if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo apt-get install octave; fi - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install octave; fi - if [ "$TRAVIS_OS_NAME" = "windows" ]; then choco install octave.portable; fi addons: apt: packages: - octave update: true script: - ${OCTAVE} --version - ${OCTAVE} --eval "addpath(pwd);cd test;run_jsonlab_test" - ${OCTAVE} --eval "addpath(pwd);cd examples; demo_jsonlab_basic; jsonlab_selftest" jsonlab-2.9.8/AUTHORS.txt000066400000000000000000000065511460134415400150610ustar00rootroot00000000000000The author of "JSONLab" toolbox is Qianqian Fang. Dr. Fang is currently an Associate Professor in the Department of Bioengineering, Northeastern University, USA. 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, https://neurojson.org, https://neurojson.io Email: and Since 2021, this project has been partially funded by the USA National Institute of Health (NIH) and National Institute of Neurological Disorders and Stroke (NINDS) under grant U24-NS124027 (PI Qianqian Fang). It is the reference implementation of the JData and BJData specifications developed under the NeuroJSON Project (https://neurojson.org). 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 svn 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 install via npm package manager - Paul Koprowski (PR#55) Feature: Added Encoding option to loadjson and savejson. jsonlab-2.9.8/ChangeLog.txt000066400000000000000000000537051460134415400155660ustar00rootroot00000000000000============================================================================ JSONlab - compact, portable, robust JSON/binary-JSON encoder/decoder for MATLAB/Octave ---------------------------------------------------------------------------- JSONlab ChangeLog (key features marked by *): == JSONlab 2.9.8 (codename: Micronus Prime - beta), FangQ == 2024-03-28*[b39c374] [feat] add json2couch from jbids toolbox 2024-03-28 [6da4f2b] [doc] remove the unrelated npm package.json 2024-03-28 [36b605d] [doc] update documentation 2024-03-27*[2e43586] [feat] merge nii/jnii/hdf5/tsv reading functions self-contained 2024-03-27 [b482c8f] [test] pass all tests on matlab R2010b 2024-03-27 [2008934] [doc] additional documentations on decompression functions 2024-03-27 [0a582fb] [doc] add documentations for jsonpath, jsoncache, jdlink, and maxlinklevel 2024-03-27 [5dba1de] [bug] .. searches deep level of struct,make jdlink work for Octave 4.2 and 5.2 2024-03-27*[fea481e] [doc] add line-by-line comment on examples, add jsonset/jsonget 2024-03-26*[e1d386d] [feat] support saving dictionary to json and bjdata 2024-03-26 [dfc744b] [feat] support caching data from any URL using hash, add NO_ZMAT flag 2024-03-24 [22d297e] [doc] fix README.rst formatting issues 2024-03-24 [36fef2c] [bug] fix missing quotes for function names 2024-03-24 [7e27db5] [doc] update documentation, preparing for v2.9.8 release 2024-03-24 [1227a0b] [format] reformat 2024-03-24 [67f30ca] [feat] support using \. or [] in JSONPath to escape dots in key names 2024-03-24 [ee830cd] [bug] fix error_pos error when giving a non-existant input file 2024-03-24 [d69686d] [feat] add jdlink to dynamically download and cache linked data 2024-03-22 [772a1ef] [ci] fix octave failed test 2024-03-22 [cff529a] [test] add jsonpath test, refine jsonpath syntax support 2024-03-22 [22435e4] [bug] fix jsonpath handling of recursive deep scans 2024-03-21 [c9f8a20] [bug] support deep scan in cell and struct, merge struct/containers.Map 2024-03-21 [394394a] [bug] improve jsonpath cell with deep scan 2024-03-20 [a599e71] [feat] add jsoncache to handle _DataLink_ download cache, rename jsonpath 2024-02-19*[4f2edeb] [feat] support .. jsonpath operator for deep scan 2024-01-11 [c43a758] [bug] fix missing index_esc reset, add test for automap 2024-01-11*[ef5b472] [feat] automatically switch to map object when key length > 63 2023-11-17 [ee24122] use sprintf to replace unescapejsonstring 2023-11-12 [abe504f] [ci] test again on macos-12 2023-11-12 [d2ff26a] [ci] install octave via conda on macos to avoid hanged install 2023-11-07 [33263de] completely reformat m-files using miss_hit 2023-11-07 [3ff781f] make octavezmat work on matlab 2023-10-29 [ea4a4fd] make test script run on MATLAB R2010b 2023-10-27 [ca91e07] use older matlab due to matlab-actions/run-command#43 2023-10-27 [4bf8232] add NO_ZMAT flag, fix fread issue 2023-10-27*[ce3c0a0] add fallback zlib/glib support on Octave via file-based zip/unzip 2023-10-26 [7ab1b6e] fix error for expecting an ending object mark when count is given 2023-09-08 [6dfa58e] Fix typos found by codespell 2023-06-27 [7d7e7f7] fix typo of compression method 2023-06-27*[c25dd0f] support blosc2 codecs in save and load data, upgrade jsave/jload 2023-06-19 [b23181a] test root-level indentation 2023-06-19 [5bfde65] add indentation test 2023-06-19 [b267858] fix CI errors related to octave utf-8 handling 2023-06-19 [1e93d07] avoid octave 6.4+ regexp non-utf8 error see discussions at octave bug thread: https://savannah.gnu.org/bugs/index.php?57107 2023-06-15 [8f921ac] fix broken tests 2023-06-11*[6cb5f12] allow linking binary jdata files inside json 2023-06-10 [2d0649b] do not compress long string by default, read bjd from URI 2023-06-10 [5135dea] saving JSON with UTF-8 encoding, fix #71 2023-06-10*[a3c807f] add zstdencode and zstddecode via new version of zmat 2023-06-07 [837c8b5] fix containers.Map indentiation bug with a single element 2023-06-07 [747c99b] fix string indentation, add option EmptyArrayAsNull, fix #91 2023-06-05*[cf57326] support blosc2 meta compressors 2023-05-05 [d37a386] use {:} to expand varargin 2023-04-23 [03311d2] remove README.txt, no longer used, fix #88 2023-04-21 [49eceb0] Fix typo not found by codespell 2023-04-21 [75b1fdc] Fix typos found by codespell 2023-04-17 [8fea393] revert savejson change 2023-04-17 [9554a44] Merge branch 'master' of github.com:fangq/jsonlab 2023-04-17 [3c32aff] speed up string encoding and decoding 2023-04-09*[8c8464f] rename jamm files to pmat - portable mat, will add jsonmmap 2023-04-09 [aa1c2a4] drop ubuntu-18.04 2023-04-08 [9173525] replace regexp to ismember due to octave bug 57107; test mac 2023-04-08 [67065dc] fix matlab test 2023-04-08 [8dcedad] use alternative test to avoid octave bug 57107 2023-04-08*[9b6be7b] add github action based tests 2023-02-24 [cb43ed1] add bug fix test section 2023-02-24 [2412ebf] only simplify all-numeric or all-struct cells 2023-02-23 [d4e77e1] add missing file extension 2023-02-23 [408cc2e] fix loadjd and savejd file extension match, add jbids 2023-02-22 [29bac9d] fix broken jdatahash 2023-02-22*[69a7d01] add a portable data hash function 2023-02-09 [0448eb1] preventing matlab 2022b converting string to unicode 2022-11-21 [9ce91fc] handle empty struct with names, fix #85 2022-11-20 [9687d17] accept string typed file name, close #84 2022-08-12 [283e5f1] output data depends on nargout 2022-08-08 [c729048] avoid conjugating complex numbers, fix #83 2022-06-05*[fa35843] implementing JSON-Mmap spec draft 1, https://neurojson.org/jsonmmap/draft1 2022-05-18 [8b74d30] make savejd work for saveh5 to save hdf5 files 2022-04-19 [f1332e3] make banner image transparent background 2022-04-19 [6cf82a6] fix issues found by dependency check 2022-04-19 [94167bb] change neurojson urls to https 2022-04-19 [c4c4da1] create Contents.m from matlab 2022-04-19*[2278bb1] stop escaping / to \/ in JSON string, see https://mondotondo.com/2010/12/29/the-solidus-issue/ 2022-04-01*[fb711bb] add loadjd and savejd as the unified JSON/binary JSON file interface 2022-03-30 [4433a21] improve datalink uri handling to consider : inside uri 2022-03-30 [6368409] make datalink URL query more robust 2022-03-29 [dd9e9c6] when file suffix is missing, assume JSON feed 2022-03-29*[07c58f3] initial support for _DataLink_ of online/local file with JSONPath ref 2022-03-29 [897b7ba] fix test for older octave 2022-03-20 [bf03eff] force msgpack to use big-endian 2022-03-13 [46bbfa9] support empty name key, which is valid in JSON, fix #79 2022-03-12 [9ab040a] increase default float number digits from 10 to 16, fix #78 2022-03-11 [485ea29] update error message on the valid root-level markers 2022-02-23 [aa3913e] disable TFN marker in optimized header due to security risk and low benefit 2022-02-23 [f2c3223] support SCH{[ markers in optimized container type 2022-02-14 [540f95c] add optional preceding whitespace, explain format 2022-02-13 [3dfa904] debugged and tested mmap, add mmapinclude and mmapexclude options 2022-02-10*[6150ae1] handle uncompressed raw data (only base64 encoded) in jdatadecode 2022-02-10 [88a59eb] give a warning when jdatadecode fails, but still return the raw data 2022-02-03*[05edb7a] fast reading and writing json data record using mmap and jsonpath 2022-02-02*[b0f0ebd] return disk-map or memory-map table in loadjson 2022-02-01 [0888218] correct typos and add additional descriptions in README 2022-02-01*[03133c7] fix row-major ('formatversion',1.8) ND array storage order, update demo outputs 2022-02-01 [5998c70] revert variable name encoding to support unicode strings 2022-01-31 [16454e7] test flexible whitespaces in 1D/2D arrays, test mixed array from string 2022-01-31*[5c1ef15] accelerate fastarrayparser by 200%! jsonlab_speedtest cuts from 11s to 5.8s 2022-01-30 [9b25e20] fix octave 3.8 error on travis, it does not support single 2022-01-30 [5898f6e] add octave 5.2 to travis 2022-01-30*[2e3344c] [bjdata:breaking] Upgrade savebj/loadbj to BJData v1-draft 2, use little-endian by default 2022-01-30*[2e3344c] [bjdata:breaking] Fix optimized ND array element order (previously used column-major) 2022-01-30*[2e3344c] optimize loadjson and loadbj speed 2022-01-30*[2e3344c] add 'BuiltinJSON' option for savejson/loadjson to call jsonencode/jsondecode 2022-01-30*[2e3344c] more robust tests on ND array when parsing JSON numerical array construct 2021-06-23 [632531f] fix inconsistency between singlet integer and float values, close #70 2021-06-23 [f7d8226] prevent function calls when parsing array strings using eval, fix #75 2021-06-23 [b1ae5fa] fix #73 as a regression to #22 2020-09-29 [d0cb3b8] Fix for loading objects. 2020-07-26 [d0fb684] Add travis badge 2020-07-25 [708c36c] drop octave 3.2 2020-07-25 [436d84e] debug octave 3.2 2020-07-25 [0ce96ec] remove windows and osx targets from travis-ci 2020-07-25 [0d8baa4] fix ruby does not support error on windows 2020-07-25*[faa7921] enable travis-ci for jsonlab 2020-07-08 [321ab1a] add Debian and Ubuntu installation commands 2020-07-08 [e686828] update author info 2020-07-08*[ce40fdf] supports ND cell array, fix #66 2020-07-07 [6a8ce93] fix string encoding over 399 characters, close #65 2020-06-14 [5a58faf] fix DESCRIPTION date bug 2020-06-14 [9d7e94c] match octave description file and upstream version number 2020-06-14 [a5b6170] fix warning about lz4encode file name == 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 implements 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/NeuroJSON/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 install 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 handle 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.9.8/Contents.m000066400000000000000000000063771460134415400151540ustar00rootroot00000000000000% JSONLAB % % Files % base64decode - output = base64decode(input) % base64encode - output = base64encode(input) % blosc2decode - output = blosc2decode(input) % blosc2encode - output = blosc2encode(input) % decodevarname - newname = decodevarname(name) % encodevarname - newname = encodevarname(name) % fast_match_bracket - [endpos, maxlevel] = fast_match_bracket(key,pos,startpos,brackets) % filterjsonmmap - mmap=filterjsonmmap(mmap, patterns, isinclude) % gzipdecode - output = gzipdecode(input) % gzipencode - output = gzipencode(input) % isoctavemesh - [isoctave verinfo]=isoctavemesh % jdatadecode - newdata=jdatadecode(data,opt,...) % jdataencode - jdata=jdataencode(data) % jdatahash.m - key = jdatahash(data, algorithm) % jdlink - data = jdlink(uripath) % jload - jload % jsave - jsave % json2couch - response = json2couch(jsonfile, couchdburl, dbname, docname, logininfo) % jsoncache - [cachepath, filename]=jsoncache(hyperlink) % jsonget - json=jsonget(fname,mmap,'$.jsonpath1','$.jsonpath2',...) % jsonopt - val=jsonopt(key,default,optstruct) % jsonpath - obj=jsonpath(root, jsonpath) % jsonset - json=jsonset(fname,mmap,'$.jsonpath1',newval1,'$.jsonpath2','newval2',...) % loadbj - data=loadbj(fname,opt) % loadjd - data=loadjd(inputfile) % loadjson - data=loadjson(fname,opt) % loadmsgpack - data = loadmsgpack(fname,varargin) % 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, isndarray, maxlevel, count] = nestbracket2dim(str,brackets) % octavezmat - output = octavezmat(input, iscompress, zipmethod) % savebj - bjd=savebj(obj) % savejd - savejd(rootname, obj, outputfile) % savejson - json=savejson(obj) % savemsgpack - msgpk=savemsgpack(obj) % saveubjson - ubj=saveubjson(obj) % varargin2struct - opt=varargin2struct('param1',value1,'param2',value2,...) % zlibdecode - output = zlibdecode(input) % zlibencode - output = zlibencode(input) % zstddecode - output = zstddecode(input) % zstdencode - output = zstdencode(input) % loadbidstsv - data = loadbidstsv(tsvfile) % loadh5 - [data, meta] = loadh5(filename) % loadjnifti - jnii=loadjnifti(inputfile) % loadnifti - jnii=loadnifti(inputfile) % nii2jnii - jnii=nii2jnii(niifile) % niicodemap - newval=niicodemap(name, value) % niiformat - niiheader=niiformat(format) % niiheader2jnii - nii = niiheader2jnii(nii0) jsonlab-2.9.8/DESCRIPTION000066400000000000000000000012311460134415400146670ustar00rootroot00000000000000Name: jsonlab Version: 2.9.8 Date: 2024-25-03 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: https://neurojson.org/jsonlab Categories: JSON jsonlab-2.9.8/INDEX000066400000000000000000000016711460134415400137630ustar00rootroot00000000000000jsonlab >> JSONLab JSON loadjson savejson Binary JData loadbj savebj UBJSON loadubjson saveubjson MessagePack loadmsgpack savemsgpack JData Workspace jload jsave JData Specification jdatadecode jdataencode Interface loadjd savejd JSON Mmap jsonget jsonset filterjsonmmap jsonpath External Links jdlink jsoncache json2couch Compression and Decompression base64decode base64encode blosc2decode blosc2encode gzipdecode gzipencode lz4decode lz4encode lz4hcdecode lz4hcencode lzipdecode lzipencode lzmadecode lzmaencode zlibdecode zlibencode zstddecode zstdencode octavezmat HDF5 file parser loadh5 JNIfTI file parser loadjnifti loadnifti nii2jnii niicodemap niiformat niiheader2jnii Helper Functions decodevarname encodevarname fast_match_bracket isoctavemesh jsonopt jdatahash match_bracket mergestruct nestbracket2dim varargin2struct getvarfrom regrouph5 transposemat memmapstream loadbidstsv jsonlab-2.9.8/LICENSE_BSD.txt000066400000000000000000000035061460134415400155030ustar00rootroot00000000000000Copyright (c) 2011-2024 Qianqian Fang (all units) Copyright (c) 2014,2016 Bastian Bechtold (loadmsgpack.m) Copyright (c) 2012, Kota Yamaguchi (zlibdecode.m, zlibencode.m, gzipencode.m, gzipdecode.m, base64encode.m, base64decode.m) Copyright (c) 2009, Nedialko Krouchev (loadjson.m) Copyright (c) 2009, François Glineur (loadjson.m) Copyright (c) 2008, Joel Feenstra (loadjson.m) 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.9.8/LICENSE_GPLv3.txt000066400000000000000000001067131460134415400157720ustar00rootroot00000000000000=============================================================================== = JSONlab = = Compact, portable, robust JSON/binary-JSON encoder/decoder for MATLAB/Octave= =============================================================================== Copyright (C) 2011-2024 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.9.8/README.rst000066400000000000000000001604041460134415400146600ustar00rootroot00000000000000.. image:: https://neurojson.org/wiki/upload/neurojson_banner_long.png ######################################################################################## JSONLab: compact, portable, robust JSON/binary-JSON encoder/decoder for MATLAB/Octave ######################################################################################## * Copyright (c) 2011-2024 Qianqian Fang * License: BSD or GNU General Public License version 3 (GPL v3), see License*.txt * Version: 2.9.8 (Micronus Prime - Beta) * URL: https://neurojson.org/jsonlab * User forum: https://github.com/orgs/NeuroJSON/discussions/categories/neurojson-json-format-specifications-and-parsers * JData Specification Version: V1 Draft-3 (https://neurojson.org/jdata/draft3) * Binary JData Specification Version: V1 Draft-2 (https://neurojson.org/bjdata/draft2) * JSON-Mmap Specification Version: V1 Draft-1 (https://neurojson.org/jsonmmap/draft1) * Compatibility: MATLAB R2008 or newer, GNU Octave 3.8 or newer * Acknowledgement: This project is supported by US National Institute of Health (NIH) grant `U24-NS124027 `_ .. image:: https://github.com/fangq/jsonlab/actions/workflows/run_test.yml/badge.svg :target: https://github.com/fangq/jsonlab/actions/workflows/run_test.yml ################# Table of Contents ################# .. contents:: :local: :depth: 3 ============ What's New ============ We are excited to announce that the JSONLab project, as the official reference library for both `JData `_ and `BJData `_ specifications, has been funded by the US National Institute of Health (NIH) as part of the NeuroJSON project (https://neurojson.org and https://neurojson.io). The goal of the NeuroJSON project is to develop scalable, searchable, and reusable neuroimaging data formats and data sharing platforms. All data produced from the NeuroJSON project will be using JSON/Binary JData formats as the underlying serialization standards and the lightweight JData specification as language-independent data annotation standard, all of which have been evolved from the over a decade development of JSONLab. JSONLab v2.9.8 - code named "Micronus Prime - beta" - is the beta-release of the next milestone (v3.0), containing a number of key feature enhancements and bug fixes. The major new features include 1. exporting JSON Memory-Map (``jsonget,jsonset``) for rapid disk-map like reading/writing of JSON/binary JSON files and writing, implementing `JSON-Mmap spec v1 Draft 1 `_ 2. supporting JSONPath query (``jsonpath``) to MATLAB data and JSON/binary JSON file and streams, including deep-scan operators, 3. (**breaking**) upgrading the supported BJData spec to `V1 Draft 2 `_ where the default numerical data byte order changed from Big-Endian to **Little-Endian**, 4. adding initial support to JData `_DataLink_ `_ decoding to link multiple JSON/binary JSON files 5. dynamically cache linked data files (``jsoncache``, ``jdlink``) to permit on-demand download and processing of complex JSON-encoded datasets such as neuroimaging datasets hosted on https://neurojson.io 6. support high-performance Blosc2 meta-compressor for storing large N-D array data, 7. ``savejson/loadjson`` can use MATLAB/Octave built-in ``jsonencode/jsondecode`` using the ``BuiltinJSON`` option 8. automatically switch from ``struct`` to ``containers.Map`` when encoded key-length exceeds 63 9. provide fall-back zlib/gzip compression/decompression function (``octavezmat``) on Octave when ZMat is not installed 10. include built-in ``.nii/.nii.gz/.jnii/.h5/.snirf/.tsv/.csv`` parsers to allow loadjd.m to read wide range of files 11. include ``json2couch`` from jbids (https://github.com/NeuroJSON/jbids) to allow uploading json files to CouchDB server There have been many major updates added to this release since the previous release v2.0 in June 2020. A list of the major changes are summarized below (with key features marked by \*), including the support to BJData Draft-2 specification, new interface functions ``savejd/loadjd``, and options to use MATLAB/Octave built-in ``jsonencode/jsondecode`` functions. The ``octave-jsonlab`` package has also been included in the official distributions of Debian Bullseye and Ubuntu 21.04 or newer. - 2024-03-28 [b39c374] [feat] add json2couch from jbids toolbox - 2024-03-27*[2e43586] [feat] merge ``nii/jnii/hdf5/tsv`` reading functions self-contained - 2024-03-27 [b482c8f] [test] pass all tests on matlab R2010b - 2024-03-27 [2008934] [doc] additional documentations on decompression functions - 2024-03-27 [0a582fb] [doc] add documentations for jsonpath, jsoncache, jdlink, and maxlinklevel - 2024-03-27 [5dba1de] [bug] ``..`` searches deep level of struct, make jdlink work for Octave 4.2 and 5.2 - 2024-03-27 [fea481e] [doc] add line-by-line comment on examples, add ``jsonset/jsonget`` - 2024-03-26 [e1d386d] [feat] support saving dictionary to json and bjdata - 2024-03-26 [dfc744b] [feat] support caching data from any URL using hash, add ``NO_ZMAT`` flag - 2024-03-24 [22d297e] [doc] fix README.rst formatting issues - 2024-03-24 [7e27db5] [doc] update documentation, preparing for v2.9.8 release - 2024-03-24 [1227a0b] [format] reformat - 2024-03-24 [67f30ca] [feat] support using \. or [] in JSONPath to escape dots in key names - 2024-03-24 [ee830cd] [bug] fix error_pos error when giving a non-existant input file - 2024-03-24 [d69686d] [feat] add jdlink to dynamically download and cache linked data - 2024-03-22 [772a1ef] [ci] fix octave failed test - 2024-03-22*[cff529a] [test] add jsonpath test, refine jsonpath syntax support - 2024-03-22 [22435e4] [bug] fix jsonpath handling of recursive deep scans - 2024-03-21 [c9f8a20] [bug] support deep scan in cell and struct, merge struct/containers.Map - 2024-03-21 [394394a] [bug] improve jsonpath cell with deep scan - 2024-03-20 [a599e71] [feat] add jsoncache to handle ``_DataLink_`` download cache, rename jsonpath - 2024-02-19*[4f2edeb] [feat] support .. jsonpath operator for deep scan - 2024-01-11 [c43a758] [bug] fix missing index_esc reset, add test for automap - 2024-01-11*[ef5b472] [feat] automatically switch to map object when key length > 63 - 2023-11-17 [ee24122] use sprintf to replace unescapejsonstring - 2023-11-12 [abe504f] [ci] test again on macos-12 - 2023-11-12 [d2ff26a] [ci] install octave via conda on macos to avoid hanged install - 2023-11-07 [33263de] completely reformat m-files using miss_hit - 2023-11-07 [3ff781f] make octavezmat work on matlab - 2023-10-29 [ea4a4fd] make test script run on MATLAB R2010b - 2023-10-27 [ca91e07] use older matlab due to matlab-actions/run-command#43 - 2023-10-27 [4bf8232] add NO_ZMAT flag, fix fread issue - 2023-10-27*[ce3c0a0] add fallback zlib/glib support on Octave via file-based zip/unzip - 2023-10-26 [7ab1b6e] fix error for expecting an ending object mark when count is given - 2023-09-08 [6dfa58e] Fix typos found by codespell - 2023-06-27 [7d7e7f7] fix typo of compression method - 2023-06-27*[c25dd0f] support blosc2 codecs in save and load data, upgrade jsave/jload - 2023-06-19 [b23181a] test root-level indentation - 2023-06-19 [5bfde65] add indentation test - 2023-06-19 [b267858] fix CI errors related to octave utf-8 handling - 2023-06-19 [1e93d07] avoid octave 6.4+ regexp non-utf8 error see discussions at octave bug thread: https://savannah.gnu.org/bugs/index.php?57107 - 2023-06-15 [8f921ac] fix broken tests - 2023-06-11*[6cb5f12] allow linking binary jdata files inside json - 2023-06-10 [2d0649b] do not compress long string by default, read bjd from URI - 2023-06-10 [5135dea] saving JSON with UTF-8 encoding, fix #71 - 2023-06-10*[a3c807f] add zstdencode and zstddecode via new version of zmat - 2023-06-07 [837c8b5] fix containers.Map indentiation bug with a single element - 2023-06-07 [747c99b] fix string indentation, add option EmptyArrayAsNull, fix #91 - 2023-06-05*[cf57326] support blosc2 meta compressors - 2023-05-05 [d37a386] use {:} to expand varargin - 2023-04-23 [03311d2] remove README.txt, no longer used, fix #88 - 2023-04-21 [49eceb0] Fix typo not found by codespell - 2023-04-21 [75b1fdc] Fix typos found by codespell - 2023-04-17 [8fea393] revert savejson change - 2023-04-17 [9554a44] Merge branch 'master' of github.com:fangq/jsonlab - 2023-04-17 [3c32aff] speed up string encoding and decoding - 2023-04-09*[8c8464f] rename jamm files to pmat - portable mat, will add jsonmmap - 2023-04-09 [aa1c2a4] drop ubuntu-18.04 - 2023-04-08 [9173525] replace regexp to ismember due to octave bug 57107; test mac - 2023-04-08 [67065dc] fix matlab test - 2023-04-08 [8dcedad] use alternative test to avoid octave bug 57107 - 2023-04-08*[9b6be7b] add github action based tests - 2023-02-24 [cb43ed1] add bug fix test section - 2023-02-24 [2412ebf] only simplify all-numeric or all-struct cells - 2023-02-23 [d4e77e1] add missing file extension - 2023-02-23 [408cc2e] fix loadjd and savejd file extension match, add jbids - 2023-02-22 [29bac9d] fix broken jdatahash - 2023-02-22*[69a7d01] add a portable data hash function - 2023-02-09 [0448eb1] preventing matlab 2022b converting string to unicode - 2022-11-21 [9ce91fc] handle empty struct with names, fix #85 - 2022-11-20 [9687d17] accept string typed file name, close #84 - 2022-08-12 [283e5f1] output data depends on nargout - 2022-08-08 [c729048] avoid conjugating complex numbers, fix #83 - 2022-06-05*[fa35843] implementing JSON-Mmap spec draft 1, https://neurojson.org/jsonmmap/draft1 - 2022-05-18 [8b74d30] make savejd work for saveh5 to save hdf5 files - 2022-04-19 [f1332e3] make banner image transparent background - 2022-04-19 [6cf82a6] fix issues found by dependency check - 2022-04-19 [94167bb] change neurojson urls to https - 2022-04-19 [c4c4da1] create Contents.m from matlab - 2022-04-19*[2278bb1] stop escaping / to \/ in JSON string, see https://mondotondo.com/2010/12/29/the-solidus-issue/ - 2022-04-01*[fb711bb] add loadjd and savejd as the unified JSON/binary JSON file interface - 2022-03-30 [4433a21] improve datalink uri handling to consider : inside uri - 2022-03-30 [6368409] make datalink URL query more robust - 2022-03-29 [dd9e9c6] when file suffix is missing, assume JSON feed - 2022-03-29*[07c58f3] initial support for ``_DataLink_`` of online/local file with JSONPath ref - 2022-03-29 [897b7ba] fix test for older octave - 2022-03-20 [bf03eff] force msgpack to use big-endian - 2022-03-13 [46bbfa9] support empty name key, which is valid in JSON, fix #79 - 2022-03-12 [9ab040a] increase default float number digits from 10 to 16, fix #78 - 2022-03-11 [485ea29] update error message on the valid root-level markers - 2022-02-23 [aa3913e] disable TFN marker in optimized header due to security risk and low benefit - 2022-02-23 [f2c3223] support SCH{[ markers in optimized container type - 2022-02-14 [540f95c] add optional preceding whitespace, explain format - 2022-02-13 [3dfa904] debugged and tested mmap, add mmapinclude and mmapexclude options - 2022-02-10*[6150ae1] handle uncompressed raw data (only base64 encoded) in jdatadecode - 2022-02-10 [88a59eb] give a warning when jdatadecode fails, but still return the raw data - 2022-02-03*[05edb7a] fast reading and writing json data record using mmap and jsonpath - 2022-02-02*[b0f0ebd] return disk-map or memory-map table in loadjson - 2022-02-01 [0888218] correct typos and add additional descriptions in README - 2022-02-01*[03133c7] fix row-major ('formatversion',1.8) ND array storage order, update demo outputs - 2022-02-01 [5998c70] revert variable name encoding to support unicode strings - 2022-01-31 [16454e7] test flexible whitespaces in 1D/2D arrays, test mixed array from string - 2022-01-31*[5c1ef15] accelerate fastarrayparser by 200%! jsonlab_speedtest cuts from 11s to 5.8s - 2022-01-30 [9b25e20] fix octave 3.8 error on travis, it does not support single - 2022-01-30 [5898f6e] add octave 5.2 to travis - 2022-01-30*[2e3344c] [bjdata:breaking] Upgrade ``savebj/loadbj`` to BJData v1-draft 2, use little-endian by default - 2022-01-30*[2e3344c] [bjdata:breaking] Fix optimized ND array element order (previously used column-major) - 2022-01-30*[2e3344c] optimize loadjson and loadbj speed - 2022-01-30*[2e3344c] add 'BuiltinJSON' option for ``savejson/loadjson`` to call ``jsonencode/jsondecode`` - 2022-01-30*[2e3344c] more robust tests on ND array when parsing JSON numerical array construct - 2021-06-23 [632531f] fix inconsistency between singlet integer and float values, close #70 - 2021-06-23 [f7d8226] prevent function calls when parsing array strings using eval, fix #75 - 2021-06-23 [b1ae5fa] fix #73 as a regression to #22 - 2021-11-22*[ ] octave-jsonlab is officially in Debian Testing/Bullseye - 2020-09-29 [d0cb3b8] Fix for loading objects. - 2020-07-26 [d0fb684] Add travis badge - 2020-07-25 [708c36c] drop octave 3.2 - 2020-07-25 [436d84e] debug octave 3.2 - 2020-07-25 [0ce96ec] remove windows and osx targets from travis-ci - 2020-07-25 [0d8baa4] fix ruby does not support error on windows - 2020-07-25*[faa7921] enable travis-ci for jsonlab - 2020-07-08 [321ab1a] add Debian and Ubuntu installation commands - 2020-07-08 [e686828] update author info - 2020-07-08*[ce40fdf] supports ND cell array, fix #66 - 2020-07-07 [6a8ce93] fix string encoding over 399 characters, close #65 - 2020-06-14 [5a58faf] fix DESCRIPTION date bug - 2020-06-14 [9d7e94c] match octave description file and upstream version number - 2020-06-14 [a5b6170] fix warning about ``lz4encode`` file name Please note that the ``savejson/loadjson`` in both JSONLab v2.0-v3.0 are compliant with JData Spec Draft 3; the ``savebj/loadbj`` in JSONLab v3.0 is compatible to BJData spec Draft 2, which contains breaking feature changes compared to those in JSONLab v2.0. The BJData spec was derived from UBJSON spec Draft 12, with the following breaking differences: - BJData adds 4 new numeric data types: ``uint16 [u]``, ``uint32 [m]``, ``uint64 [M]`` and ``float16 [h]`` (supported in JSONLab v2.0 or newer) - 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) - BJData Draft 2 changes the default byte order to Little-Endian instead of Big-Endian (JSONLab 3.0 or later) - BJData only permits non-zero-fixed-length data types as the optimized array type, i.e. only ``UiuImlMLhdDC`` are allowed To avoid using the new features, one should attach ``'UBJSON',1`` and ``'Endian','B'`` in the ``savebj`` command as .. code-block:: savebj('',data,'FileName','myfile.bjd','UBJSON',1, 'Endian','B'); To read BJData data files generated by JSONLab v2.0, you should call .. code-block:: data=loadbj('my_old_data_file.bjd','Endian','B') You are strongly encouraged to convert all pre-v2.9 JSONLab generated BJD or .pmat files using the new format. ============ Introduction ============ JSONLab is an open-source JSON/UBJSON/MessagePack encoder and decoder written completely in the native MATLAB language. It can be used to convert most MATLAB data structures (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 a MATLAB data structure. JSONLab supports both MATLAB and `GNU Octave `_ (a free MATLAB clone). Compared to other MATLAB/Octave JSON parsers, JSONLab is uniquely lightweight, ultra-portable, producing dependable outputs across a wide-range of MATLAB (tested on R2008) and Octave (tested on v3.8) versions. It also uniquely supports BinaryJData/UBJSON/MessagePack data files as binary-JSON-like formats, designed for efficiency and flexibility with loss-less binary storage. As a parser written completely with the native MATLAB language, it is surprisingly fast when reading small-to-moderate sized JSON files (1-2 MB) with simple hierarchical structures, and is heavily optimized for reading JSON files containing large N-D arrays (known as the "fast array parser" in ``loadjson``). 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, 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 roles for storage, exchange and interoperation of large-scale scientific data among the wide-variety of tools. As container-formats, they offer both the flexibility and generality similar to other more sophisticated formats such as `HDF5 `_, but are significantly simpler with a much greater software ecosystem. Towards this goal, we have developed the JData Specification (http://github.com/NeuroJSON/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/NeuroJSON/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 Then open Octave, and type ``pkg load jsonlab`` to enable jsonlab toolbox. ------------------------- Install JSONLab on Debian ------------------------- JSONLab is currently available on Debian Bullseye. To install, you may run .. code:: shell sudo apt-get install octave-jsonlab One can alternatively install ``matlab-jsonlab`` if MATLAB is available. ------------------------- Install JSONLab on Ubuntu ------------------------- JSONLab is currently available on Ubuntu 21.04 or newer as package `octave-jsonlab`. To install, you may run .. code:: shell sudo apt-get install octave-jsonlab For older Ubuntu releases, one can add the below PPA https://launchpad.net/~fangq/+archive/ubuntu/ppa To install, please run .. code:: shell sudo add-apt-repository ppa:fangq/ppa sudo apt-get update to add this PPA, and then use .. code:: shell sudo apt-get install octave-jsonlab to install the toolbox. ``octave-zmat`` will be automatically installed. ------------------------------ 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; it also provides three equivalent pairs -- ``loadbj/savebj`` for binary JData, ``loadubjson/saveubjson`` for UBJSON 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 MATLAB data structures to their easy-to-serialized forms according to the JData specifications. The detailed help information can be found in the ``Contents.m`` file. In JSONLab 2.9.8 and later versions, a unified file loading and saving interface is provided for JSON, binary JSON and HDF5, including ``loadjd`` and ``savejd`` for reading and writing below files types: - JSON based files: ``.json``, ``.jdt`` (text JData file), ``.jmsh`` (text JMesh file), ``.jnii`` (text JNIfTI file), ``.jnirs`` (text JSNIRF file) - BJData based files: ``.bjd``, ``.jdb`` (binary JData file), ``.bmsh`` (binary JMesh file), ``.bnii`` (binary JNIfTI file), ``.bnirs`` (binary JSNIRF file), ``.pmat`` (MATLAB session file) - UBJSON based files: ``.ubj`` - MessagePack based files: ``.msgpack`` - HDF5 based files: ``.h5``, ``.hdf5``, ``.snirf`` (SNIRF fNIRS data files) - require `EasyH5 toolbox `_ In the below section, we provide a few examples on how to us each of the core functions for encoding/decoding JSON/Binary JSON/MessagePack data. ---------- savejson.m ---------- .. code-block:: 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]); % convert any matlab variables to JSON (variable name is used as the root name) savejson(jsonmesh) % convert matlab variables to JSON with a root-name "jmesh" savejson('jmesh',jsonmesh) % an empty root-name directly embed the data in the root {} % the compact=1 flag prints JSON without white-space in a single-line savejson('',jsonmesh,'Compact',1) % if 3 inputs are given, the 3rd parameter defines the output file name savejson('jmesh',jsonmesh,'outputfile.json') % param/value pairs can be provided after the 2nd input to customize outputs % if you want to use params/values and save JSON to a file, you must use the 'filename' to set output file savejson('',jsonmesh,'FileName','outputfile2.json','ArrayIndent',0,'FloatFormat','\t%.5g') % jsonlab utilizes JData annotations to encode complex/sparse ND-arrays savejson('cpxrand',eye(5)+1i*magic(5)) % when setting 'BuiltinJSON' to 1, savejson calls jsonencode.m in MATLAB (R2016+) % or Octave (v7+) to convert data to JSON; this is typically faster, but does not % support all features native savejson offers savejson('cpxrand',eye(5)+1i*magic(5), 'BuiltinJSON', 1) % JData annotations also allows one to compress binary strongly-typed data and store in the JSON % gzip/zlib are natively supported in MATLAB and Octave; using ZMat toolbox, one can use lz4, lzma, blosc2 etc compressors savejson('ziparray',eye(10),'Compression','zlib','CompressArraySize',1) % 'ArrayToStruct' flag forces all arrays to use the JData ND array annotations to preserve types savejson('',jsonmesh,'ArrayToStruct',1) % JData supports compact storage of special matrices using the '_ArrayShape_' annotation savejson('',eye(10),'UseArrayShape',1) ---------- loadjson.m ---------- .. code-block:: % loadjson can directly parse a JSON string if it starts with "[" or "{", here is an empty object loadjson('{}') % loadjson can also parse complex JSON objects in a string form dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}') % if the input is a file name, loadjson reads the file and parse the data inside dat=loadjson(['examples' filesep 'example1.json']) % param/value pairs can be used following the 1st input to customize the parsing behavior dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',0) % if a URL is provided, loadjson reads JSON data from the URL and return the parsed results, % similar to webread, except loadjson calls jdatadecode to decode JData annotations dat=loadjson('https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json') % using the 'BuildinJSON' flag, one can use the built-in jsondecode.m in MATLAB (R2016+) % or Octave (7.0+) to parse the JSON data for better speed, note that jsondecode encode % key names differently compared to loadjson dat=loadjson('{"_obj":{"string":"value","array":[1,2,3]}}', 'builtinjson', 1) % when the JSON data contains long key names, one can use 'UseMap' flag to % request loadjson to store the data in a containers.Map instead of struct (key name limited to 63) dat=loadjson('{"obj":{"an object with a key longer than 63":"value","array":[1,2,3]}}', 'UseMap', 1) % loadjson can further download the linked data pointed by _DataLink_ tag, and merge with the parent dat=loadjson('{"obj":{"_DataLink_":"https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json"},"array":[1,2]}','maxlinklevel',1) % a JSONPath can be attached to the URL to retrieve a sub element dat=loadjson('{"obj":{"_DataLink_":"https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json:$.address.city"},"array":[1,2]}','maxlinklevel',1) % loadjson can optionally return a JSON-memory-map object, which defines each JSON element's % memory buffer offset and length to enable disk-map like fast read/write operations [dat, mmap]=loadjson('{"obj":{"key":"value","array":[1,2,3]}}') % if set 'mmaponly' to 1, loadjson only returns the JSON-mmap structure mmap=loadjson('{"obj":{"key":"value","array":[1,2,3]}}', 'mmaponly', 1) -------- savebj.m -------- .. code-block:: % savebj works almost exactly like savejson, except that the output is the more compact binary JSON a={single(rand(2)), struct('va',1,'vb','string'), 1+2i}; savebj(a) % customizing the root-name using the 1st input, and the 3rd input setting the output file savebj('rootname',a,'testdata.ubj') % enabling the 'debug' flag to allow printing binary JSON in text-form, helping users to run tests or troubleshoot savebj('rootname',a, 'debug',1) % like savejson, savebj also allow data compression for even more compact storage savebj('zeros',zeros(100),'Compression','gzip') % binary JSON does not need base64-encoding, therefore, the output can be ~33% smaller than text-based JSON [length(savebj('magic',magic(100),'Compression','zlib')), length(savejson('magic',magic(100),'Compression','zlib'))] % savebj can output other popular binary JSON formats, such as MessagePack or UBJSON savebj('mesh',a,'FileName','meshdata.msgpk','MessagePack',1) % same as calling savemsgpack savebj('mesh',a,'FileName','meshdata.ubj','UBJSON',1) % same as calling saveubjson -------- loadbj.m -------- .. code-block:: % similarly, loadbj does almost exactly the same as loadjson, but it parses binary JSON instead obj=struct('string','value','array',single([1 2 3]),'empty',[],'magic',uint8(magic(5))); ubjdata=savebj('obj',obj); % loadbj can load a binary JSON (BJData - a derived format from UBJSON) object from a buffer dat=loadbj(ubjdata) % you can test if loadbj parsed object still matches the data saved using savebj class(dat.obj.array) isequaln(obj,dat.obj) % similarly, savebj/loadbj can compress/decompress binary array data using various compressors dat=loadbj(savebj('',eye(10),'Compression','zlib','CompressArraySize',1)) % if given a path to a binary JSON file (.jdb,.bnii,.pmat,.jmsh,...), it opens and parses the file dat=loadbj('/path/to/a/binary_json.jdb'); % loadbj can directly load binary JSON data files from URL, here is a binary-JSON based NIfTI file dat=loadbj('https://neurojson.org/io/stat.cgi?action=get&db=abide&doc=CMU_b&file=0a429cb9101b733f594eefc1261d6985-zlib.bnii') % similar to loadjson, loadbj can also return JSON-memory-map to permit disk-map % like direct reading/writing of specific data elements [dat, mmap]=loadbj(ubjdata) mmap=loadbj(ubjdata, 'mmaponly', 1) ------------- jdataencode.m ------------- .. code-block:: % jdataencode transforms complex MATLAB data structures (ND-array, sparse array, complex arrays, % table, graph, containers.Map etc) into JSON-serializable forms using portable JData annotations % here, we show how to save a complex-valued sparse array using JSON JData annotations testdata = struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5)); jd=jdataencode(testdata) savejson('',jd) % when setting 'annotatearray' to 1, jdataencode uses _ArrayType_/_ArraySize_/_ArrayData_ % JData tags to store ND array to preserve data types; use 'prefix' to customize variable name prefix encodedmat=jdataencode(single(magic(5)),'annotatearray',1,'prefix','x') % when setting 'usearrayshape' to 1, jdataencode can use _ArrayShape_ to encode special matrices encodedtoeplitz=jdataencode(uint8(toeplitz([1,2,3,4],[1,5,6])),'usearrayshape',1) ------------- jdatadecode.m ------------- .. code-block:: % jdatadecode does the opposite to jdataencode, it recognizes JData annotations and convert % those back to MATLAB native data structures, such as ND-arrays, tables, graph etc rawdata=struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5)); jd=jdataencode(rawdata) newjd=jdatadecode(jd) % we can test that the decoded data are the same as the original isequaln(newjd,rawdata) % if one uses jsondecode to parse a JSON object, the output JData annotation name prefix is different % jsondecode adds "x_" as prefix rawdecode_builtin = jsondecode(savejson('',rawdata)); rawdecode_builtin.a finaldecode=jdatadecode(rawdecode_builtin) % in comparison, loadjson calls encodevarname.m, producing "x0x5F_" as prefix (hex for '_') % encodevarname encoded names can be reversed to original decodevarname.m rawdecode_jsonlab = loadjson(savejson('',rawdata), 'jdatadecode', 0); rawdecode_jsonlab.a finaldecode=jdatadecode(rawdecode_jsonlab) -------- savejd.m -------- .. code-block:: % savejd is a unified interface for savejson/savebj/savemsgpack/saveh5 depending on the output file suffix a={single(rand(2)), struct('va',1,'vb','string'), 1+2i}; savejd('', a, 'test.json') savejd('', a, 'test.jdb') savejd('', a, 'test.ubj') savejd('', a, 'test.h5') -------- loadjd.m -------- .. code-block:: % loadjd is a unified interface for loadjson/loadbj/loadmsgpack/loadh5/load/loadjnifti depending on the input file suffix % supported types include .json,.jnii,.jdt,.jmsh,.jnirs,.jbids,.bjd,.bnii,.jdb,.bmsh,.bnirs,.ubj,.msgpack, % .h5,.hdf5,.snirf,.pmat,.nwb,.nii,.nii.gz,.tsv,.tsv.gz,.csv,.csv.gz,.mat,.bvec,.bval; input can be an URL data = loadjd('test.json'); data = loadjd('test.jdb'); data = loadjd('test.ubj'); data = loadjd('test.h5'); data = loadjd('file:///path/to/test.jnii'); data = loadjd('https://neurojson.org/io/stat.cgi?action=get&db=abide&doc=CMU_b&file=0a429cb9101b733f594eefc1261d6985-zlib.bnii'); --------- jsonget.m --------- .. code-block:: % loadjson/loadbj JSON-memory-map (mmap) output returned by loadjson or loadbj % each mmap contains a pair of JSONPath and two numbers [offset, length] of the object in bytes in the buffer/file jsonstr = '{"obj":{"string":"value","array":[1,2,3]}}'; mmap=loadjson(jsonstr, 'mmaponly', 1) % mmap = [ ["$",[1,42]], ["$.obj",[8,34]], ["$.obj.string",[18,7]], ["$.obj.array",[34,7]] ] % this means there are 4 objects, root '$', with its content starting byte 1, with a length of 42 bytes; % content of object '$.obj' starts byte 8, with a length of 34 bytes mmap{:} % using the above mmap, jsonget can return any raw data without needing to reparse jsonstr % below command returns '[1,2,3]' as a string by following the offset/length data in mmap jsonget(jsonstr, mmap, '$.obj.array') % you can request multiple objects by giving multiple JSONPath keys jsonget(jsonstr, mmap, '$.obj', '$.obj.string') % you can request multiple objects by giving multiple JSONPath keys jsonget(jsonstr, mmap, '$.obj', '$.obj.string') % jsonget not only can fast reading a JSON string buffer, it can also do disk-map read of a file mmap = loadjson('/path/to/data.json', 'mmaponly', 1); jsonget('/path/to/data.json', mmap, '$.obj') --------- jsonset.m --------- .. code-block:: % using JSON mmap, one can rapidly modify the content of JSON object pointed by a path jsonstr = '{"obj":{"string":"value","array":[1,2,3]}}'; mmap=loadjson(jsonstr, 'mmaponly', 1) % we can rewrite object $.obj.array by changing its value '[1,2,3]' to a string "test" % this returns the updated jsonstr as '{"obj":{"string":"value","array":"test" }}' % the new value of a key must not have longer bytes than the original value jsonset(jsonstr, mmap, '$.obj.array', '"test"') % one can change multiple JSON objects, below returns '{"obj":{"string":"new" ,"array":[] }}' jsonset(jsonstr, mmap, '$.obj.string', '"new"', '$.obj.array', '[]') % if mmap is parsed from a file, jsonset can perform disk-map like fast writing to modify the json content mmap = loadjson('/path/to/data.json', 'mmaponly', 1); jsonset('/path/to/data.json', mmap, '$.obj.string', '"new"', '$.obj.array', '[]') ---------- jsonpath.m ---------- .. code-block:: % JSONPath is a widely supported standard to index/search a large struct, such as those loaded from a JSON file % the jsonpath.m function implements a subset of the features % the below command returns the value of obj.key subfield, which is "value" obj = loadjson('{"obj":{"key":"value1","array":[1,2,3],"sub":{"key":"value2","array":[]}}}'); jsonpath(obj, '$.obj.key') % using [] operator, one can also index array elements, index start from 0; the output below is 2 jsonpath(obj, '$.obj.array[1]') % [] operator supports range, for example below commands yields [1,2] jsonpath(obj, '$.obj.array[0:1]') % a negative index in [] counting elements backwards, -1 means the last element jsonpath(obj, '$.obj.array[-1]') % jsonpath.m supports JSONPath's deep-scan operator '..', it traverses through the struct % and find all keys following .., here the output is {"value1", "value2"} jsonpath(obj, '$.obj..key') % you can further concatenate JSONPath operators to select outputs from the earlier ones, this outputs {'value2'} jsonpath(obj, '$.obj..key[1]') % instead of .keyname, you can use [keyname], below command is the same as above jsonpath(obj, '$[obj]..[key][1]') % one can escape special char, such as ".", in the key using special\.key or [special.key] jsonpath(obj, '$.obj.special\.key.sub') ----------- jsoncache.m ----------- .. code-block:: % the _DataLink_ annotation in the JData specification permits linking of external data files % in a JSON file - to make downloading/parsing externally linked data files efficient, such as % processing large neuroimaging datasets hosted on http://neurojson.io, we have developed a system % to download files on-demand and cache those locally. jsoncache.m is responsible of searching % the local cache folders, if found the requested file, it returns the path to the local cache; % if not found, it returns a SHA-256 hash of the URL as the file name, and the possible cache folders % % When loading a file from URL, below is the order of cache file search paths, ranking in search order % % global-variable NEUROJSON_CACHE | if defined, this path will be searched first % [pwd '/.neurojson'] | on all OSes % /home/USERNAME/.neurojson | on all OSes (per-user) % /home/USERNAME/.cache/neurojson | if on Linux (per-user) % /var/cache/neurojson | if on Linux (system wide) % /home/USERNAME/Library/neurojson| if on MacOS (per-user) % /Library/neurojson | if on MacOS (system wide) % C:\ProgramData\neurojson | if on Windows (system wide) % % When saving a file from a URL, under the root cache folder, subfolders can be created; % if the URL is one of a standard NeuroJSON.io URLs as below % % https://neurojson.org/io/stat.cgi?action=get&db=DBNAME&doc=DOCNAME&file=sub-01/anat/datafile.nii.gz % https://neurojson.io:7777/DBNAME/DOCNAME % https://neurojson.io:7777/DBNAME/DOCNAME/datafile.suffix % % the file datafile.nii.gz will be downloaded to /home/USERNAME/.neurojson/io/DBNAME/DOCNAME/sub-01/anat/ folder % if a URL does not follow the neurojson.io format, the cache folder has the below form % % CACHEFOLDER{i}/domainname.com/XX/YY/XXYYZZZZ... % % where XXYYZZZZ.. is the SHA-256 hash of the full URL, XX is the first two digit, YY is the 3-4 digits % below command searches CACHEFOLDER{i}/io/openneuro/ds000001/sub-01/anat/, and return the path/filename [cachepath, filename] = jsoncache('https://neurojson.org/io/stat.cgi?action=get&db=openneuro&doc=ds000001&file=sub-01/anat/sub-01_inplaneT2.nii.gz&size=669578') % this searches CACHEFOLDER{i}/raw.githubusercontent.com/55/d2, and the filename is 55d24a4bad6ecc3f5dc4d333be728e01c26b696ef7bc5dd0861b7fa672a28e8e.json [cachepath, filename] = jsoncache('https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json') % this searches cachefolder{i}/io/adhd200/Brown folder, and look for file Brown.json [cachepath, filename] = jsoncache('https://neurojson.io:7777/adhd200/Brown') % this searches cachefolder{i}/io/openneuro/ds003805 folder, and look for file ds003805.json [cachepath, filename] = jsoncache('https://neurojson.io:7777/openneuro/ds003805') ----------- jdlink.m ----------- .. code-block:: % jdlink dynamically downloads, caches and parses data files from one or multiple URLs % jdlink calls jsoncache to scan cache folders first, if a cache copy exists, it loads the cache first % here we download a dataset from NeuroJSON.io, containing many linked data files data = loadjson('https://neurojson.io:7777/openneuro/ds000001'); % we now use jsonpath to scan all linked resources under subfolder "anat" alllinks = jsonpath(data, '$..anat.._DataLink_') % let's download all linked nifti files (total 4) for sub-01 and sub-02, and load the files as niidata niidata = jdlink(alllinks, 'regex', 'sub-0[12]_.*\.nii'); % if you just want to download/cache all files and do not want to parse the files, you can run jdlink(alllinks); --------- 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. ======================================== In-memory data compression/decompression ======================================== JSONLab contains a set of functions to perform in-memory buffer data compression and decompression ---------------------------------------------------------------------------- Data Compression: {zlib,gzip,base64,lzma,lzip,lz4,lz4hc,zstd,blosc2}encode.m ---------------------------------------------------------------------------- .. code-block:: % MATLAB running with jvm provides zlib and gzip compression natively % one can also install ZMat (https://github.com/NeuroJSON/zmat) to do zlib(.zip) or gzip (.gz) compression output = zlibencode(diag([1,2,3,4])) [output, info] = zlibencode(uint8(magic(8))) outputbase64 = char(base64encode(output(:))) % char, numeric and logical ND-arrays are acceptable inputs to the compression functions [output, info] = gzipencode(uint8(magic(8))) % setting a negative integer between -1 to -9 to set compression level: -9 being the highest [output, info] = zlibencode(uint8(magic(8)), -9) % other advanced compressions are supported but requires ZMat % lzma offers the highest compression rate, but slow compresison speed output = lzmaencode(uint8(magic(8))) % lz4 offers the fastest compression speed, but slightly low compression ratio output = lz4encode(peaks(10)) output = lz4hcencode(uint8(magic(8))) % zstd has a good balanced speed/ratio, similar to zlib output = zstdencode(peaks(10)) output = zstdencode(peaks(10), -9) ----------------------------------------------------------------------------- Data Deompression: {zlib,gzip,base64,lzma,lzip,lz4,lz4hc,zstd,blosc2}decode.m ----------------------------------------------------------------------------- .. code-block:: % passing on a compressed byte-array buffer to *decode function decompresses the buffer [compressed, info] = zlibencode(eye(10)); % the decompressed buffer is a byte-array decompressd = zlibdecode(compressed); % to fully recover the original data structure, one most use the info struct returned by the compressor decompressd = zlibdecode(compressed, info) % if one passes a zlib compressed buffer to a different decompressor, an error is reported decompressd = gzipdecode(compressed, info) outputbase64 = char(base64decode(base64encode('jsonlab test'))) ======================================== 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 ``.pmat``. 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 .pmat file to share matlab variables include * a ``.pmat`` file can be 50% smaller than a ``.mat`` file when using ``jsave(..., "compression","lzma")``; the only drawback is longer saving time. * a ``.pmat`` 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 ``.pmat`` files are largely compatible with BJData's parsers available at https://neurojson.org/#software * a ``.pmat`` file is quasi-human-readable, one can see the internal data fields even in a command line, for example using ``strings -n 2 file.pmat | 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:: jsave % save the current workspace to default.pmat jsave mydata.pmat jsave('mydata.pmat','vars',{'var1','var2'}) jsave('mydata.pmat','compression','lzma') jsave('mydata.json','compression','gzip') ---------- jload.m ---------- .. code-block:: jload % load variables from default.pmat to the current workspace jload mydata.pmat % load variables from mydata.pmat vars=jload('mydata.pmat','vars',{'var1','var2'}) % return vars.var1, vars.var2 jload('mydata.pmat','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, .pmat`` etc). Using binary JData files are expected to produce much smaller file sizes and faster parsing, while maintaining 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/NeuroJSON/pyjdata * **bjdata** PyPi: https://pypi.org/project/bjdata/ ; Github: https://github.com/NeuroJSON/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:: import jdata as jd import numpy as np data1=jd.loadt('myfile.json'); data2=jd.loadb('myfile.bjd'); data3=jd.loadb('myfile.pmat'); 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/NeuroJSON/jnifti or **jsnirf**: https://github.com/NeuroJSON/jsnirf) 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 consistent 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 user forum to ask any question you may have regarding JSONLab: https://github.com/orgs/NeuroJSON/discussions/categories/neurojson-json-format-specifications-and-parsers ========================== 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.9.8/base64decode.m000066400000000000000000000026001460134415400155700ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/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.9.8/base64encode.m000066400000000000000000000027041460134415400156070ustar00rootroot00000000000000function 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/NeuroJSON/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\n]', ''); jsonlab-2.9.8/blosc2decode.m000066400000000000000000000036511460134415400156770ustar00rootroot00000000000000function varargout = blosc2decode(varargin) % % output = blosc2decode(input,codec) % output = blosc2decode(input) % or % output = blosc2decode(input,info) % % Decompressing an blosc2-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/NeuroJSON/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store blosc2-compressed data % codec: if the 2nd input is a string, it is treated as a compression method that % blosc2 supports, it can be one of: % 'blosc2blosclz', 'blosc2lz4', 'blosc2lz4hc', 'blosc2zlib' and 'blosc2zstd' % if no codec is specified, 'blosc2blosclz' method is assumed % info (optional): a struct produced by the zmat/blosc2encode 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]=blosc2encode(eye(10)); % orig=blosc2decode(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 >= 2 && ischar(varargin{2})) [varargout{1:nargout}] = zmat(varargin{1}, 0, varargin{2:end}); elseif (nargin > 1) [varargout{1:nargout}] = zmat(varargin{1}, varargin{2:end}); else [varargout{1:nargout}] = zmat(varargin{1}, 0, 'blosc2blosclz', varargin{2:end}); end else error('you must install ZMat toolbox to use this feature: http://github.com/NeuroJSON/zmat'); end jsonlab-2.9.8/blosc2encode.m000066400000000000000000000024721460134415400157110ustar00rootroot00000000000000function varargout = blosc2encode(varargin) % % output = blosc2encode(input) % or % [output, info] = blosc2encode(input) % % Compress a string or a numerical array using LZ4-compression % % This function depends on the ZMat toolbox (http://github.com/NeuroJSON/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]=blosc2encode(eye(10)); % orig=blosc2decode(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 && ischar(varargin{2})) [varargout{1:nargout}] = zmat(varargin{1}, 1, varargin{2:end}); else [varargout{1:nargout}] = zmat(varargin{1}, 1, 'blosc2blosclz', varargin{2:end}); end return else error('you must install ZMat toolbox to use this feature: http://github.com/NeuroJSON/zmat'); end jsonlab-2.9.8/decodevarname.m000066400000000000000000000051111460134415400161350ustar00rootroot00000000000000function 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/NeuroJSON/easyh5 % % License: GPLv3 or 3-clause BSD license, see https://github.com/NeuroJSON/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(strfind(name, '0x')) || 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 if (isunpack && strcmp(name, 'x0x0_')) newname = ''; return end 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.9.8/encodevarname.m000066400000000000000000000045531460134415400161600ustar00rootroot00000000000000function 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 truncated 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/NeuroJSON/easyh5 % % License: GPLv3 or 3-clause BSD license, see https://github.com/NeuroJSON/easyh5 for details % if (~isvarname(str(1))) if (exist('unicode2native', 'builtin')) str = sprintf('x0x%s_%s', sprintf('%X', unicode2native(str(1))), str(2:end)); else str = sprintf('x0x%X_%s', char(str(1)) + 0, str(2:end)); 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 = find(~ismember(str, ['0':'9', 'A':'Z', 'a':'z', '_'])); % 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 jsonlab-2.9.8/examples/000077500000000000000000000000001460134415400150025ustar00rootroot00000000000000jsonlab-2.9.8/examples/demo_jsonlab_basic.m000066400000000000000000000355641460134415400207720ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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 empty 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); 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.9.8/examples/demo_msgpack_basic.m000066400000000000000000000321341460134415400207550ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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 empty 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.9.8/examples/demo_ubjson_basic.m000066400000000000000000000325211460134415400206300ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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 empty 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.9.8/examples/example1.json000066400000000000000000000006641460134415400174170ustar00rootroot00000000000000 { "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.9.8/examples/example2.json000066400000000000000000000011071460134415400174110ustar00rootroot00000000000000{ "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.9.8/examples/example3.json000066400000000000000000000004201460134415400174070ustar00rootroot00000000000000{"menu": { "id": "file", "value": "_&File", "popup": { "menuitem": [ {"value": "_&New", "onclick": "CreateNewDoc(\"'\\\"Untitled\\\"'\")"}, {"value": "_&Open", "onclick": "OpenDoc()"}, {"value": "_&Close", "onclick": "CloseDoc()"} ] } }} jsonlab-2.9.8/examples/example4.json000066400000000000000000000010631460134415400174140ustar00rootroot00000000000000[ { "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.9.8/examples/jsonlab_basictest.matlab000066400000000000000000000543231460134415400216640ustar00rootroot00000000000000 < 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 empty 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: [1x3 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: {[1x1 struct] [1x1 struct] [10.0400 10.1000 11.0400 11.1000]} >> >> %================================================= >> % 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: [2x3 struct] >> >> >> %================================================= % 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 = 1x2 struct array with fields: Format TimeZone Year Month Day Hour Minute Second SystemTimeZone >> >> %================================================= % 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.9.8/examples/jsonlab_selftest.m000066400000000000000000000020331460134415400205170ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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.9.8/examples/jsonlab_selftest.matlab000066400000000000000000000104061460134415400215260ustar00rootroot00000000000000 < 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.9.8/examples/jsonlab_speedtest.m000066400000000000000000000013111460134415400206640ustar00rootroot00000000000000%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % 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.9.8/examples/jsonlab_ubjson_basictest.matlab000066400000000000000000000456331460134415400232500ustar00rootroot00000000000000 < 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-DTû! @ >> json2data = 3.1416 >> >> %================================================= >> % an empty array >> %================================================= >> >> data2json = [] >> ans = {UemptyZ} >> json2data = empty: [] >> >> %================================================= >> % an empty 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 ð? "@ @ $@ $@ @ @ @ $@ @ @ @ @ @ "@ $@ $@ $@21ëÓûä?;lö:h?è?±Ù8,ë?#'æ½½Çç?€o`[?Ù?éN˜É2¸å?àpÃH¢?P¶¹ÎEãí?¶ ²Ä¬ùä?}} >> 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 ð? "@ @ $@ $@ @ @ @ $@ @ @ @ @ @ "@ $@ $@ $@21ëÓûä?;lö:h?è?±Ù8,ë?#'æ½½Çç?€o`[?Ù?éN˜É2¸å?àpÃH¢?P¶¹ÎEãí?¶ ²Ä¬ùä?21ëÓûä¿;lö:h?迱Ù8,ë¿#'æ½½Ç翀o`[?Ù¿éN˜É2¸å¿àpÃH¢¿P¶¹ÎEãí¿¶ ²Ä¬ùä¿}} >> 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[[{UbuzzDš™™™™™ñ?UrexD333333ó?UboDÃÌÌÌÌÌô?UhammUUslinkDÃÌÌÌÌÌ @UpotatoDš™™™™™@UwoodyUUsargeDÃÌÌÌÌÌ@UetchUUlennyUUsqueezeUUwheezyU}{UUbuntu[SUKubuntuSUXubuntuSULubuntu]}[$D#U®Gáz$@333333$@®Gáz&@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.9.8/examples/random_json_joke.m000066400000000000000000000016731460134415400205100ustar00rootroot00000000000000function jokes = random_json_joke(num, url) % this example shows how to use the _DataLink_ annotation defined in the % JData specification % (https://github.com/NeuroJSON/jdata/blob/master/JData_specification.md#data-referencing-and-links) % to define linked JSON/binary JSON data using external files or URL on the % web. In the below example, the jokeapi.dev feed returns a JSON record via % RESTFul URL, the returned record contains a subfield called `joke`, which % can be retrieved via the JSONPath $.joke attached after the URL, separated % by a colon. The general _DataLink_ URL is in the form of "URL:$jsonpath" if (nargin == 0) num = 1; end if (nargin < 2) url = 'https://v2.jokeapi.dev/joke/Programming?type=single'; end joke.(encodevarname('_DataLink_')) = [url ':$.joke']; jurl = savejson('', joke); jokes = cell(1, num); for i = 1:num jokes{i} = loadjson(jurl, 'maxlinklevel', 1); end if (num == 1) jokes = jokes{1}; end jsonlab-2.9.8/fast_match_bracket.m000066400000000000000000000052631460134415400171540ustar00rootroot00000000000000function [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, % including 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.9.8/filterjsonmmap.m000066400000000000000000000032001460134415400163670ustar00rootroot00000000000000function mmap = filterjsonmmap(mmap, patterns, isinclude) % % mmap=filterjsonmmap(mmap, patterns, isinclude) % % filter JSON mmap keys based on inclusive or exclusive string patterns % % authors:Qianqian Fang (q.fang neu.edu) % initially created on 2022/02/13 % % input: % mmap: memory-map returned by loadjson/loadbj of the same data % important: mmap must be produced from the same file/string, % otherwise calling this function may cause data corruption % patterns: a string or a cell array of strings, each string will % be tested to match the JSONPath keys in mmap % isinclude: 1 (default) to include all mmap entries that match at % least one of the patterns, and 0 - exclude those that match % % output: % mmap: a filtered JSON mmap % % examples: % str='{"arr":[[1,2],"a",{"c":2}],"obj":{"k":"test"}}'; % [dat, mmap]=loadjson(str); % savejson('',mmap) % newmmap=filterjsonmmap(mmap,{'arr[1]', 'obj.k'}); % savejson('',newmmap) % % 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) isinclude = 1; end if (nargin > 1 && ~isempty(patterns)) keylist = [mmap{:}]; keylist = keylist(1:2:end); if (~iscell(patterns)) patterns = {patterns}; end mask = zeros(1, length(keylist)); for i = 1:length(patterns) mask = mask + cellfun(@length, strfind(keylist, patterns{i})); end if (isinclude) mmap = mmap(mask > 0); else mmap(mask > 0) = []; end end jsonlab-2.9.8/gendocs.sh000077500000000000000000000034331460134415400151500ustar00rootroot00000000000000#!/bin/sh #============================================================ # JSONLAB inline documentation to wiki converter # # 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_interface="loadjd savejd" func_mmap="jsonget jsonset getfromjsonpath filterjsonmmap" 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 %%=== "#" Interface === print_group $func_interface echo %%=== "#" Memory-map === print_group $func_mmap echo %%=== "#" Compression and decompression === print_group $func_zip echo %%=== "#" Miscellaneous functions === print_group $func_helper jsonlab-2.9.8/genlog.sh000077500000000000000000000000771460134415400150020ustar00rootroot00000000000000#!/bin/sh git log --date=short --pretty='format: %cd [%h] %s' jsonlab-2.9.8/getvarfrom.m000066400000000000000000000013151460134415400155160ustar00rootroot00000000000000function p = getvarfrom(ws, name) % % p=getvarfrom(ws,name) % % get variable value by name from specified work-space % % author: Qianqian Fang, % % input: % ws: name of the work-space, for example, 'base' % name: name string of the variable % % output: % p: the value of the specified variable, if the variable does not % exist, return empty array % % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net) % wsname = ws; if (~iscell(ws)) wsname = cell(1); wsname{1} = ws; end p = []; for i = 1:length(wsname) isdefined = evalin(wsname{i}, ['exist(''' name ''')']); if (isdefined == 1) p = evalin(wsname{i}, name); break end end jsonlab-2.9.8/gzipdecode.m000066400000000000000000000045441460134415400154660ustar00rootroot00000000000000function 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/NeuroJSON/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 nozmat = getvarfrom({'caller', 'base'}, 'NO_ZMAT'); if ((exist('zmat', 'file') == 2 || exist('zmat', 'file') == 3) && (isempty(nozmat) || nozmat == 0)) 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) [varargout{1:nargout}] = octavezmat(varargin{1}, 0, 'gzip'); return 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.9.8/gzipencode.m000066400000000000000000000037161460134415400155000ustar00rootroot00000000000000function 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/NeuroJSON/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 nozmat = getvarfrom({'caller', 'base'}, 'NO_ZMAT'); if ((exist('zmat', 'file') == 2 || exist('zmat', 'file') == 3) && (isempty(nozmat) || nozmat == 0)) [varargout{1:nargout}] = zmat(varargin{1}, 1, 'gzip'); return elseif (isoctavemesh) [varargout{1:nargout}] = octavezmat(varargin{1}, 1, 'gzip'); return end error(javachk('jvm')); input = varargin{1}(:)'; if (ischar(input)) input = uint8(input); elseif (isa(input, 'string')) input = uint8(char(input)); else input = typecast(input, 'uint8'); end input = typecast(input, '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.9.8/images/000077500000000000000000000000001460134415400144315ustar00rootroot00000000000000jsonlab-2.9.8/images/jsonlab-banner.png000066400000000000000000000162661460134415400200450ustar00rootroot00000000000000‰PNG  IHDR@…€€…ëƒzTXtRaw profile type exifxÚ­™a’$© …ÿç)|ÁqA„oàãûSvõìÌîÚÞpWLWuUéé½§œçüëŸ÷ù?¥yªZo£µÄO¼3yÑÓ×ÏxçTßßï/ËçÝ_Þº~¾$¼—|]–l~=çÉûúÛ¾÷Èë×÷ŸþùDúg¡Ïß –ØYxá?Éûòõ~®Ÿ…ÆùzÑF·ŸC]òõ¼?¾¡|þí‘ÖûÞ'êøûùùjdÉ•ŠÈ)¹¤÷wÿŠ Ä?)“çÊï\†|¿SŠ>ïSúDBB~9Þ÷sJ?'è—$¿z~Ÿ}éž|™Ÿ+ÊïrÙ>9âÅŸ~õÏ“ÿ¦ø§Ëˆä×ÚIûÇùü»×û½çët³62Ú>ˆJÏwvâ;\H5jy¿Öxÿ”×ö>Na6%w¶[ú2 ¨£ }Œ1§<“&kM®Ÿ¼³d•U—®¶lõ5ÖÜÀg×­»mÛ}=]¼84áÍÍ»Ÿ'?¦8õèiÇN?ãÌ Ön¹õêm×n¿ãÎUûTõ¿Qµü©š¼•ŠëìGÕx÷1û^"hÔŒŠIÍTÜ¢Z¢f©çZ%*5KC‚Ï„ 5jóxŽŠQÂz²èÍ?j÷[åþRÝí©nò¿*÷Déþ•{(Ýëö'UóˆýVì« #§©Ð}èÃèë)¹‘¡ABê8—skÖ[ÄÎ!c„Öúl½®J`e­<öuwŽéÓ]G®§ŽTž2H@^£uÍ^Ó>çpq¥QÖ$[‰¤`y›'5Ys3ŒÃ+;Óz½è$<Ï-s¬Ûl»-½Ó„C‘.'kÙTÔ”a;tÚrõ~œM´µUs¸TÛ3`GOq I)wÏqiq¤Tº^¶í‘9]íÝÖjÇ¡™×}Í~öðnµ1¼¢ÙîìFÄwm–vîM;»PÝíðžiåÒÐ³Šø~ØZ”–ÒV /c«ž5ÆÚ &èËN£FV™fÃýÊd'VzÚï.—ªñ[*p+ò3Ú^Þv$ŸÞ´®X|À^`ÈXfŽLÅŒŽYE†’ÂÚ2RÍòz“Úª-B);õCÊîr²íX­žGéÎÉW½œym:f鱩7ˆM(üØG†aávÓuF[m®s×ÕìW“²A2›§ZÃi-Ó0¯ö€i2Ï£ÕÔù çÜ{Ê…³Ç¡xMvÍÕ6-8®ƒÌ7_¼ÑY>²žR²ë´:û:ªõ´yÛYÙ£Ev2¿=.]ìÂj™†$:Ý´0h›îÇ44ševPA»F‹ZÂ+´% S©0”w-‹ª;¹¶é#ƒt}¯DS‰Ø˹a¨}goÑAS.A@E»Íb¦‚3=õ-˨îóFÉÉ­³èÆØÈOŸk‘Êså¬Â‰sx*Ýðk+ëî-ä ĉÞò/P%|=×!•HMk>ã®Îi=-8¬r)Ÿ(Gí$h*´v›/ƒ€G¡€çhÛðN+ëõt‘Iú¡Ã÷qPµù$2`mó¢¯kí›§¨hÁô€¯Òuf™NÁxn«åö–ŽÝ4—>'ƒ«ÜÊÉwµ*ðw9hààZ5Úò‚ÏËU{Qö‘cô6”E ¨ú°I5 HÑÐ×A!Dt¸ŽýóªŠÒ·S@#‰H·(,NÓf/²O¢ÐŒ?2ŠÈ7¸€‹ó¥ënð?ÚÚ_c~Î ¢#1.¸3õHyŸ]ÓxÖî#4KRöÌp36èÌnÝþ6,ü—p¡<fní¢M‚NQi7=py*€DŠ9™ ij0z..XË‚ìbwFö3ëE­ŸxF°]H ¿U©Ú ôÒìû€ȈK³9T^ÓZ©YšÎÆÃFC¾W"š”š</žÆÔupnx¿e¿§ƒ_Åè V!qÊŒD5 Øú) 4io ’FOþ|¬•NŸ)TÕr( (šy’ö£Àl±Nª—†E;WƒÙ}ÍP”‰t&â†z{mB7«.ø b€&ø®†J¬%j‰% µéL> ±“JKAï†ä`,!±™‚ YÂ#tx]ÈáBòzÚ®ÄC°®(þ(ÏŠÞBS³¾‹•8á‡j¢˜—á8¨Á⬵³]Œl·Üî$e„uÛ#ÀˆÑ®•Êž(ârÝX$†°‰JÜÄ ȶî\ ¯x 6¯äIéu:ä¶|”ú±¬o[pt«œêë´uâ\¨¿Quà—*·WvGªúIO{ãF&¨À+Vx„ ‚W[¥Íú]·zÂi¿5‡åÁÒœK]2Î#æ~`²qêü…Œçâ’aPX³÷ gë&«Ð‘-l ª3#šŒÔbzRlˆŠT»4º†¹[` úµñ ×að5ØBì?»Ces¦0i¬Ç´ŒI‚ÝG'z…NduÊwûb£½ÏIÃO E DÚi¤3C<;Jœ‹èhÚ°rv¡BÜ ŠUxR„ =š ä8¦#¸.ddçÜt´öŒÉÛíau'”‡P¯4H„K š-j!D€7ÔO@§ÆL»§¾Fçbb×¾ªG»@& 4 Ôì IN *ê¤ßú¡#G,vO× Ò]dd–'¥ôóƒ}‡«ØmñîöØ[yO‚Hm†a’ÍŸ|tÆ4Ñ_Ão†œ6¶â,Dƒ~Ã1n•Éé&R²É‚Âèí¦ö¶ô †½ {œ³á±—h#xcÎmŽ -‡2ÄÀÑ…iÞÙÌÔÙ`çÁ NÚŒ/±öÄÁ’ÇEhRâP #燙§Ë${(ù^¬²È!CU{"AË!Êš&;%šIYŽnpØî;6üô 嚈®£ßX”vq#hû÷Ué*{'1ˆktfz£1¯†­ä$7sw„73ì$ã"8ႇ8Žohª4öÁÎcÍv”¡…½bâG+Báa þèÕÚt0 ¬GÃá³q¯­‡ñÀA÷a Öï!sø6[q«‰ÎH-DÂüƒ8ˆéÐR`¨J ‹SíÑóxÏ0ô^6åiR à°î ˆÛ×þƒOÉ >Kv ºÆŒÓŽ’ÍL%9^DT#ä£ÑÃá$g¶ºSŒj„ e4‘,¤WœŽÜ÷4½—gcºàÇ\“NgX …¦¶ÅJÁµ jǃûhŒ}ŒÂèKÓáj&4îŒ ëˆz ñ›±üâ)©Aí˜V;U¿;2üãíA ÙdZã {BjÌ>pâƒãv%í0uT& DŽ-ï ºF¥˜Žb‡«/|²{Ø~Úb¡1 h DÜûÆØ~©µ/”ël c”)yÔHWÜ=Âýãw8WÇm CÜSC˜5j‰ÃðÙ‚~È:i~ÿ 6?žA¸lt:3€ol!=R¨O;åà¡‚—;`ò€ÃÎ@¾b^ýæ5Z¡KïxDç ºã„Afe hã93HÆfR|Æ(5ÆÇQZl2ôu“˜Œ!þLËÂI9ãG'«e>oHøEchÀ~ü´4eB(qwá2¾Â% :1‘F¦¨È``‘ƒfÒ"c$޹«c^ñÜÆ‡õ€¦iäNw¦Åü>߿иU-á–nL-«<ÐŒ &th懖ñ+ Óƒjä«·g¤:ºJs%òÓc¨œ¨ ÃqY yË÷< : gàðÜý-Wf7ŸprË´0”ƒE6’à~„žÁ¯Õf þ†Þ½ ùçEã¡pø„V5¹GË–í9lÇÚ”r`NKÜc`¬BnL|—ÉŸA.ÇMâÅ(³Â–1ï—/;‹U†ÉXL&Ì̈£&rÆ@.0$æñîm×YŒGxY¤@Ù´Ç5ÚšìÑ3Àö^ü8슴Sqx îÞ>tšÆÍ¸L²ïŽ!Ò"&`4cÀ^°ÃÅØ¡kÊ× ›”™¬-îtñ==ñÐìq3ƒZe ÃõðPW­Ö˜f™Á–á– œ¸ïwrST68n„?›^10»ôw¨“œã8w¤LF_·ZÊ.~aEt=N*Zi½j4RÁoÜù‘°¨‘ µGD ͆ïÐ$½ ÀÙ¦»¢¡{YÊÉÝËžñÿ2Êx ÔÊ0âøÖ¦v,Få}ÉbÛS0!ædyÁ>áŠÙŸ CÇg“,&Ø“™ñØÎ„¸‘Étîq„á"«w¼Æ© d2‹6º?n¦h¯8¹Å,GO2Ý#–øÃ•Fœ¨`”çb’|wèùûeÚ»÷úxþ ©4Ð!–ÃèƒiCCPICC profilexœ}‘=HÃ@Å_ÓE*vqˆP,ˆŠ8jŠP!Ô ­:˜\úM’GÁµààÇbÕÁÅYWWAüqtrRt‘ÿ—ZÄxpÜw÷wï¡Qaš4Ý6ÓÉ„˜Í­Š]¯! ÃËÌ2æ$)ßñu_ïâ<ËÿÜŸ£WÍ[ ˆÄ³Ì0mâ âéMÛà¼Oe%Y%>'3é‚Ä\W<~ã\tYà™Q3“ž'Ž‹ÅV:˜•LxŠ8¦j:å YUÎ[œµJµîÉ_Éë+Ë\§9„$± "ÔPF6â´ê¤XHÓ~ÂÇ?èú%r)ä*ƒ‘cUh]?øüîÖ*LNxI‘~qœ khÖçûØqš'@ð¸ÒÛþj˜ù$½ÞÖbG@ß6pqÝÖ”=àrx2dSv¥ M¡PÞÏè›r@ÿ-гæõÖÚÇé¡®R7ÀÁ!0Z¤ìuŸwwwööï™V?Or—¼¦÷PLTEapÿiiijjjkkkººº»»»¼¼¼9kVtRNS@æØfbKGDˆH pHYsuÚuÚÎ}QOtIMEæ#aª[ ùIDATxÚíÝMr£º`2µwà*îTˆ¸.Y@F{yÚ#¿í¿ÜÄÆú9G:Bà4ŒhCÇBG™1h;|o{¶m³l»Ÿü¦ž~¸oм@4£ÇÉÐü@áÖ>¬µFM,ÐÒ9æó °€^É@Ü V•RÂ9RßÿR¨sòÊN17Óã63¬&¥“îJ@U$P‡Z€6ó=>\2™·(dùh_[Ã߃߉À¤z>¯ èqt¼ð@ýõHjÆäT¾TêÉsú˜ªü@H¥I 4tºTF $ƒ¨õ¥Rÿƒ`1󮈋 sHå’~ Q6‚j3?[=MµÄRSyS‰±ñP(‚ê±ù´~ £´àÝ—Ä<4 @ƒ7•D A µ &¹4ô'ÆØŽÖr@Š tNâK1GxX.›Ôä~ ©ÕBßI:ê;”[G¢©t*¥,@lÝ@¼å¹ý´a:иs¢‰½»kâÈÔBM ¨ÇJ8‡:R€Й ô™$'±ü@ªÌ’íŸÇ‰ ‰Á×€%oˆºZ…áÿnÛýÓÛ?¯,4@#\ZµÀmkìäŒn¯–$îÜAÞF y®x¤*Ì3•«q”G… ¡Z!@•y<3Рÿ¹Î ô¸Ó¹å….+ÚûÎ`çûe%@Ìz»õ²»A°d .ûÇ-z =V8s‰tŽG "žù®@ç :ÔJâ„)@,ØynÐÜžÓ1âÒä2mòj2qçfC˘e€$6ÿÓ,ûj¨+ÔÌ$žˆI§¦§zZˆ­è3H®¨ õfwAXWu*äSë hï¥uÏA#¼íæúi{ Ç'I8‡ª•!ͨ_H)¤#”ˆ¯HU’sUE€þ|ðâúÐNœT¯hÀ¾~y ³§5ðÃöٸ͸8 Û#Mç&]O‹ÝdæªV$üIªùÔ|@¼xíJ¡$ ]´<þÙ½ú€Ôt vf  T#£¥‹ ;‚”ô9Hê@2 Ð>/6œ]csáæÒ+!-¤0 • t¢…ßï( $|#= QèQ·Üö>Љ5qéL…_!A¯ÊéEU@Ç$ C:y‹Ðd1 …Ýz¯^ði¨$ ;ŒóÂЕgD Cf  ô˜tÝ="¯ÆWOž(®•õ‘@#¨õ¾òpË] ˆÁ@,ÃèUO!.ã@=wæ,€jÿýh͈BÔT a. C h´TÑ×{«\@™€¬…$€‰i½„󬧴‹«‚2‘7HN‰ šôqú‘¹4àT¹KîêÀ§ô·Ü±8Ù’€À2n É !pG*s­G Æ‘…kºVò> ÈŠ_§’ “v]Òz)p2èâR#Ðû4 Gã­ ‘òÕù™€Ãá@_÷bP S"èQŸTe€Ô èÝz,‘Ð$Uã%ÙéŸäã‚L]èWb¯á÷á:ˆ ½ˆ«B…º¤@ Æ:Or*QQ×YÙyØT †/…@Œ 2'Yý¡ë²@ôup|@,ãÎÚ G h¼rrTÓ€”1‚ nÍjHŽ :Ä€¸D=|tŒâ¡ft±#è1«$ Èy; OkfÛBl¢à 4í-¡0àv35ˆQ€Ìb9€€Sd¡lT N³ÁA,¾‘j@,P’‰”ToÉ´”rvr5³gba ‘X¥´â€2N Wccè} ×ê]¤‰ ¡2ý („J D Æ˜~e½º@ç éz¢F{€ßªÉ1’u…P ­™}zü!ò5pIyÜ ôÙ#Hoº5é@„>Ð$T@.Û> ð÷ƒŒâÑ@¡%P …s (PE/ã0‰ÄÑl°Œ£q€¾³âÈ"€Î÷) 5˜ëd6u4;õyXÆ•¢ÌIPú”ß³½ê¯Ê4“—síó>Q…»B´"n„É t6€^ËIÐ@­„ˆIß{e³±GhÌÔOÚâÐ q ^èü4Tæ-ï_tŽª¢ú¥jP…±r@ ô ½Çqè¸âb ¾³šL„‰Éý ¿èebHϪ1 ^ ˆE}ÆÉ¿$‚ê²@g[b>¨•žVÂóE ÄžH>!€ŽÎ¡Ù€kA¥ Š j‹ÛèÄŸzÕ^¸‡¸^éL@/ö¯i@ü€°XÎÊ€Z½Ä3Uå®Ðkf gdbÏA'üáV9 ½%¾pò·uÀY%аùé+ê=ƒ¥ ^5jgºfB_ 謣|áâ"ˆÇùU(ØHP¥$$êݾµpÒ%³qÒÜl<‚2‰ œ¨²‚Ùé8ÿ‚ Å}™æD¾9D"vBMd q*PMžù›$±ÿÉ óŸs%ñD &H¿" Ü}Á¦Ã~„°¿·ÈZ $ÌôcC!Ù€º•ÝÓNlÚv€~ÒÃ%úÈZoÝ… 'NäêONì¨ÎA‚M{G5 *0: +òGiBjÝdT~ V„ˆú­u«kê®Ëq¢–p¡…,P …®Äüä{Ej5@Ì[Ø¢.sÁ€®*°Tv) ÓS±¹"èûP-ÄæÌ_¢Ó.6RŸmµ+ëWµ®~ ý¡h@U,XþHK,ôˆ èxãÌ4 ݱÁyµ3j‹ì@ˆB¡£€Ø$ ¨— ˆã@b ‚àžÚ4D7³û§êØ@šãÊ$žŽÝFÎÕµÑ@Ý • yˆÍTƒ_ÚzÒ‚…¹óš2§-oñRT á T?~ èÀÈ•PPÁ¾²žå"®ÕýAŒt&õ ê³F?å»z€ ¸§2äp:Ñ¡zò³(ú2­Ï³ù 1Ò;H#w°ë%¨XÔ?}{{ÞZ듯’íuÔ]ù뀂Oìä {×aèÑŠ·_ÿៜRýJžÀnÊâ²Û–=€‚@û-§  CpZÖ' ´-ÉãÚM]avÛrÙøó}Z9Û€ÖD>sZh¿­ˆ~ê´Оԗ݀Š8yšˆ’çÐr@Ôÿ±-û?5üd(±bIEND®B`‚jsonlab-2.9.8/images/jsonlab-logo.png000066400000000000000000000055321460134415400175320ustar00rootroot00000000000000‰PNG  IHDRXrø•PLTEcolÿiiijjjkkk»»»<~o³tRNS@æØfbKGDˆH pHYsé?é?wœ tIMEä $¸A]| ÁIDATxÚíÝ]’Ü&à–Ûz—nŠ/ÐrW9Ћî•¤²ë‘ ¡›?!Oã™iøÜ ´iý¸ešêd`=¦Ûc}¤ Rý`e÷rœ '¬œyq¾/¬l¹aŽnÞ|$ü|U+û_'~{•žL••ûèx=¦`娺V=–©‹…¹°ÖrVÜk-S_uе”²jKyeñæ©P!ìk-X<Þk)X}b­e+ˆE«],È‚µ)… X¾K|D~eÀZ‹woèÂBcÿ“Ëý«ÿñV?XVæÍ1¹"΢ö¿•k)Q ,:bY=Y¹Î  [k½ëœuc%Æ\ OXTkÒêë—òXhc±1gÊ`Åf/o÷«ËðXþ„2bñ¥'–ä þÂËX_ñr V®õAXƃ%aôaÑáUJPdÀ ‚c =XȗвX¶V,HÇrZñµY%,HÇÒÜâW~raYAGE°Ò‡Ú'õ‚XèÁÂ,8¡B^3b¡ `ë‚VØ9±ðí6 ®3; kÊ4œöf€¬£Æ©­ÄJO9±–jXäøg¬´ì–Ä¢ ²X4°– ¹ö¼ÝYñ4,Ħ¾¿ôŽwÄ¢ =ËÓ(5÷ÆZKbQ–Xì€ÎÀ2c­ `a,z‰±h`±X0°ì¡°,ó8,X!,dB UXÔ6ÖrS,ÅàÅÔWË`©Æò›Æ2Xo¹K°Tó<ÄBwhÁÒUk bA,IÕä´¶±La,¼?€XÌsðj¬·YŸ,ꋊb™°p`ɱÀ;ßDˆEOÁr…– Œe”Xô8,X ,ôÍq’a™Ç`drŽ X=4JM­Åb¡gÆ€‹Xtk,ˆÇB9–rEœf±ŸK·Ç°L9,ÝÜ”f± Ë»Aåƒ?íb¡ážÝ`½*¢ÜCaíbÁÀŠÂ2:,| ¦bу°À=d:°²bÁ±Žåp`y± Ë ,>ë0¬7°Ê`Á±`` ¬2X(Ãp¯,ö\,ûY*3°Ø ¬åÅ‚•ŠEa,X«Œ žϧŷ³VK¶¼Šc1ëõx,ðÝH[XÞ©öÍaåZ·ç¸”;†±(ŒR¬ZÏ:”Ár>ÍíÀÂ,X -M`Ù÷3®©æ/P„•2…®*–§_Ê=KÓ¸û)ËÜ ë`qX&¼¤‘Ë´åzðJ¶È­`ý' ÖÃZ“±Þ7:ŒÆ‚XT+¶qÅÖâÂåà9,Ì•’ãÚXÞÏ¢°LXp{¬)7Vàb(Û‘‡ÜÍÿXK“XÔÖ’ŒÅoQäf·{%²`Ågy­…E>,¸k­‡…âM=ˆÿ·oŒKÙ(Çš2cQÐ<;ö¹n‰‹c-µêwK%ìÁ 'cQáÒ”¼wV <g¸!UÿKÖXXÈdÛÿptiX‘²”ý£ÅÍó»: ¨k^8¼ WÔS–½‚™ÿØ@½›uBeYžrí³µ'äôP,ýV¡‘ßékøÊc°Ô;Ùª÷Cî:´ü’i ên°øP™²mnÞM9<¬ðìÐ:X>_ž„5%bŒÐ’b-ÏšR°fÒ‚Q冕\ †•\ †•\ FÝ.¯åa„•<¸`Ä•<¶F1ÌP ¬5¦Cá¦Ãh”ª°–QÇt™éu¤þ¬×ƒøwÞ)už§Q®þ,‡–µtïÏ{aùvvHíV^Ù“}Ë=™ôz,…ŤÃê0²t9ÁßZ'û£¬Iy… ß+vs¹–ºé4…¾ðuŠï½ÃIßÌœ¤X½CqÎEZÒ“Ý+êöEˆ½cEÝ-®“ý¼=Öù÷G>w,Á¢î±"o½ `í{^Òbõûc;\|X¿œ'Û?Òv<Îì~Nïþþ3;m ˜ž®AX ]'›UXóéÝÝ‹šVâÆÄÀ¬©Vô¬°ÅõãÿbÃAÖ^ËšéiaÅOaýJÄÚ«b‹ÜXëÇëdn¬9†°Œ‹.ÅBÖv°Œç÷CÊ„rs:Ö|y±Š¬ëð-ÖVË‚1X»«¸ÅB9ÖÛyÀ‚°æšXÈ.}×öÕ0„õùÎÀz¯´DXûÀ²Zå°Ì#°æXt?¬Í‡5¬Ùªµ?1æ*Xô ¬- uXÔÖîkN•Áv=æf±v kã:æ¡&6‰õVí-bAƒX›kOÃ2+‹ü£;bý.çÌ¿Œrb ‹šÂ‚&±$¥ð:¬ÝU.¬- %X²?êcmg kË…ÜŽ*ÒÍn¯Ç²›žû…XÐÖNƒXt¬=Ëh°àÆXs>,’`A³X3sS3—Æb÷C‚ö°NWA rcA+4#±¬=ŒµUÂjîj¸×ÅB–iëhÖÌÂc]ŸŠu¼0òXÔÖÜ2–¹%Öv†KÇB 5Œ…±ŒËÜ k.Eö×D¡uȱæ\XÀmh~5Ö&ÃÚŠc ¶‹Y°ÐµIµ Å:<£<3Ä2~,j V6,à'°è° ˆMbmÇÙ„e±LGX›…uúg^,d¶ŽÙåp`55«±¶å賚ù¥Œ"°Üw×c­7Â2qXë%XÀcí‹ÁÚÄXûÀ*ŽezÀší§p«bQXóÀÊ€µ= ¸þ½¼XXky –©5ÅcÍ Ö>°,P`íõ°è™X¦Y¬EƒV-U‹n…ån7Í×a…ûà§V±øÎ¾,ûÅ.4ÍŒöt‚µ•Æ2ƒ¬9±Ö XûuX…ïv”_ÄšÓ±èqX»Ë(°PÙrHÅZòaA)¬Ã{:¬©1¬ù:,Sk½ë˜e–ÑVYú ¡§ Xg9–3ÞœX¢gJ3c-7Â2 |ZyÊŒµ¦bí‚ †‰X‹µæÆZ:ÀÊ"n¯V*Ö®Å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.9.8/jdatadecode.m000066400000000000000000000505651460134415400156040ustar00rootroot00000000000000function 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/NeuroJSON/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 % MaxLinkLevel: [0|int] When expanding _DataLink_ pointers, % this sets the maximum level of recursion % 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 converted 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); opt.maxlinklevel = jsonopt('MaxLinkLevel', 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 (ismember(zipmethod, {'zlib', 'gzip', 'lzma', 'lzip', 'lz4', 'lz4hc', 'base64'}) || ~isempty(regexp(zipmethod, '^blosc2', 'once'))) decodeparam = {}; if (~isempty(regexp(zipmethod, '^blosc2', 'once'))) decompfun = @blosc2decode; decodeparam = {zipmethod}; else decompfun = str2func([zipmethod 'decode']); end arraytype = data(j).(N_('_ArrayType_')); chartype = 0; if (strcmp(arraytype, 'char') || strcmp(arraytype, 'logical')) chartype = 1; arraytype = 'uint8'; end if (needbase64 && strcmp(zipmethod, 'base64') == 0) ndata = reshape(typecast(decompfun(base64decode(data(j).(N_('_ArrayZipData_'))), decodeparam{:}), arraytype), dims); else ndata = reshape(typecast(decompfun(data(j).(N_('_ArrayZipData_')), decodeparam{:}), 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_'))) 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 %% handle data link if (opt.maxlinklevel > 0 && isfield(data, N_('_DataLink_'))) if (ischar(data.(N_('_DataLink_')))) datalink = data.(N_('_DataLink_')); if (regexp(datalink, '\:\$')) ref = regexp(datalink, '^(?[a-zA-Z]+://)*(?.+)(?\:)()*(?(?<=:)\$\d*\.*.*)*', 'names'); else ref = regexp(datalink, '^(?[a-zA-Z]+://)*(?.+)(?\:)*(?(?<=:)\$\d*\..*)*', 'names'); end if (~isempty(ref.path)) uripath = [ref.proto ref.path]; [newdata, fname] = jdlink(uripath); if (exist(fname, 'file')) opt.maxlinklevel = opt.maxlinklevel - 1; if (~isempty(ref.jsonpath)) newdata = jsonpath(newdata, ref.jsonpath); end end end end end %% subfunctions function escaped = N_(str) escaped = [prefix str]; end end jsonlab-2.9.8/jdataencode.m000066400000000000000000000410721460134415400156070ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/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') || isa(item, 'dictionary')) 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 elseif (num == 1) % a single struct names = fieldnames(item); newitem = struct; for i = 1:length(names) newitem.(names{i}) = obj2jd(item.(names{i}), varargin{:}); end else newitem = item; 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 (isa(item, 'dictionary')) newitem = dictionary(); elseif (strcmp(item.KeyType, 'char')) newitem = containers.Map(); else newitem = containers.Map('KeyType', item.KeyType, 'ValueType', 'any'); end if (isa(item, 'dictionary')) for i = 1:length(names) newitem(names(i)) = obj2jd(item(names(i)), varargin{:}); end else for i = 1:length(names) newitem(names{i}) = obj2jd(item(names{i}), varargin{:}); end 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 (uband < size(item, 2) - 1 || lband < size(item, 1) - 1) % band newitem.(N('_ArrayShape_')) = {'band', uband, lband}; newitem.(N('_ArrayData_')) = spdiags(item.', -uband:lband).'; elseif (all(toeplitz(item(:, 1), item(1, :)) == item)) % Toeplitz matrix newitem.(N('_ArrayShape_')) = 'toeplitz'; newitem.(N('_ArrayZipSize_')) = [2, max(size(item))]; newitem.(N('_ArrayData_')) = zeros(2, max(size(item))); newitem.(N('_ArrayData_'))(1, 1:size(item, 2)) = item(1, :); newitem.(N('_ArrayData_'))(2, 1:size(item, 1)) = item(:, 1).'; else % full matrix newitem = rmfield(newitem, N('_ArrayZipSize_')); encoded = 0; end % serialize complex data at last if (encoded && isstruct(newitem) && ~isreal(newitem.(N('_ArrayData_')))) item = squeeze(zeros([2, size(newitem.(N('_ArrayData_')))])); item(1, :) = real(newitem.(N('_ArrayData_'))(:)); item(2, :) = imag(newitem.(N('_ArrayData_'))(:)); newitem.(N('_ArrayZipSize_')) = size(item); newitem.(N('_ArrayData_')) = item; end % wrap _ArrayData_ into a single row vector, and store preprocessed % size to _ArrayZipSize_ (force varargin{1}.usearrayzipsize=true) if (encoded) if (isstruct(newitem) && ~isvector(newitem.(N('_ArrayData_')))) item = newitem.(N('_ArrayData_')); item = permute(item, ndims(item):-1:1); newitem.(N('_ArrayData_')) = item(:).'; else newitem = rmfield(newitem, N('_ArrayZipSize_')); end newitem.(N('_ArrayData_')) = full(newitem.(N('_ArrayData_'))); return end end % no encoding for char arrays or non-sparse real vectors if (isempty(item) || isa(item, 'string') || ischar(item) || varargin{1}.nestarray || ... ((isvector(item) || ndims(item) == 2) && isreal(item) && ~issparse(item) && ... ~varargin{1}.annotatearray)) newitem = item; return end if (isa(item, 'logical')) item = uint8(item); end if (isreal(item)) if (issparse(item)) fulldata = full(item(item ~= 0)); newitem.(N('_ArrayIsSparse_')) = true; newitem.(N('_ArrayZipSize_')) = [2 + (~isvector(item)), length(fulldata)]; if (isvector(item)) newitem.(N('_ArrayData_')) = [find(item(:))', fulldata(:)']; else [ix, iy] = find(item); newitem.(N('_ArrayData_')) = [ix(:)', iy(:)', fulldata(:)']; end else if (varargin{1}.formatversion > 1.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) encodeparam = {}; if (~isempty(regexp(zipmethod, '^blosc2', 'once'))) compfun = @blosc2encode; encodeparam = {zipmethod, 'nthread', jsonopt('nthread', 1, varargin{1}), ... 'shuffle', jsonopt('shuffle', 1, varargin{1}), ... 'typesize', jsonopt('typesize', length(typecast(item(1), 'uint8')), varargin{1})}; else compfun = str2func([zipmethod 'encode']); end 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'), encodeparam{:}); 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 % array 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.9.8/jdatahash.m000066400000000000000000000027561460134415400153030ustar00rootroot00000000000000function key = jdatahash(data, algorithm, varargin) % % key = jdatahash(data) % or % key = jdatahash(data, algorithm) % key = jdatahash(data, algorithm, 'param1', value1, ...) % % computing the hash key for a string or a numeric array (data elements % are serialized in the row-major order first) % % author: Qianqian Fang (q.fang neu.edu) % % input: % data: a string or a numeric array % algorithm: a string denoting the data hashing algorithm (case % insensitive); default is 'sha-256'; supported options include % % for both MATLAB/Octave: 'sha-256' (default), 'sha-1' ,'sha-384', 'sha-512', 'md2', 'md5' % Octave-only: 'md4' % % examples: % sha256key = jdatahash('neurojson') % md5key = jdatahash('reusable data', 'md5') % % 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) algorithm = 'sha-256'; end if (ischar(data)) data = uint8(data); end opt = varargin2struct(varargin{:}); if (jsonopt('rowmajor', 1, opt)) data = permute(data, ndims(data):-1:1); end if (isoctavemesh && exist('hash')) algorithm(algorithm == '-') = []; key = hash(algorithm, char(typecast(data(:).', 'uint8'))); else md = java.security.MessageDigest.getInstance(algorithm); key = sprintf('%2.2x', typecast(md.digest(typecast(data(:), 'uint8')), 'uint8')'); end jsonlab-2.9.8/jdlink.m000066400000000000000000000077211460134415400146240ustar00rootroot00000000000000function varargout = jdlink(uripath, varargin) % % data = jdlink(uripath) % or % [data, fname, cachepath] = jdlink(uripath, 'param1', value1, ...) % % Download linked data files from URLs and store those in cached folders % % author: Qianqian Fang (q.fang neu.edu) % % input: % uripath: a single string or a cell array of strings, containing % the http:// or https:// links pointing to the linked % resources % 'param'/value pairs: (optional) additional options are supported, % including % showlink: [1]: print URL or cached file; 0 do not print. % showsize: [1]: print the total size of the linked files; 0 do not print. % regex: a regular expression that is used to filter the URL % cell array; only those matching the pattern are being % downloaded; this has no effect to a single URL input % % output: % data: a cell array storing the parsed data of each linked file % fname: a cell array listing the path to each locally cached files % cachepath: a cell array listing the cache search path orders % % examples: % data = loadjson('https://neurojson.io:7777/openneuro/ds000001'); % anatfiles = jsonpath(data, '$..anat.._DataLink_'); % data = jdlink(anatfiles, 'regex', 'sub-0[12].*\.nii'); % jsonpath(data, '$..Dim') % % 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{:}); opt.showlink = jsonopt('showlink', 1, opt); opt.showsize = jsonopt('showsize', 1, opt); if (iscell(uripath)) if (isfield(opt, 'regex')) haspattern = cellfun(@(x) isempty(regexp(x, opt.regex, 'once')), uripath); uripath(haspattern) = []; end if (isfield(opt, 'showsize')) totalsize = 0; nosize = 0; for i = 1:length(uripath) filesize = regexp(uripath{i}, '&size=(\d+)', 'tokens'); if (~isempty(filesize) && ~isempty(filesize{1})) totalsize = totalsize + str2double(filesize{1}); else nosize = nosize + 1; end end fprintf('total %d links, %.0f bytes, %d files with unknown size\n', length(uripath), totalsize, nosize); end alloutput = cell(1, nargout); for i = 1:length(uripath) [newdata, fname, cachepath] = downloadlink(uripath{i}, opt); if (nargout > 0) alloutput{1}{end + 1} = newdata; if (nargout > 1) alloutput{2}{end + 1} = fname; if (nargout > 2) alloutput{3}{end + 1} = cachepath; end end end end if (length(uripath) == 1) alloutput = cellfun(@(x) x{1}, alloutput, 'UniformOutput', false); end varargout = alloutput; elseif (ischar(uripath) || isa(uripath, 'string')) [varargout{1:nargout}] = downloadlink(uripath, opt); end %% function [newdata, fname, cachepath] = downloadlink(uripath, opt) newdata = []; [cachepath, filename] = jsoncache(uripath); if (iscell(cachepath) && ~isempty(cachepath)) if (opt.showlink) fprintf(1, 'downloading from URL: %s\n', uripath); end fname = [cachepath{1} filesep filename]; fpath = fileparts(fname); if (~exist(fpath, 'dir')) mkdir(fpath); end if (exist('websave')) websave(fname, uripath); else rawdata = urlread(uripath); fid = fopen(fname, 'wb'); if (fid == 0) error('can not save URL to cache at path %s', fname); end fwrite(fid, uint8(rawdata)); fclose(fid); end newdata = loadjd(fname, opt); elseif (~iscell(cachepath) && exist(cachepath, 'file')) if (opt.showlink) fprintf(1, 'loading from cache: %s\n', cachepath); end fname = cachepath; newdata = loadjd(fname, opt); end jsonlab-2.9.8/jload.m000066400000000000000000000070771460134415400144460ustar00rootroot00000000000000function 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 'default.pmat' % if fname has a '.json' or '.jdt' suffix, a text-based % JSON/JData file will be expected; if the suffix is '.pmat' 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 equivalent % 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 loadbj/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 default.pmat to the 'caller' workspace % jload mydat.pmat % jload('mydat.pmat','vars', {'v1','v2',...}) % load selected variables % varlist=jload('mydat.pmat','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 'default.pmat']; end opt = varargin2struct(varargin{:}); ws = jsonopt('ws', 'caller', opt); 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 try header = loadjd(filename, 'ObjectID', 1, 'MaxBuffer', 65536, varargin{:}); catch header = loadjd(filename, 'ObjectID', 1, varargin{:}); end 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 = loadjd(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.9.8/jsave.m000066400000000000000000000114461460134415400144600ustar00rootroot00000000000000function 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 'default.pmat' % if fname has a '.json' or '.jdt' suffix, a text-based % JSON/JData file will be created (slow); if the suffix is '.pmat' or % '.jdb', a Binary JData (https://github.com/NeuroJSON/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 equivalent % 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.pmat % jsave('mydat.pmat','vars', {'v1','v2',...}) % save selected variables % jsave('mydat.pmat','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 'default.pmat']; end opt = varargin2struct(varargin{:}); if (~isfield(opt, 'nthread')) opt.nthread = 4; end if (~isfield(opt, 'compression')) if (exist('zipmat')) opt.compression = 'blosc2zstd'; else opt.compression = 'zlib'; end end if (~isfield(opt, 'shuffle')) opt.shuffle = 1; end if (~isfield(opt, 'typesize')) opt.typesize = 4; end 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, ... 'BJDataVersion', 'v1_draft-2'); 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 if (nargout == 1) varargout{1} = header; end defaultopt = {'compression', opt.compression, 'nthread', opt.nthread, ... 'shuffle', opt.shuffle, 'typesize', opt.typesize, 'keeptype', 1, 'array2struct', 1}; 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, ... 'UseArrayZipSize', 1, 'MapAsStruct', 1, 'prefix', 'x', defaultopt{:}, 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); elseif (jsonopt('usemmap', 0, opt) == 1) bodyjson = savejd('WorkspaceData', body, ... defaultopt{:}, varargin{:}); header.(encodevarname('_MMap_')) = loadjd(bodyjson, 'mmaponly', 1, varargin{:}); savejd('WorkspaceHeader', header, 'filename', filename, varargin{:}); fid = fopen(filename, 'ab+'); fwrite(fid, bodyjson); fclose(fid); else savejd('WorkspaceHeader', header, 'filename', filename, varargin{:}); savejd('WorkspaceData', body, 'filename', filename, 'append', 1, ... defaultopt{:}, varargin{:}); end jsonlab-2.9.8/json2couch.m000066400000000000000000000051511460134415400154210ustar00rootroot00000000000000function response = json2couch(jsonfile, couchdburl, dbname, docname, options) % % json2couch(jsonfile, servername, dbname, docname, options) % % uploading JSON-encoded data to a CouchDB database (a NoSQL database) % as a document % % author: Qianqian Fang (q.fang neu.edu) % % input: % jsonfile: the path to the .json file % couchdburl: the URL of the CouchDB server, usually it is % http://servername:5984 where servername is your own % server's domain name % dbname: the database for whcih the file is uploaded to, must be % created first % docname: the document name for the uploaded JSON data % options: a options structure created by weboptions(), defining % Username, Password, ContentType when such information is % desired to access the server; by default, % options.ContentType is set to 'json' and % options.RequestMethod is set to 'POST' % % if options is a string, it defines a template for a curl % command, for example 'curl -X PUT -d @$f $u/$d/$s'. % Variables (start with $) are expanded as % $f -> path of the json file (first input) % $u -> couchdb full URL (second input) % $d -> database name (third input) % $s -> document name (forth input) % % examples: % values = inputdlg({'Username:', 'Password:'}); % options = weboptions('ContentType', 'json', 'RequestMethod', 'POST', 'Username',values{1},'Password',values{2}); % json2couch('ds001.json', 'https://example.com:5984', 'bids-samples', 'ds001', options) % json2couch('ds001.json', sprintf('https://%s:%s@example.com:5984', values{1}, values{2}), 'bids-samples', 'ds001', 'curl -X PUT -d @$f $u/$d/$s') % % license: % BSD license, see LICENSE_BSD.txt files for details % % -- this function is part of JBIDS toolbox (https://neurojson.org/#software) % if (nargin < 5) options = weboptions(''); end if (~ischar(options) && ~isa(options, 'string')) options.ContentType = 'json'; options.RequestMethod = 'POST'; response = webwrite([couchdburl '/' dbname '/' docname], fileread(jsonfile), options); else options = regexprep(options, '\$f', ['''' jsonfile '''']); options = regexprep(options, '\$u', couchdburl); options = regexprep(options, '\$d', dbname); options = regexprep(options, '\$s', docname); [status, response] = system(options); if (status ~= 0) error('command failed:\n%s\n', response); end end jsonlab-2.9.8/jsoncache.m000066400000000000000000000151501460134415400153010ustar00rootroot00000000000000function [cachepath, filename] = jsoncache(dbname, docname, filename, domain) % % cachepaths=jsoncache() % [cachepath, filename]=jsoncache(hyperlink) % [cachepath, tf]=jsoncache(filename) % cachepath=jsoncache(dbname, docname, filename, domain) % % return the JSON cache folder where _DataLink_ hyperlinked data files are downloaded % % author: Qianqian Fang (q.fang at neu.edu) % % input: % hyperlink: if a single input is provided, the function check if it is % a hyperlink starting with http://, https:// or ftp://, if % so, it trys to extract the database name, document name and % file name using NeuroJSON's standard link format as % % https://neurojson.org/io/stat.cgi?dbname=..&docname=..&file=..&size=.. % % if the URL does not follow the above format, a SHA-256 hash % will be computed based on the full URL to produce filename; % dbname is set as the first 2 letters of the hash and % docname is set to the 3rd/4th letters of the hash; the % domain name is also extracted from the URL; if the URL % contains the file's suffix, it is appended to the filename. % % if the string does not contain a link, or the link starts % with file://, it is treated as a local file path % dbname: the name of the NeuroJSON database (must exist) % docname: the name of the NeuroJSON dataset document (must exist) % filename: the name of the data file - may contain a relative folder % domain: optional, if not given, 'default' is used; otherwise, user can % specify customized domain name % % output: % cachepaths: if the linked file is found in any of the cache folders, % this returns the full path of the found file as a string; % otherwise, this stores a cell array listing the searched cache % folders in the search order % tf: if a file is found in the cache folder, this returns true; % otherwise, this contains the extracted file name. % % the cached data files will be searched in the following order % % [pwd '/.neurojson'] | on all OSes % /home/USERNAME/.neurojson | on all OSes (per-user) % /home/USERNAME/.cache/neurojson | if on Linux (per-user) % /var/cache/neurojson | if on Linux (system wide) % /home/USERNAME/Library/neurojson| if on MacOS (per-user) % /Library/neurojson | if on MacOS (system wide) % C:\ProgramData\neurojson | if on Windows (system wide) % % if a global variable NEUROJSON_CACHE is set in 'base', it will be % used instead of the above search paths % % % example: % [cachepath, filename] = jsoncache('https://neurojson.org/io/stat.cgi?action=get&db=openneuro&doc=ds000001&file=sub-01/anat/sub-01_inplaneT2.nii.gz&size=669578') % [cachepath, filename] = jsoncache('https://raw.githubusercontent.com/fangq/jsonlab/master/examples/example1.json') % [cachepath, filename] = jsoncache('https://neurojson.io:7777/adhd200/Brown') % [cachepath, filename] = jsoncache('https://neurojson.io:7777/openneuro/ds003805') % % -- this function is part of iso2mesh toolbox (http://iso2mesh.sf.net) % pathname = getenv('HOME'); cachepath = {[pwd filesep '.neurojson']}; if (strcmp(pathname, pwd) == 0) cachepath{end + 1} = [pathname filesep '.neurojson']; end if (ispc) cachepath{end + 1} = [getenv('PROGRAMDATA') filesep 'neurojson']; elseif (ismac) cachepath{end + 1} = [pathname '/Library/neurojson']; cachepath{end + 1} = '/Library/neurojson'; else cachepath{end + 1} = [pathname '/.cache/neurojson']; cachepath{end + 1} = '/var/cache/neurojson'; end if (nargin < 4) domain = 'default'; end if (nargin == 1) link = dbname; if (~isempty(regexp(link, '^file://', 'once')) || isempty(regexp(link, '://', 'once'))) filename = regexprep(link, '^file://', ''); if (exist(filename, 'file')) cachepath = filename; filename = true; return end else if (~isempty(regexp(link, '^https*://neurojson.org/io/', 'once'))) domain = 'io'; else newdomain = regexprep(regexp(link, '^(https*|ftp)://[^\/?#:]+', 'match', 'once'), '^(https*|ftp)://', ''); if (~isempty(newdomain)) domain = newdomain; end end dbname = regexp(link, '(?<=db=)[^&]+', 'match', 'once'); docname = regexp(link, '(?<=doc=)[^&]+', 'match', 'once'); filename = regexp(link, '(?<=file=)[^&]+', 'match', 'once'); if (isempty(filename) && strcmp(domain, 'neurojson.io')) ref = regexp(link, '^(https*|ftp)://neurojson.io(:\d+)*(?/[^\/]+)(?/[^\/]+)(?/[^\/?]+)*', 'names', 'once'); if (~isempty(ref)) if (~isempty(ref.dbname)) dbname = ref.dbname(2:end); end if (~isempty(ref.docname)) docname = ref.docname(2:end); end if (~isempty(ref.filename)) filename = ref.filename(2:end); elseif (~isempty(dbname)) if (~isempty(docname)) filename = [docname '.json']; else filename = [dbname '.json']; end end end end if (isempty(filename)) filename = jdatahash(link); suffix = regexp(link, '\.\w{1,5}(?=([#&].*)*$)', 'match', 'once'); filename = [filename suffix]; if (isempty(dbname)) dbname = filename(1:2); end if (isempty(docname)) docname = filename(3:4); end end end end p = getvarfrom({'caller', 'base'}, 'NEUROJSON_CACHE'); if (nargin == 0 || nargin == 1 || nargin >= 3) if (~isempty(p)) cachepath = [{p}, cachepath{:}]; elseif (exist('dbname', 'var') && exist('docname', 'var')) cachepath = cellfun(@(x) [x filesep domain filesep dbname filesep docname], cachepath, 'UniformOutput', false); end if (exist('filename', 'var') && ~isempty(filename)) for i = 1:length(cachepath) if (exist([cachepath{i} filesep filename], 'file')) cachepath = [cachepath{i} filesep filename]; filename = true; return end end elseif (exist('link', 'var')) [pathname, fname, fext] = fileparts(link); filename = [fname fext]; end if (~isempty(p)) cachepath(2) = []; else cachepath(1) = []; end return end jsonlab-2.9.8/jsonget.m000066400000000000000000000053451460134415400150220ustar00rootroot00000000000000function json = jsonget(fname, mmap, varargin) % % json=jsonget(fname,mmap,'$.jsonpath1','$.jsonpath2',...) % % Fast reading of JSON data records using memory-map (mmap) returned by % loadjson and JSONPath-like keys % % authors:Qianqian Fang (q.fang neu.edu) % initially created on 2022/02/02 % % input: % fname: a JSON/BJData/UBJSON string or stream, or a file name % mmap: memory-map returned by loadjson/loadbj of the same data % important: mmap must be produced from the same file/string, % otherwise calling this function may cause data corruption % '$.jsonpath1,2,3,...': a series of strings in the form of JSONPath % as the key to each of the record to be retrieved; if no paths % are given, all items in mmap are retrieved % % output: % json: a cell array, made of elements {'$.jsonpath_i',json_string_i} % % examples: % str='[[1,2],"a",{"c":2}]{"k":"test"}'; % [dat, mmap]=loadjson(str); % savejson('',dat,'filename','mydata.json','compact',1); % json=jsonget(str,mmap,'$[0]','$[2].c') % json=jsonget('mydata.json',mmap,'$[0]','$[2].c') % % 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 (ischar(fname) || isa(fname, 'string')) if (regexp(fname, '^\s*(?:\[.*\])|(?:\{.*\})\s*$', 'once')) inputstr = fname; elseif (~exist('memmapfile', 'file')) if (exist(fname, 'file')) try fid = fopen(fname, 'rb'); catch end end end end mmap = [mmap{:}]; keylist = mmap(1:2:end); loc = 1:length(keylist); if (length(varargin) >= 1) [tf, loc] = ismember(varargin, keylist); if (any(tf)) keylist = keylist(loc); else keylist = {}; end end json = {}; if (isstruct(fname) || iscell(fname) || isa(fname, 'table') || isa(fname, 'containers.Map')) for i = 1:length(keylist) json{end + 1} = jsonpath(fname, keylist{i}); end if (length(json) == 1) json = json{1}; end return end for i = 1:length(keylist) bmap = mmap{loc(i) * 2}; rec = {'uint8', [1, bmap(2)], 'x'}; if (exist('inputstr', 'var')) json{end + 1} = {keylist{i}, inputstr(bmap(1):bmap(1) + bmap(2) - 1)}; else if (exist('fid', 'var') && fid >= 0) fseek(fid, bmap(1), -1); json{end + 1} = {keylist{i}, fread(fid, bmap(1), 'uint8=>char')}; else fmap = memmapfile(fname, 'writable', false, 'offset', bmap(1), 'format', rec); json{end + 1} = {keylist{i}, char(fmap.Data(1).x)}; end end end if (exist('fid', 'var') && fid > 0) fclose(fid); end jsonlab-2.9.8/jsonlab.prj000066400000000000000000000241101460134415400153270ustar00rootroot00000000000000 jsonlab Qianqian Fang fangqq@gmail.com Northeastern University Compact, portable, robust JSON/binary-JSON 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 2.9.8 ${PROJECT_ROOT}/jsonlab.mltbx d1e5cb15-4ada-479a-aafd-24b64efb8455 *.m~ .git* true false false true true true true ${PROJECT_ROOT} ${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}/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}/filterjsonmmap.m ${PROJECT_ROOT}/gendocs.sh ${PROJECT_ROOT}/genlog.sh ${PROJECT_ROOT}/gzipdecode.m ${PROJECT_ROOT}/gzipencode.m ${PROJECT_ROOT}/images ${PROJECT_ROOT}/isoctavemesh.m ${PROJECT_ROOT}/jdatadecode.m ${PROJECT_ROOT}/jdataencode.m ${PROJECT_ROOT}/jdlink.m ${PROJECT_ROOT}/jload.m ${PROJECT_ROOT}/jsave.m ${PROJECT_ROOT}/json2couch.m ${PROJECT_ROOT}/jsoncache.m ${PROJECT_ROOT}/jsonget.m ${PROJECT_ROOT}/jsonhash.m ${PROJECT_ROOT}/jsonopt.m ${PROJECT_ROOT}/jsonpath.m ${PROJECT_ROOT}/jsonset.m ${PROJECT_ROOT}/loadbj.m ${PROJECT_ROOT}/loadjd.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}/octavezmat.m ${PROJECT_ROOT}/package.json ${PROJECT_ROOT}/savebj.m ${PROJECT_ROOT}/savejd.m ${PROJECT_ROOT}/savejson.m ${PROJECT_ROOT}/savemsgpack.m ${PROJECT_ROOT}/saveubjson.m ${PROJECT_ROOT}/varargin2struct.m ${PROJECT_ROOT}/zlibdecode.m ${PROJECT_ROOT}/zlibencode.m ${PROJECT_ROOT}/zstddecode.m ${PROJECT_ROOT}/zstdencode.m ${PROJECT_ROOT}/getvarfrom.m ${PROJECT_ROOT}/loadbidstsv.m ${PROJECT_ROOT}/loadh5.m ${PROJECT_ROOT}/loadjnifti.m ${PROJECT_ROOT}/loadnifti.m ${PROJECT_ROOT}/memmapstream.m ${PROJECT_ROOT}/nii2jnii.m ${PROJECT_ROOT}/niicodemap.m ${PROJECT_ROOT}/niiformat.m ${PROJECT_ROOT}/niiheader2jnii.m ${PROJECT_ROOT}/regrouph5.m ${PROJECT_ROOT}/transposemat.m jsonlab.mltbx /home/app/MATLAB/R2020a true false false false false false true false 5.6.14-050614-generic false true glnxa64 true jsonlab-2.9.8/jsonopt.m000066400000000000000000000016611460134415400150420ustar00rootroot00000000000000function 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.9.8/jsonpath.m000066400000000000000000000135671460134415400152040ustar00rootroot00000000000000function obj = jsonpath(root, jpath) % % obj=jsonpath(root, jpath) % % Query and retrieve elements from matlab data structures using JSONPath % % author: Qianqian Fang (q.fang neu.edu) % % input: % root: a matlab data structure like an array, cell, struct, etc % jpath: a string in the format of JSONPath, see loadjson help % % output: % obj: if the specified element exist, obj returns the result % % example: % jsonpath(struct('a',[1,2,3]), '$.a[1]') % returns 2 % % 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) % obj = root; jpath = regexprep(jpath, '([^.\]])(\[[-0-9:\*]+\])', '$1.$2'); jpath = regexprep(jpath, '\[[''"]*([^\]''"]+)[''"]*\]', '.[$1]'); jpath = regexprep(jpath, '\\\.', '_0x2E_'); while (regexp(jpath, '(\[[''"]*[^\]''"]+)\.(?=[^\]''"]+[''"]*\])')) jpath = regexprep(jpath, '(\[[''"]*[^\]''"]+)\.(?=[^\]''"]+[''"]*\])', '$1_0x2E_'); end [pat, paths] = regexp(jpath, '(\.{0,2}[^\.]+)', 'match', 'tokens'); if (~isempty(pat) && ~isempty(paths)) if (strcmp(paths{1}, '$')) paths(1) = []; end for i = 1:length(paths) [obj, isfound] = getonelevel(obj, paths, i); if (~isfound) return end end end %% scan function function [obj, isfound] = getonelevel(input, paths, pathid) pathname = paths{pathid}; if (iscell(pathname)) pathname = pathname{1}; end deepscan = ~isempty(regexp(pathname, '^\.\.', 'once')); origpath = pathname; pathname = regexprep(pathname, '^\.+', ''); if (strcmp(pathname, '$')) obj = input; elseif (regexp(pathname, '$\d+')) obj = input(str2double(pathname(2:end)) + 1); elseif (~isempty(regexp(pathname, '^\[[-0-9\*:]+\]$', 'once')) || iscell(input)) arraystr = pathname(2:end - 1); if (find(arraystr == ':')) arrayrange = regexp(arraystr, '(?-*\d*):(?-*\d*)', 'names'); if (~isempty(arrayrange.start)) arrayrange.start = str2double(arrayrange.start); arrayrange.start = (arrayrange.start < 0) * length(input) + arrayrange.start + 1; else arrayrange.start = 1; end if (~isempty(arrayrange.end)) arrayrange.end = str2double(arrayrange.end); arrayrange.end = (arrayrange.end < 0) * length(input) + arrayrange.end + 1; else arrayrange.end = length(input); end elseif (regexp(arraystr, '^[-0-9:]+', 'once')) firstidx = str2double(arraystr); if (firstidx < 0) firstidx = length(input) + firstidx + 1; else firstidx = firstidx + 1; end arrayrange.start = firstidx; arrayrange.end = firstidx; elseif (~isempty(regexp(arraystr, '^\*', 'once'))) % do nothing end if (exist('arrayrange', 'var')) obj = {input(arrayrange.start:arrayrange.end)}; else arrayrange = struct('start', 1, 'end', length(input)); end if (~exist('obj', 'var') && iscell(input)) input = {input{arrayrange.start:arrayrange.end}}; if (deepscan) searchkey = ['..' pathname]; else searchkey = origpath; end for idx = 1:length(input) [val, isfound] = getonelevel(input{idx}, [paths{1:pathid - 1} {searchkey}], pathid); if (isfound) if (~exist('newobj', 'var')) newobj = {}; end newobj = [newobj(:)', val(:)']; end end if (exist('newobj', 'var')) obj = newobj; end if (exist('obj', 'var') && iscell(obj) && length(obj) == 1) obj = obj{1}; end else obj = input(arrayrange.start:arrayrange.end); end elseif (isstruct(input) || isa(input, 'containers.Map') || isa(input, 'table')) pathname = regexprep(pathname, '^\[(.*)\]$', '$1'); stpath = encodevarname(pathname); if (isstruct(input)) if (isfield(input, stpath)) obj = {input.(stpath)}; end elseif (isa(input, 'table')) if (any(ismember(input.Properties.VariableNames, stpath))) obj = {input.(stpath)}; end else if (isKey(input, pathname)) obj = {input(pathname)}; end end if (~exist('obj', 'var') || deepscan) if (isa(input, 'containers.Map')) items = keys(input); else items = fieldnames(input); end for idx = 1:length(items) if (isa(input, 'containers.Map')) [val, isfound] = getonelevel(input(items{idx}), [paths{1:pathid - 1} {['..' pathname]}], pathid); elseif (isa(input, 'table')) [val, isfound] = getonelevel({input.(items{idx})}, [paths{1:pathid - 1} {['..' pathname]}], pathid); elseif (isstruct(input) && length(input) > 1) % struct array [val, isfound] = getonelevel({input.(items{idx})}, [paths{1:pathid - 1} {['..' pathname]}], pathid); else [val, isfound] = getonelevel(input.(items{idx}), [paths{1:pathid - 1} {['..' pathname]}], pathid); end if (isfound) if (~exist('obj', 'var')) obj = {}; end if (iscell(val)) obj = [obj(:)', val(:)']; else obj = [obj(:)', {val}]; end end end if (exist('obj', 'var') && length(obj) == 1) obj = obj{1}; end end if (exist('obj', 'var') && iscell(obj) && length(obj) == 1) obj = obj{1}; end elseif (~deepscan) error('json path segment "%s" can not be found in the input object\n', pathname); end if (~exist('obj', 'var')) isfound = false; obj = []; elseif (nargout > 1) isfound = true; end jsonlab-2.9.8/jsonset.m000066400000000000000000000064671460134415400150440ustar00rootroot00000000000000function json = jsonset(fname, mmap, varargin) % % json=jsonset(fname,mmap,'$.jsonpath1',newval1,'$.jsonpath2','newval2',...) % % Fast writing of JSON data records to stream or disk using memory-map % (mmap) returned by loadjson/loadbj and JSONPath-like keys % % authors:Qianqian Fang (q.fang neu.edu) % initially created on 2022/02/02 % % input: % fname: a JSON/BJData/UBJSON string or stream, or a file name % mmap: memory-map returned by loadjson/loadbj of the same data % important: mmap must be produced from the same file/string, % otherwise calling this function may cause data corruption % '$.jsonpath1,2,3,...': a series of strings in the form of JSONPath % as the key to each of the record to be written % % output: % json: the modified JSON string or, in the case fname is a filename, % the cell string made of jsonpaths that are successfully % written % % examples: % % create test data % d.arr={[1,2],'a',struct('c',2)}; d.obj=struct('k','test') % % convert to json string % str=savejson('',d,'compact',1) % % parse and return mmap % [dat, mmap]=loadjson(str); % % display mmap entries % savejson('',mmap) % % replace value using mmap % json=jsonset(str,mmap,'$.arr[2].c','5') % % save same json string to file (must set savebinary 1) % savejson('',d,'filename','file.json','compact',1,'savebinary',1); % % fast write to file % json=jsonset('file.json',mmap,'$.arr[2].c','5') % % 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 (regexp(fname, '^\s*(?:\[.*\])|(?:\{.*\})\s*$', 'once')) inputstr = fname; else if (~exist('memmapfile', 'file')) fid = fopen(fname, 'r+b'); end end mmap = [mmap{:}]; keylist = mmap(1:2:end); opt = struct; for i = 1:2:length(varargin) if (isempty(regexp(varargin{i}, '^\$', 'once'))) opt.(encodevarname(varargin{i})) = varargin{i + 1}; end end json = {}; for i = 1:2:length(varargin) if (regexp(varargin{i}, '^\$')) [tf, loc] = ismember(varargin{i}, keylist); if (tf) bmap = mmap{loc * 2}; if (ischar(varargin{i + 1})) val = varargin{i + 1}; else val = savejson('', varargin{i + 1}, 'compact', 1); end if (length(val) <= bmap(2)) val = [val repmat(' ', [1, bmap(2) - length(val)])]; if (exist('inputstr', 'var')) inputstr(bmap(1):bmap(1) + bmap(2) - 1) = val; else if (exist('memmapfile', 'file')) rec = {'uint8', [1 bmap(2)], 'x'}; fmap = memmapfile(fname, 'writable', true, 'offset', bmap(1) - 1, 'format', rec, 'repeat', 1); fmap.Data.x = uint8(val); else fseek(fid, bmap(1) - 1, 'bof'); fwrite(fid, val); end json{end + 1} = {varargin{i}, val}; end end end end end if (exist('fid', 'var') && fid >= 0) fclose(fid); end if (exist('inputstr', 'var')) json = inputstr; end jsonlab-2.9.8/loadbidstsv.m000066400000000000000000000052431460134415400156640ustar00rootroot00000000000000function data = loadbidstsv(tsvfile, delim) % % data = loadbidstsv(tsvfile) % or % data = loadbidstsv(tsvfile, delim) % % Loading a BIDS-formatted .tsv (tab-separated values) or .tsv.gz file as a % struct; numerical fields are converted to floating-point data records % when possible; the header of the file is parsed to define sub-field % names % % author: Qianqian Fang (q.fang neu.edu) % % input: % tsvfile: the path to the .tsv file % delim: (optional) if not set, tab ('\t') is used as column delimiter % % examples: % data = loadbidstsv('participants.tsv'); % % license: % BSD license, see LICENSE_BSD.txt files for details % % -- this function is part of JBIDS toolbox (https://neurojson.org/#software) % if (nargin < 2) delim = sprintf('\t'); end data = struct; if (~isempty(regexp(tsvfile, '\.[Gg][Zz]$', 'once'))) finput = fopen(tsvfile, 'rb'); tsvdata = fread(finput, inf, 'uint8=>uint8'); fclose(finput); if (~exist('gzipdecode', 'file')) error('To process zipped files, you must install gzipdecode.m from the JSONLab toolbox: http://github.com/fangq/jsonlab'); end fid = char(gzipdecode(tsvdata)); clear tsvdata; [header, endpos] = regexp(fid, '([^\n\r]*)', 'once', 'tokens', 'end'); if (~isempty(header)) header = header{1}; fid = fid((endpos + 1):end); end else fid = fopen(tsvfile, 'rt'); header = fgetl(fid); header = regexprep(header, '\s*$', ''); end if (isempty(header)) return end if (exist('strsplit')) cols = strsplit(header, delim); else cols = regexp(header, '\t*([^\t]*)\t*', 'tokens'); cols = cellfun(@(x) x{:}, cols, 'uniformoutput', 0); end cols = cellfun(@encodevarname, cols, 'uniformoutput', 0); if (~isempty(cols)) body = textscan(fid, [repmat('%s\t', 1, length(cols) - 1), '%s'], 'delimiter', '\t'); if (length(body) ~= length(cols)) error('invalid tsv'); end for i = 1:length(body) try % bodynum = cellfun(@(x) sscanf(regexprep(x,'^n/a$','NaN'), '%f'), body{i}, 'uniformoutput', 0); bodynum = cellfun(@(x) sscanf(x, '%f\t'), body{i}, 'uniformoutput', 0); if (exist('isna')) len = cellfun(@(x) numel(x) * (~isna(sum(x))), bodynum); else len = cellfun(@numel, bodynum); end if (any(len)) body{i}(len > 0) = bodynum(len > 0); if (all(len)) body{i} = cell2mat(body{i}); end end catch ME warning(ME.message); end data.(cols{i}) = body{i}(:).'; end end fclose(fid); jsonlab-2.9.8/loadbj.m000066400000000000000000000476021460134415400146060ustar00rootroot00000000000000function [data, mmap] = loadbj(fname, varargin) % % data=loadbj(fname,opt) % or % [data, mmap]=loadbj(fname,'param1',value1,'param2',value2,...) % % Parse a Binary JData (BJData v1 Draft-2, defined in https://github.com/NeuroJSON/bjdata) % file or memory buffer and convert into a MATLAB data structure % % By default, this function parses 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). % Starting from BJD Draft-2 (JSONLab 3.0 beta or later), all integer and % floating-point numbers are parsed in Little-Endian as opposed to % Big-Endian form as in BJD Draft-1/UBJSON Draft-12 (JSONLab 2.0 or older) % % 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 equivalent % 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. % Endian ['L'|'B']: specify the endianness of the numbers % in the BJData/UBJSON input data. Default: 'L'. % % Starting from JSONLab 2.9, BJData by default uses % [L] Little-Endian for both integers and floating % point numbers. This is a major departure from the % UBJSON specification, where 'B' - Big-Endian - % format is used for integer fields. UBJSON does % not specifically define Endianness for % floating-point numbers, resulting in mixed % implementations. JSONLab 2.0-2.1 used 'B' for % integers and floating-points; JSONLab 1.x uses % 'B' for integers and native-endianness for % floating-point numbers. % 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, loadbj uses a containers.Map to % store map objects; otherwise use a struct object % ObjectID [0|integer 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. % MmapOnly [0|1]: if set to 1, this function only returns mmap % MMapInclude 'str1' or {'str1','str2',..}: if provided, the % returned mmap will be filtered by only keeping % entries containing any one of the string patterns % provided in a cell % MMapExclude 'str1' or {'str1','str2',..}: if provided, the % returned mmap will be filtered by removing % entries containing any one of the string patterns % provided in a cell % % output: % dat: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % mmap: (optional) a cell array in the form of % {{jsonpath1,[start,length]}, {jsonpath2,[start,length]}, ...} % where jsonpath_i is a string in the form of JSONPath, and % start is an integer referring to the offset from the beginning % of the stream, and length is the JSON object string length. % For more details, please see the help section of loadjson.m % % The format of the mmap table returned from this function % follows the JSON-Mmap Specification Draft 1 [3] defined by the % NeuroJSON project, see https://neurojson.org/jsonmmap/draft1/ % % 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) % opt = varargin2struct(varargin{:}); if (length(fname) < 4096 && exist(fname, 'file')) fid = fopen(fname, 'rb'); string = fread(fid, jsonopt('MaxBuffer', inf, opt), 'uint8=>char')'; fclose(fid); elseif (all(fname < 128) && ~isempty(regexpi(fname, '^\s*(http|https|ftp|file)://'))) if (exist('webread')) string = char(webread(fname, weboptions('ContentType', 'binary')))'; else string = urlread(fname); end elseif (~isempty(fname) && any(fname(1) == '[{SCHiUIulmLMhdDTFZN')) string = fname; else error('input file does not exist or buffer is invalid'); end pos = 1; inputlen = length(string); inputstr = string; opt.simplifycell = jsonopt('SimplifyCell', 1, opt); opt.simplifycellarray = jsonopt('SimplifyCellArray', 0, opt); opt.usemap = jsonopt('UseMap', 0, opt); opt.nameisstring = jsonopt('NameIsString', 0, opt); mmaponly = jsonopt('MmapOnly', 0, opt); [os, maxelem, systemendian] = computer; opt.flipendian_ = (systemendian ~= upper(jsonopt('Endian', 'L', opt))); objid = jsonopt('ObjectID', 0, opt); maxobjid = max(objid); if (maxobjid == 0) maxobjid = inf; end opt.jsonpath_ = '$'; if (nargout > 1 || mmaponly) mmap = {}; end jsoncount = 1; while pos <= inputlen [cc, pos] = next_char(inputstr, pos); switch (cc) case '{' if (nargout > 1 || mmaponly) mmap{end + 1} = {opt.jsonpath_, pos}; [data{jsoncount}, pos, newmmap] = parse_object(inputstr, pos, opt); if (pos < 0) opt.usemap = 1; [data{jsoncount}, pos, newmmap] = parse_object(inputstr, -pos, opt); end mmap{end}{2} = [mmap{end}{2}, pos - mmap{end}{2}]; mmap = [mmap(:); newmmap(:)]; else [data{jsoncount}, pos] = parse_object(inputstr, pos, opt); if (pos < 0) opt.usemap = 1; [data{jsoncount}, pos] = parse_object(inputstr, -pos, opt); end end case '[' if (nargout > 1 || mmaponly) mmap{end + 1} = {opt.jsonpath_, pos}; [data{jsoncount}, pos, newmmap] = parse_array(inputstr, pos, opt); mmap{end}{2} = [mmap{end}{2}, pos - mmap{end}{2}]; mmap = [mmap(:); newmmap(:)]; else [data{jsoncount}, pos] = parse_array(inputstr, pos, opt); end 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('Root level structure must start with a valid marker "{[SCHiUIulmLMhdDTFZN"', inputstr, pos); end if (jsoncount >= maxobjid) break end opt.jsonpath_ = sprintf('$%d', jsoncount); 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 (nargout > 1 || mmaponly) mmap = mmap'; mmap = filterjsonmmap(mmap, jsonopt('MMapExclude', {}, opt), 0); mmap = filterjsonmmap(mmap, jsonopt('MMapInclude', {}, opt), 1); end if (jsonopt('JDataDecode', 1, varargin{:}) == 1) try data = jdatadecode(data, 'Base64', 0, 'Recursive', 1, varargin{:}); catch ME warning(['Failed to decode embedded JData annotations, '... 'return raw JSON data\n\njdatadecode error: %s\n%s\nCall stack:\n%s\n'], ... ME.identifier, ME.message, char(savejson('', ME.stack))); end end if (mmaponly) data = mmap; end %% ------------------------------------------------------------------------- %% helper functions %% ------------------------------------------------------------------------- function [data, adv] = parse_block(inputstr, pos, type, count, varargin) if (count >= 0 && ~isempty(type) && isempty(strfind('iUIulmLMdDh', type))) adv = 0; switch (type) case {'S', 'H', '{', '['} data = cell(1, count); adv = pos; for i = 1:count [data{i}, pos] = parse_value(inputstr, pos, type, varargin{:}); end adv = pos - adv; case 'C' data = inputstr(pos:pos + count); adv = count; case {'T', 'F', 'N'} error_pos(sprintf('For security reasons, optimized type %c is disabled at position %%d', type), inputstr, pos); otherwise error_pos(sprintf('Unsupported optimized type %c at position %%d', type), inputstr, pos); end return end [cid, len] = elem_info(inputstr, pos, type); datastr = inputstr(pos:pos + len * count - 1); newdata = uint8(datastr); if (varargin{1}.flipendian_) newdata = swapbytes(typecast(newdata, cid)); end data = typecast(newdata, cid); adv = double(len * count); %% ------------------------------------------------------------------------- function [object, pos, mmap] = parse_array(inputstr, pos, varargin) % JSON array is written in row-major order if (nargout > 2) mmap = {}; origpath = varargin{1}.jsonpath_; end 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', inputstr, pos); 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 = permute(reshape(object, fliplr(dim(:)')), length(dim):-1:1); 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 if (nargout > 2) varargin{1}.jsonpath_ = [origpath sprintf('[%d]', length(object))]; mmap{end + 1} = {varargin{1}.jsonpath_, pos}; [val, pos, newmmap] = parse_value(inputstr, pos, [], varargin{:}); mmap{end}{2} = [mmap{end}{2}, pos - mmap{end}{2}]; mmap = [mmap(:); newmmap(:)]; else [val, pos] = parse_value(inputstr, pos, [], varargin{:}); end 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 %% ------------------------------------------------------------------------- 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 %% ------------------------------------------------------------------------- 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 %% ------------------------------------------------------------------------- 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 %% ------------------------------------------------------------------------- function [str, pos] = parseStr(inputstr, pos, type, varargin) if (isempty(type)) 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 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 %% ------------------------------------------------------------------------- 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; %% ------------------------------------------------------------------------- function varargout = parse_value(inputstr, pos, type, varargin) if (length(type) == 1) cc = type; varargout{2} = pos; else [cc, varargout{2}] = next_char(inputstr, pos); end if (nargout > 2) varargout{3} = {}; end switch (cc) case {'S', 'C', 'H'} [varargout{1:2}] = parseStr(inputstr, varargout{2}, type, varargin{:}); return case '[' [varargout{1:nargout}] = parse_array(inputstr, varargout{2}, varargin{:}); return case '{' [varargout{1:nargout}] = parse_object(inputstr, varargout{2}, varargin{:}); if (varargout{2} < 0) varargin{1}.usemap = 1; [varargout{1:nargout}] = parse_object(inputstr, -varargout{2}, varargin{:}); end return case {'i', 'U', 'I', 'u', 'l', 'm', 'L', 'M', 'h', 'd', 'D'} [varargout{1:2}] = parse_number(inputstr, varargout{2}, varargin{:}); return case 'T' varargout{1} = true; varargout{2} = varargout{2} + 1; return case 'F' varargout{1} = false; varargout{2} = varargout{2} + 1; return case {'Z', 'N'} varargout{1} = []; varargout{2} = varargout{2} + 1; return end error_pos('Value expected at position %d', inputstr, varargout{2}); %% ------------------------------------------------------------------------- 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); %% ------------------------------------------------------------------------- function [object, pos, mmap] = parse_object(inputstr, pos, varargin) oldpos = pos; if (nargout > 2) mmap = {}; origpath = varargin{1}.jsonpath_; end 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 (length(str) > 63) pos = -oldpos; object = []; return end if isempty(str) str = 'x0x0_'; % empty name is valid in BJData/UBJSON, decodevarname('x0x0_') restores '\0' end if (nargout > 2) varargin{1}.jsonpath_ = [origpath, '.', str]; mmap{end + 1} = {varargin{1}.jsonpath_, pos}; [val, pos, newmmap] = parse_value(inputstr, pos, [], varargin{:}); mmap{end}{2} = [mmap{end}{2}, pos - mmap{end}{2}]; mmap = [mmap(:); newmmap(:)]; else [val, pos] = parse_value(inputstr, pos, [], varargin{:}); end num = num + 1; if (usemap) object(str) = val; else str = encodevarname(str, varargin{:}); if (length(str) > 63) pos = -oldpos; object = []; return end object.(str) = val; end [cc, pos] = next_char(inputstr, pos); if (count >= 0 && num >= count) || cc == '}' break end end end if (count == -1) pos = parse_char(inputstr, pos, '}'); 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 jsonlab-2.9.8/loadh5.m000066400000000000000000000247271460134415400145320ustar00rootroot00000000000000function varargout = loadh5(filename, varargin) % % [data, meta] = loadh5(filename) % [data, meta] = loadh5(root_id) % [data, meta] = loadh5(filename, rootpath) % [data, meta] = loadh5(filename, rootpath, options) % [data, meta] = loadh5(filename, options) % [data, meta] = loadh5(filename, 'Param1',value1, 'Param2',value2,...) % % Load data in an HDF5 file to a MATLAB structure. % % author: Qianqian Fang (q.fang neu.edu) % % input % filename % Name of the file to load data from % root_id: an HDF5 handle (of type 'H5ML.id' in MATLAB) % rootpath : (optional) % Root path to read part of the HDF5 file to load % options: (optional) a struct or Param/value pairs for user specified options % Order: 'creation' - creation order (default), or 'alphabet' - alphabetic % Regroup: [0|1]: if 1, call regrouph5() to combine indexed % groups into a cell array % PackHex: [1|0]: convert invalid characters in the group/dataset % names to 0x[hex code] by calling encodevarname.m; % if set to 0, call getvarname % ComplexFormat: {'realKey','imagKey'}: use 'realKey' and 'imagKey' % as possible keywords for the real and the imaginary part % of a complex array, respectively (sparse arrays not supported); % a common list of keypairs is used even without this option % Transpose: [1|0] - if set to 1 (default), the row-majored HDF5 % datasets are transposed (to column-major) so that the % output MATLAB array has the same dimensions as in the % HDF5 dataset header. % % output % data: a structure (array) or cell (array) % meta: optional output to store the attributes stored in the file % % example: % a={rand(2), struct('va',1,'vb','string'), 1+2i}; % saveh5(a,'test.h5'); % a2=loadh5('test.h5') % a3=loadh5('test.h5','regroup',1) % isequaln(a,a3.a) % a4=loadh5('test.h5','/a1') % % This function was adapted from h5load.m by Pauli Virtanen % This file is part of EasyH5 Toolbox: https://github.com/NeuroJSON/easyh5 % % License: GPLv3 or 3-clause BSD license, see https://github.com/NeuroJSON/easyh5 for details % path = ''; opt = struct; if (bitand(length(varargin), 1) == 0) opt = varargin2struct(varargin{:}); elseif (length(varargin) >= 3) path = varargin{1}; opt = varargin2struct(varargin{2:end}); elseif (length(varargin) == 1) path = varargin{1}; end opt.dotranspose = jsonopt('Transpose', 1, opt); opt.stringarray = jsonopt('StringArray', 0, opt); opt.rootpath = path; if (exist('OCTAVE_VERSION', 'builtin') ~= 0) [varargout{1:nargout}] = load(filename, '-hdf5'); if (opt.dotranspose) varargout{1} = transposemat(varargout{1}); end return end if (isa(filename, 'H5ML.id')) loc = filename; else try loc = H5F.open(filename, 'H5F_ACC_RDONLY', 'H5P_DEFAULT'); catch ME error('fail to open file'); end end if (~(isfield(opt, 'complexformat') && iscellstr(opt.complexformat) && numel(opt.complexformat) == 2)) opt.complexformat = {'Real', 'Imag'}; end opt.releaseid = 0; vers = ver('MATLAB'); if (~isempty(vers)) opt.releaseid = datenum(vers(1).Date); end if ((isfield(opt, 'order') && strcmpi(opt.order, 'alphabet')) || opt.releaseid < datenum('1-Jan-2015')) opt.order = 'H5_INDEX_NAME'; else opt.order = 'H5_INDEX_CRT_ORDER'; end try if (nargin > 1 && ~isempty(path)) try rootgid = H5G.open(loc, path); [varargout{1:nargout}] = load_one(rootgid, opt); H5G.close(rootgid); catch [gname, dname] = fileparts(path); rootgid = H5G.open(loc, gname); [status, res] = group_iterate(rootgid, dname, struct('data', struct, 'meta', struct, 'opt', opt)); if (nargout > 0) varargout{1} = res.data; elseif (nargout > 1) varargout{2} = res.meta; end H5G.close(rootgid); end else [varargout{1:nargout}] = load_one(loc, opt); end H5F.close(loc); catch ME H5F.close(loc); rethrow(ME); end if (jsonopt('Regroup', 0, opt)) if (nargout >= 1) varargout{1} = regrouph5(varargout{1}); elseif (nargout >= 2) varargout{2} = regrouph5(varargout{2}); end end if (isfield(opt, 'jdata') && opt.jdata && nargout >= 1) varargout{1} = jdatadecode(varargout{1}, 'Base64', 0, opt); end % -------------------------------------------------------------------------- function [data, meta] = load_one(loc, opt) data = struct(); meta = struct(); inputdata = struct('data', data, 'meta', meta, 'opt', opt); % Load groups and datasets try [status, count, inputdata] = H5L.iterate(loc, opt.order, 'H5_ITER_INC', 0, @group_iterate, inputdata); catch ME if (strcmp(opt.order, 'H5_INDEX_CRT_ORDER')) [status, count, inputdata] = H5L.iterate(loc, 'H5_INDEX_NAME', 'H5_ITER_INC', 0, @group_iterate, inputdata); else rethrow(ME); end end data = inputdata.data; meta = inputdata.meta; % -------------------------------------------------------------------------- function [status, res] = group_iterate(group_id, objname, inputdata) status = 0; attr = struct(); encodename = jsonopt('PackHex', 1, inputdata.opt); try data = inputdata.data; meta = inputdata.meta; % objtype index info = H5G.get_objinfo(group_id, objname, 0); objtype = info.type; objtype = objtype + 1; if objtype == 1 % Group name = regexprep(objname, '.*/', ''); group_loc = H5G.open(group_id, name); try [sub_data, sub_meta] = load_one(group_loc, inputdata.opt); H5G.close(group_loc); catch ME H5G.close(group_loc); rethrow(ME); end if (encodename) name = encodevarname(name); else name = genvarname(name); end data.(name) = sub_data; meta.(name) = sub_meta; elseif objtype == 2 % Dataset name = regexprep(objname, '.*/', ''); dataset_loc = H5D.open(group_id, name); try sub_data = H5D.read(dataset_loc, ... 'H5ML_DEFAULT', 'H5S_ALL', 'H5S_ALL', 'H5P_DEFAULT'); try [status, count, attr] = H5A.iterate(dataset_loc, 'H5_INDEX_NAME', 'H5_ITER_INC', 0, @getattribute, attr); catch attr = []; end H5D.close(dataset_loc); catch exc H5D.close(dataset_loc); rethrow(exc); end if (ischar(sub_data) && numel(sub_data) > 1 && sub_data(end) == 0) sub_data = sub_data(1:end - 1); end if ((isnumeric(sub_data) && inputdata.opt.dotranspose) || (iscell(sub_data) && length(sub_data) > 1)) sub_data = permute(sub_data, ndims(sub_data):-1:1); end sub_data = fix_data(sub_data, attr, inputdata.opt); if (encodename) name = encodevarname(name); else name = genvarname(name); end data.(name) = sub_data; meta.(name) = attr; end catch ME rethrow(ME); end res = struct('data', data, 'meta', meta, 'opt', inputdata.opt); % -------------------------------------------------------------------------- function data = fix_data(data, attr, opt) % Fix some common types of data to more friendly form. if isstruct(data) fields = fieldnames(data); if (length(intersect(fields, {'SparseIndex', opt.complexformat{1}})) == 2) if isnumeric(data.SparseIndex) && isnumeric(data.(opt.complexformat{1})) if (nargin > 1 && isstruct(attr)) if (isfield(attr, 'SparseArraySize')) spd = sparse(1, prod(attr.SparseArraySize)); if (isfield(data, opt.complexformat{2})) spd(data.SparseIndex) = complex(data.(opt.complexformat{1}), data.(opt.complexformat{2})); else spd(data.SparseIndex) = data.(opt.complexformat{1}); end data = reshape(spd, attr.SparseArraySize(:)'); return end end end else if (numel(opt.complexformat) == 2 && length(intersect(fields, opt.complexformat)) == 2) if isnumeric(data.(opt.complexformat{1})) && isnumeric(data.(opt.complexformat{2})) data = data.(opt.complexformat{1}) + 1j * data.(opt.complexformat{2}); end else % if complexformat is not specified or not found, try some common complex number storage formats if (length(intersect(fields, {'Real', 'Imag'})) == 2) if isnumeric(data.Real) && isnumeric(data.Imag) data = data.Real + 1j * data.Imag; end elseif (length(intersect(fields, {'real', 'imag'})) == 2) if isnumeric(data.real) && isnumeric(data.imag) data = data.real + 1j * data.imag; end elseif (length(intersect(fields, {'Re', 'Im'})) == 2) if isnumeric(data.Re) && isnumeric(data.Im) data = data.Re + 1j * data.Im; end elseif (length(intersect(fields, {'re', 'im'})) == 2) if isnumeric(data.re) && isnumeric(data.im) data = data.re + 1j * data.im; end elseif (length(intersect(fields, {'r', 'i'})) == 2) if isnumeric(data.r) && isnumeric(data.i) data = data.r + 1j * data.i; end end end end end if (isa(data, 'uint8') || isa(data, 'int8')) if (nargin > 1 && isstruct(attr)) if (isfield(attr, 'MATLABObjectClass')) data = getArrayFromByteStream(data); % use undocumented function end end end % handeling string arrays (or cell of char strings) if (iscell(data) && length(data) > 1) if (all(cellfun(@ischar, data)) && exist('string') && opt.stringarray) data = string(data); end end % -------------------------------------------------------------------------- function [status, dataout] = getattribute(loc_id, attr_name, info, datain) status = 0; attr_id = H5A.open(loc_id, attr_name, 'H5P_DEFAULT'); datain.(attr_name) = H5A.read(attr_id, 'H5ML_DEFAULT'); H5A.close(attr_id); dataout = datain; jsonlab-2.9.8/loadjd.m000066400000000000000000000077771460134415400146210ustar00rootroot00000000000000function varargout = loadjd(filename, varargin) % % data=loadjd(inputfile) % or % [data, mmap]=loadjd(inputfile, 'Param1',value1, 'Param2',value2,...) % % Parse a hierarchical container data file, including JSON, % binary JSON (BJData/UBJSON/MessagePack) and HDF5, and output % the parsed data in a MATLAB/Octave data structure % % author: Qianqian Fang (q.fang neu.edu) % % input: % inputfile: the input hierarchical container data file, supporting: % *.json,.jnii,.jdt,.jmsh,.jnirs,.jbids: JSON/JData based data files, see https://neurojson.org/jdata/draft2 % *.bjd,.bnii,.jdb,.bmsh,.bnirs,.pmat: binary JData (BJData) files, see https://neurojson.org/bjdata/draft2 % *.ubj: UBJSON-encoded files, see http://ubjson.org % *.msgpack: MessagePack-encoded files, see http://msgpack.org % *.h5,.hdf5,.snirf,.nwb: HDF5 files, see https://www.hdfgroup.org/ % *.nii,.nii.gz: NIfTI files, need http://github.com/NeuroJSON/jnifty % *.tsv,.tsv.gz,.csv,.csv.gz: TSV/CSV files, need http://github.com/NeuroJSON/jbids % *.bval,.bvec: EEG .bval and .bvec files % *.mat: MATLAB/Octave .mat files % options: (optional) for JSON/JData files, these are optional 'param',value pairs % supported by loadjson.m; for BJData/UBJSON/MessagePack files, these are % options supported by loadbj.m; for HDF5 files, these are options % supported by loadh5.m (part of EasyH5 toolbox, http://github.com/NeuroJSON/easyh5/) % % output: % data: a structure (array) or cell (array) storing the hierarchical data % in the container data file % mmap: (optional) output storing the JSON/binary JSON memory-map table for fast % disk access. see help info for loadjson or loadbj for more details. % % examples: % obj=struct('string','value','array',[1 2 3]); % savejd('obj', obj, 'datafile.json') % newobj=loadjd('datafile.json'); % % 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) error('you must provide file name'); end if (regexpi(filename, '\.json$|\.jnii$|\.jdt$|\.jdat$|\.jmsh$|\.jnirs|\.jbids$')) [varargout{1:nargout}] = loadjson(filename, varargin{:}); elseif (regexpi(filename, '\.bjd$|\.bnii$|\.jdb$|\.jbat$|\.bmsh$|\.bnirs$|\.pmat$')) [varargout{1:nargout}] = loadbj(filename, varargin{:}); elseif (regexpi(filename, '\.ubj$')) [varargout{1:nargout}] = loadubjson(filename, varargin{:}); elseif (regexpi(filename, '\.msgpack$')) [varargout{1:nargout}] = loadmsgpack(filename, varargin{:}); elseif (regexpi(filename, '\.h5$|\.hdf5$|\.snirf$|\.nwb$')) if (~exist('loadh5', 'file')) error('you must first install EasyH5 from http://github.com/NeuroJSON/easyh5/'); end [varargout{1:nargout}] = loadh5(filename, varargin{:}); elseif (regexpi(filename, '\.nii$|\.nii\.gz$')) if (~exist('loadnifti', 'file')) error('you must first install JNIFTY toolbox from http://github.com/NeuroJSON/jnifty/'); end [varargout{1:nargout}] = loadnifti(filename, varargin{:}); elseif (regexpi(filename, '\.tsv$|\.tsv\.gz$|\.csv$|\.csv\.gz$')) if (~exist('loadbidstsv', 'file')) error('you must first install JBIDS toolbox from http://github.com/NeuroJSON/jbids/'); end delim = sprintf('\t'); if (regexpi(filename, '\.csv')) delim = ','; end [varargout{1:nargout}] = loadbidstsv(filename, delim); elseif (regexpi(filename, '\.mat$|\.bvec$|\.bval$')) [varargout{1:nargout}] = load(filename, varargin{:}); else warning('only support parsing .json,.jnii,.jdt,.jmsh,.jnirs,.jbids,.bjd,.bnii,.jdb,.bmsh,.bnirs,.ubj,.msgpack,.h5,.hdf5,.snirf,.pmat,.nwb,.nii,.nii.gz,.tsv,.tsv.gz,.csv,.csv.gz,.mat,.bvec,.bval; load unparsed raw data'); [varargout{1:nargout}] = fileread(filename); end jsonlab-2.9.8/loadjnifti.m000066400000000000000000000043761460134415400154770ustar00rootroot00000000000000function jnii = loadjnifti(filename, varargin) % % jnii=loadjnifti(inputfile) % or % jnii=loadjnifti(inputfile, 'Param1',value1, 'Param2',value2,...) % % Load a standard NIFTI-1/2 file or text or binary JNIfTI file with % format defined in JNIfTI specification: https://github.com/NeuroJSON/jnifti % % author: Qianqian Fang (q.fang neu.edu) % % input: % inputfile: the output file name to the JNIfTI or NIFTI-1/2 file % *.bnii for binary JNIfTI file % *.jnii for text JNIfTI file % *.nii for NIFTI-1/2 files % options: (optional) if loading from a .bnii file, please see the options for % loadbj.m (part of JSONLab); if loading from a .jnii, please see the % supported options for loadjson.m (part of JSONLab). % % output: % jnii: a structure (array) or cell (array). The data structure can % be completely generic or auxilary data without any JNIfTI % constructs. However, if a JNIfTI object is included, it shall % contain the below subfields (can appear within any depth of the % structure) % jnii.NIFTIHeader - a structure containing the 1-to-1 mapped NIFTI-1/2 header % jnii.NIFTIData - the main image data array % jnii.NIFTIExtension - a cell array contaiing the extension data buffers % % example: % jnii=jnifticreate(uint8(magic(10)),'Name','10x10 magic matrix'); % savejnifti(jnii, 'magic10.jnii') % newjnii=loadjnifti('magic10.jnii'); % % this file is part of JNIfTI specification: https://github.com/NeuroJSON/jnifti % % License: Apache 2.0, see https://github.com/NeuroJSON/jnifti for details % if (nargin < 1) error('you must provide data and output file name'); end if (~exist('savejson', 'file')) error('you must first install JSONLab from http://github.com/fangq/jsonlab/'); end if (regexp(filename, '\.nii$')) jnii = nii2jnii(filename, 'jnii'); elseif (regexp(filename, '\.jnii$')) jnii = loadjson(filename, varargin{:}); elseif (regexp(filename, '\.bnii$')) jnii = loadbj(filename, varargin{:}); else error('file suffix must be .jnii for text JNIfTI, .bnii for binary JNIfTI or .nii for NIFTI-1/2 files'); end jsonlab-2.9.8/loadjson.m000066400000000000000000000645371460134415400151720ustar00rootroot00000000000000function [data, mmap] = loadjson(fname, varargin) % % data=loadjson(fname,opt) % or % [data, mmap]=loadjson(fname,'param1',value1,'param2',value2,...) % % parse a JSON (JavaScript Object Notation) file or string and return a % matlab data structure with optional memory-map (mmap) table % % 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 equivalent % 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 [3|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|integer 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. % BuiltinJSON [0|1]: if set to 1, this function attempts to call % jsondecode, if presents (MATLAB R2016b or Octave % 6) first. If jsondecode does not exist or failed, % this function falls back to the jsonlab parser % MmapOnly [0|1]: if set to 1, this function only returns mmap % MMapInclude 'str1' or {'str1','str2',..}: if provided, the % returned mmap will be filtered by only keeping % entries containing any one of the string patterns % provided in a cell % MMapExclude 'str1' or {'str1','str2',..}: if provided, the % returned mmap will be filtered by removing % entries containing any one of the string patterns % provided in a cell % % output: % dat: a cell array, where {...} blocks are converted into cell arrays, % and [...] are converted to arrays % mmap: (optional) a cell array as memory-mapping table in the form of % {{jsonpath1,[start,length,]}, % {jsonpath2,[start,length,]}, ...} % where jsonpath_i is a string in the JSONPath [1,2] format, and % "start" is an integer referring to the offset from the beginning % of the stream, and "length" is the JSON object string length. % An optional 3rd integer "whitespace_pre" may appear to record % the preceding whitespace length in case expansion of the data % record is needed when using the mmap. % % The format of the mmap table returned from this function % follows the JSON-Mmap Specification Draft 1 [3] defined by the % NeuroJSON project, see https://neurojson.org/jsonmmap/draft1/ % % Memory-mapping table (mmap) is useful when fast reading/writing % specific data records inside a large JSON file without needing % to load/parse/overwrite the entire file. % % The JSONPath keys used in mmap is largely compatible to the % upstream specification defined in [1], with a slight extension % to handle concatenated JSON files. % % In the mmap jsonpath key, a '$' denotes the root object, a '.' % denotes a child of the preceding element; '.key' points to the % value segment of the child named "key" of the preceding % object; '[i]' denotes the (i+1)th member of the preceding % element, which must be an array. For example, a key % % $.obj1.obj2[0].obj3 % % defines the memory-map of the "value" section in the below % hierarchy: % { % "obj1":{ % "obj2":[ % {"obj3":value}, % ... % ], % ... % } % } % Please note that "value" can be any valid JSON value, including % an array, an object, a string or numerical value. % % To handle concatenated JSON objects (including ndjson, % http://ndjson.org/), such as % % {"root1": {"obj1": ...}} % ["root2", value1, value2, {"obj2": ...}] % {"root3": ...} % % we use '$' or '$0' for the first root-object, and '$1' refers % to the 2nd root object (["root2",...]) and '$2' refers to the % 3rd root object, and so on. Please note that this syntax is an % extension from the JSONPath documentation [1,2] % % [1] https://goessner.net/articles/JsonPath/ % [2] http://jsonpath.herokuapp.com/ % [3] https://neurojson.org/jsonmmap/draft1/ % % examples: % dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}') % dat=loadjson(['examples' filesep 'example1.json']) % [dat, mmap]=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(fname); catch string = urlread(['file://', fullfile(pwd, fname)]); end end elseif (regexpi(fname, '^\s*(http|https|ftp|file)://')) string = urlread(fname); else error('input file does not exist'); end if (jsonopt('BuiltinJSON', 0, opt) && exist('jsondecode', 'builtin')) try newstring = regexprep(string, '[\r\n]', ''); newdata = jsondecode(newstring); newdata = jdatadecode(newdata, 'Base64', 1, 'Recursive', 1, varargin{:}); data = newdata; return catch warning('built-in jsondecode function failed to parse the file, fallback to loadjson'); end 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', opt.simplifycell, opt); opt.formatversion = jsonopt('FormatVersion', 3, opt); opt.fastarrayparser = jsonopt('FastArrayParser', 1, opt); opt.parsestringarray = jsonopt('ParseStringArray', 0, opt); opt.usemap = jsonopt('UseMap', 0, opt); opt.arraydepth_ = 1; opt.mmaponly = jsonopt('MmapOnly', 0, opt); 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 opt.jsonpath_ = '$'; if (nargout > 1 || opt.mmaponly) mmap = {}; end if (regexp(inputstr, '^\s*$')) data = []; inputlen = 0; end jsoncount = 1; while pos <= inputlen [cc, pos, w1] = next_char(inputstr, pos); switch (cc) case '{' if (nargout > 1 || opt.mmaponly) mmap{end + 1} = {opt.jsonpath_, [pos, 0, w1]}; [data{jsoncount}, pos, index_esc, newmmap] = parse_object(inputstr, pos, esc, index_esc, opt); if (pos < 0) opt.usemap = 1; [data{jsoncount}, pos, index_esc, newmmap] = parse_object(inputstr, -pos, esc, index_esc, opt); end mmap{end}{2}(2) = pos - mmap{end}{2}(1); mmap = [mmap(:); newmmap(:)]; else [data{jsoncount}, pos, index_esc] = parse_object(inputstr, pos, esc, index_esc, opt); if (pos < 0) opt.usemap = 1; [data{jsoncount}, pos, index_esc] = parse_object(inputstr, -pos, esc, index_esc, opt); end end case '[' if (nargout > 1 || opt.mmaponly) mmap{end + 1} = {opt.jsonpath_, [pos, 0, w1]}; [data{jsoncount}, pos, index_esc, newmmap] = parse_array(inputstr, pos, esc, index_esc, opt); mmap{end}{2}(2) = pos - mmap{end}{2}(1); mmap = [mmap(:); newmmap(:)]; else [data{jsoncount}, pos, index_esc] = parse_array(inputstr, pos, esc, index_esc, opt); end otherwise pos = error_pos('Outer level structure must be an object or an array', inputstr, pos); end if (jsoncount >= maxobjid) break end opt.jsonpath_ = sprintf('$%d', jsoncount); 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 (nargout > 1 || opt.mmaponly) mmap = mmap'; mmap = filterjsonmmap(mmap, jsonopt('MMapExclude', {}, opt), 0); mmap = filterjsonmmap(mmap, jsonopt('MMapInclude', {}, opt), 1); mmap = cellfun(@(x) {x{1}, x{2}(1:(2 + int8(length(x{2}) >= 3 && (x{2}(3) > 0))))}, mmap, 'UniformOutput', false); end if (jsonopt('JDataDecode', 1, opt) == 1) try data = jdatadecode(data, 'Base64', 1, 'Recursive', 1, opt); catch ME warning(['Failed to decode embedded JData annotations, '... 'return raw JSON data\n\njdatadecode error: %s\n%s\nCall stack:\n%s\n'], ... ME.identifier, ME.message, char(savejson('', ME.stack))); end end if (opt.mmaponly) data = mmap; end if (isfield(opt, 'progressbar_')) close(opt.progressbar_); end %% ------------------------------------------------------------------------- %% helper functions %% ------------------------------------------------------------------------- function [object, pos, index_esc, mmap] = parse_array(inputstr, pos, esc, index_esc, varargin) % JSON array is written in row-major order if (nargout > 3) mmap = {}; origpath = varargin{1}.jsonpath_; end 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 % for N-D packed array in a nested array construct, if (maxlevel >= 2 && ~isempty(regexp(arraystr(2:end), '^\s*\[', 'once'))) [dims, isndarray] = nestbracket2dim(arraystr); rowstart = find(arraystr(2:end) == '[', 1) + 1; if (rowstart && isndarray) [obj, nextidx] = parsendarray(arraystr, dims); if (nextidx >= length(arraystr) - 1) object = obj; 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(inputstr), pbar, 'loading ...'); end return end end end end end end if (isempty(regexp(arraystr, ':', 'once')) && 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) w2 = 0; while 1 varargin{1}.arraydepth_ = arraydepth + 1; if (nargout > 3) varargin{1}.jsonpath_ = [origpath sprintf('[%d]', length(object))]; mmap{end + 1} = {varargin{1}.jsonpath_, [pos, 0, w2]}; [val, pos, index_esc, newmmap] = parse_value(inputstr, pos, esc, index_esc, varargin{:}); mmap{end}{2}(2) = pos - mmap{end}{2}(1); mmap = [mmap(:); newmmap(:)]; else [val, pos, index_esc] = parse_value(inputstr, pos, esc, index_esc, varargin{:}); end object{end + 1} = val; [cc, pos] = next_char(inputstr, pos); if cc == ']' break end [pos, w1, w2] = parse_char(inputstr, pos, ','); end end end if (varargin{1}.simplifycell) if (iscell(object) && ~isempty(object) && (all(cellfun(@isnumeric, object)) || all(cellfun(@isstruct, object)))) 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 %% ------------------------------------------------------------------------- function [pos, w1, w2] = parse_char(inputstr, pos, c) w1 = pos; w2 = 0; pos = skip_whitespace(pos, inputstr); w1 = pos - w1; if pos > length(inputstr) || inputstr(pos) ~= c pos = error_pos(sprintf('Expected %c at position %%d', c), inputstr, pos); else pos = pos + 1; w2 = pos; pos = skip_whitespace(pos, inputstr); w2 = pos - w2; end %% ------------------------------------------------------------------------- function [c, pos, w1] = next_char(inputstr, pos) w1 = pos; pos = skip_whitespace(pos, inputstr); w1 = pos - w1; if pos > length(inputstr) c = []; else c = inputstr(pos); end %% ------------------------------------------------------------------------- function [str, pos, index_esc, mmap] = parseStr(inputstr, pos, esc, index_esc, varargin) if (nargout > 3) mmap = {}; end 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); %% ------------------------------------------------------------------------- function [num, pos] = parse_number(inputstr, pos, varargin) currstr = inputstr(pos:min(pos + 30, end)); [num, tmp, 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; %% ------------------------------------------------------------------------- function varargout = parse_value(inputstr, pos, esc, index_esc, varargin) len = length(inputstr); if (isfield(varargin{1}, 'progressbar_')) waitbar(pos / len, varargin{1}.progressbar_, 'loading ...'); end varargout{3} = index_esc; if (nargout > 3) varargout{4} = {}; end switch (inputstr(pos)) case '"' [varargout{1:nargout}] = parseStr(inputstr, pos, esc, index_esc, varargin{:}); return case '[' [varargout{1:nargout}] = parse_array(inputstr, pos, esc, index_esc, varargin{:}); return case '{' [varargout{1:nargout}] = parse_object(inputstr, pos, esc, index_esc, varargin{:}); if (varargout{2} < 0) varargin{1}.usemap = 1; [varargout{1:nargout}] = parse_object(inputstr, -varargout{2}, esc, index_esc, varargin{:}); end return case {'-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} [varargout{1:2}] = parse_number(inputstr, pos, varargin{:}); return case 't' if pos + 3 <= len && strcmpi(inputstr(pos:pos + 3), 'true') varargout{1} = true; varargout{2} = pos + 4; return end case 'f' if pos + 4 <= len && strcmpi(inputstr(pos:pos + 4), 'false') varargout{1} = false; varargout{2} = pos + 5; return end case 'n' if pos + 3 <= len && strcmpi(inputstr(pos:pos + 3), 'null') varargout{1} = []; varargout{2} = pos + 4; return end end varargout{2} = error_pos('Value expected at position %d', inputstr, pos); %% ------------------------------------------------------------------------- function [object, pos, index_esc, mmap] = parse_object(inputstr, pos, esc, index_esc, varargin) oldpos = pos; oldindex_esc = index_esc; if (nargout > 3) mmap = {}; origpath = varargin{1}.jsonpath_; end 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 (length(str) > 63) pos = -oldpos; index_esc = oldindex_esc; object = []; return end if isempty(str) && ~usemap str = 'x0x0_'; % empty name is valid in JSON, decodevarname('x0x0_') restores '\0' end [pos, w1, w2] = parse_char(inputstr, pos, ':'); if (nargout > 3) varargin{1}.jsonpath_ = [origpath, '.', str]; mmap{end + 1} = {varargin{1}.jsonpath_, [pos, 0, w2]}; [val, pos, index_esc, newmmap] = parse_value(inputstr, pos, esc, index_esc, varargin{:}); mmap{end}{2}(2) = pos - mmap{end}{2}(1); mmap = [mmap(:); newmmap(:)]; else [val, pos, index_esc] = parse_value(inputstr, pos, esc, index_esc, varargin{:}); end if (usemap) object(str) = val; else str = encodevarname(str, varargin{:}); if (length(str) > 63) pos = -oldpos; index_esc = oldindex_esc; object = []; return end object.(str) = val; end [cc, pos] = next_char(inputstr, pos); if cc == '}' break end pos = parse_char(inputstr, pos, ','); end end pos = parse_char(inputstr, pos, '}'); %% ------------------------------------------------------------------------- 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); %% ------------------------------------------------------------------------- function newpos = skip_whitespace(pos, inputstr) newpos = pos; while newpos <= length(inputstr) && isspace(inputstr(newpos)) newpos = newpos + 1; 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) || isempty(find(str == '\', 1))) return end newstr = sprintf(str); newstr = regexprep(newstr, '\\u([0-9A-Fa-f]{4})', '${char(base2dec($1,16))}'); %% ------------------------------------------------------------------------- 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')) = ' '; %% ------------------------------------------------------------------------- function [obj, nextidx] = parsendarray(arraystr, dims) astr = arraystr; astr(astr == '[') = ' '; astr(astr == ']') = ' '; astr(astr == ',') = ' '; [obj, count, errmsg, nextidx] = sscanf(astr, '%f', inf); if (nextidx >= length(astr) - 1) obj = reshape(obj, dims); nextidx = length(arraystr) + 1; end jsonlab-2.9.8/loadmsgpack.m000066400000000000000000000177101460134415400156350ustar00rootroot00000000000000function 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 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 function value = bytes2scalar(bytes, type) % reverse byte order to convert from little-endian to big-endian value = typecast(bytes(end:-1:1), type); 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; function [out, idx] = parsebytes(len, bytes, idx) out = bytes(idx:idx + len - 1); idx = idx + len; function [out, idx] = parseext(len, bytes, idx) obj.type = bytes(idx); obj.data = bytes(idx + 1:idx + len); idx = idx + len + 1; 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 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 jsonlab-2.9.8/loadnifti.m000066400000000000000000000011341460134415400153120ustar00rootroot00000000000000function varargout = loadnifti (varargin) % % jnii=loadnifti(filename) % or % nii=loadnifti(filename,option) % % Read a NIfTI-1/2 (*.nii/.nii.gz) or Analyze 7.5 (*.hdr/*.img/.hdr.gz/.img.gz) % image file. % % author: Qianqian Fang (q.fang neu.edu) % % Please run `help nii2jnii` to see the input output outputs. % This function is an alias to nii2jnii % % % this file is part of JNIfTI specification: https://github.com/NeuroJSON/jnifti % % License: Apache 2.0, see https://github.com/NeuroJSON/jnifti for details % [varargout{1:nargout}] = nii2jnii(varargin{:}); jsonlab-2.9.8/loadubjson.m000066400000000000000000000026611460134415400155070ustar00rootroot00000000000000function 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 the file with such name exists, it will % be read, otherwise, this function will attempt to parse the % string in fname as a UBJSON stream % opt: a struct to store parsing options, opt can be replaced by % a list of ('param',value) pairs - the param string is equivalent % 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{:}, 'endian', 'B'); jsonlab-2.9.8/lz4decode.m000066400000000000000000000027041460134415400152220ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/lz4encode.m000066400000000000000000000022311460134415400152270ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/lz4hcdecode.m000066400000000000000000000027261460134415400155410ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/lz4hcencode.m000066400000000000000000000022471460134415400155510ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/lzipdecode.m000066400000000000000000000027151460134415400154710ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/lzipencode.m000066400000000000000000000022401460134415400154740ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/lzmadecode.m000066400000000000000000000027151460134415400154560ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/lzmaencode.m000066400000000000000000000022401460134415400154610ustar00rootroot00000000000000function 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/NeuroJSON/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/NeuroJSON/zmat'); end jsonlab-2.9.8/match_bracket.m000066400000000000000000000037171460134415400161410ustar00rootroot00000000000000function [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, % including 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.9.8/memmapstream.m000066400000000000000000000056331460134415400160410ustar00rootroot00000000000000function outstruct = memmapstream(bytes, format, varargin) % % outstruct=memmapstream(bytes, format) % % Map a byte-array (in char array or uint8/int8 array) into a structure % using a dictionary (format is compatible with memmapfile in MATLAB) % % This function is compatible with both MATLAB and GNU Octave. % % author: Qianqian Fang (q.fang neu.edu) % % input: % bytes: a char, int8 or uint8 vector or array % format: a 3-column cell array in the format compatible with the % 'Format' parameter of memmapfile in MATLAB. It has the % following structure % % column 1: data type string, it can be one of the following % 'int8','int16','int32','int64', % 'uint8','uint16','uint32','uint64', % 'single','double','logical' % column 2: an integer vector denoting the size of the data % column 3: a string denoting the fieldname in the output struct % % For example format={'int8',[1,8],'key'; 'float',[1,1],'value'} % reads the first 8 bytes from 'bytes' as the first subfield % 'key' and the following 4 bytes as the floating point 'value' % subfield. % % output: % outstruct: a structure containing the required field % % example: % bytestream=['Andy' 5 'JT']; % format={'uint8', [1,4], 'name', % 'uint8', [1,1], 'age', % 'uint8', [1,2], 'school'}; % data=memmapstream(bytestream,format); % % this file is part of JNIfTI specification: https://github.com/NeuroJSON/jnifti % % License: Apache 2.0, see https://github.com/NeuroJSON/jnifti for details % if (nargin < 2) error('must provide bytes and format as inputs'); end if (~ischar(bytes) && ~isa(bytes, 'int8') && ~isa(bytes, 'uint8') || isempty(bytes)) error('first input, bytes, must be a char-array or uint8/int8 vector'); end if (~iscell(format) || size(format, 2) < 3 || size(format, 1) == 0 || ~ischar(format{1, 1})) error('second input, format, must be a 3-column cell array, in a format described by the memmapfile Format field.'); end bytes = bytes(:)'; datatype = struct('int8', 1, 'int16', 2, 'int32', 4, 'int64', 8, 'uint8', 1, 'uint16', 2, 'uint32', 4, 'uint64', 8, 'single', 4, 'double', 8); opt = varargin2struct(varargin{:}); opt.usemap = jsonopt('usemap', 0, opt) && exist('containers.Map'); if (opt.usemap) outstruct = containers.Map(); else outstruct = struct(); end len = 1; for i = 1:size(format, 1) bytelen = datatype.(format{i, 1}) * prod(format{i, 2}); if (opt.usemap) outstruct(format{i, 3}) = reshape(typecast(uint8(bytes(len:bytelen + len - 1)), format{i, 1}), format{i, 2}); else outstruct.(format{i, 3}) = reshape(typecast(uint8(bytes(len:bytelen + len - 1)), format{i, 1}), format{i, 2}); end len = len + bytelen; if (len > length(bytes)) break end end jsonlab-2.9.8/mergestruct.m000066400000000000000000000014011460134415400157020ustar00rootroot00000000000000function 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.9.8/nestbracket2dim.m000066400000000000000000000064711460134415400164330ustar00rootroot00000000000000function [dims, isndarray, maxlevel, count] = nestbracket2dim(str, brackets, testndarray) % % [dims, isndarray, 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)) % testndarray: (optional), 1 to test if the input string contains an % ND array, i.e. with uniform element lengths (recursively) % % 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. if testndarray is set to 1, dims returns isndarray % isndarray: 1 to indicate the input string contains an ND array, % otherwise, 0 % 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)); isndarray = testuniform(count, max(count)); if (nargin > 2 && testndarray) dims = isndarray; return end 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); function isndarray = testuniform(count, maxval) isndarray = false; if (length(count) > 2) idx = find(count(2:end) == count(1), 1); if (idx == length(count) - 2 && count(1) < maxval) isndarray = testuniform(count(2:end - 1), maxval); return end if (~isempty(idx) && mod(length(count) - 1, idx + 1) == 0) count2d = reshape(count(1:end - 1), idx + 1, []); if (all(diff(count2d') == 0)) isndarray = true; end end end jsonlab-2.9.8/nii2jnii.m000066400000000000000000000276741460134415400150750ustar00rootroot00000000000000function nii = nii2jnii(filename, format, varargin) % % nii=nii2jnii(niifile, format, options) % or % nii2jnii(niifile, jniifile, options) % nii=nii2jnii(niifile) % % A fast and portable NIFTI-1/2 and Analyze7.5 file parser and converter % to the text and binary JNIfTI formats defined in JNIfTI specification: % https://github.com/NeuroJSON/jnifti % % This function is compatible with both MATLAB and GNU Octave. % It accepts .nii, .nii.gz, .hdr/.img and .hdr.gz/.img.gz input files % % author: Qianqian Fang (q.fang neu.edu) % % input: % fname: the file name to the .nii, .nii.gz, .hdr/.img or .hdr.gz/.img.gz file % format:'nii' for reading the NIfTI-1/2/Analyze files; % 'jnii' to convert the nii data into an in-memory JNIfTI structure. % 'niiheader' return only the nii header without the image data % % if format is not listed above and nii2jnii is called without % an output, format must be a string specifying the output JNIfTI % file name - *.jnii for text-based JNIfTI, or *.bnii for the % binary version % options: (optional) if saving to a .bnii file, please see the options for % savebj.m (part of JSONLab); if saving to .jnii, please see the % supported options for savejson.m (part of JSONLab). % % output: % if the output is a JNIfTI data structure, it has the following subfield: % nii.NIFTIHeader - a structure containing the 1-to-1 mapped NIFTI-1/2 header % nii.NIFTIData - the main image data array % nii.NIFTIExtension - a cell array contaiing the extension data buffers % % when calling as nii=nii2jnii(file,'nii'), the output is a NIFTI object containing % nii.img: the data volume read from the nii file % nii.datatype: the data type of the voxel, in matlab data type string % nii.datalen: data count per voxel - for example RGB data has 3x % uint8 per voxel, so datatype='uint8', datalen=3 % nii.voxelbyte: total number of bytes per voxel: for RGB data, % voxelbyte=3; also voxelbyte=header.bitpix/8 % nii.hdr: file header info, a structure has the full nii header % key subfileds include % % sizeof_hdr: must be 348 (for NIFTI-1) or 540 (for NIFTI-2) % dim: short array, dim(2: dim(1)+1) defines the array size % datatype: the type of data stored in each voxel % bitpix: total bits per voxel % magic: must be 'ni1\0' or 'n+1\0' % % For the detailed nii header, please see % https://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h % % dependency: % No external dependency if reading .nii/.hdr/.img files; % % To load gzipped input files (.nii.gz/.hdr.gz/.img.gz), one must % install the ZMat Toolbox (http://github.com/NeuroJSON/zmat) and % JSONLab Toolbox (http://github.com/fangq/jsonlab); % % To save files into the text/binary JNIfTI formatted files, one % need to install JSONLab (http://github.com/fangq/jsonlab). % % this file was initially developed for the MCX project: https://github.com/fangq/mcx/blob/master/utils/mcxloadnii.m % % this file is part of JNIfTI specification: https://github.com/NeuroJSON/jnifti % % License: Apache 2.0, see https://github.com/NeuroJSON/jnifti for details % hdrfile = filename; isnii = -1; if (regexp(filename, '(\.[Hh][Dd][Rr](\.[Gg][Zz])*$|\.[Ii][Mm][Gg](\.[Gg][Zz])*$)')) isnii = 0; elseif (regexp(filename, '\.[Nn][Ii][Ii](\.[Gg][Zz])*$')) isnii = 1; end if (isnii < 0) error('file must be a NIfTI (.nii/.nii.gz) or Analyze 7.5 (.hdr/.img,.hdr.gz/.img.gz) data file'); end if (regexp(filename, '\.[Ii][Mm][Gg](\.[Gg][Zz])*$')) hdrfile = regexprep(filename, '\.[Ii][Mm][Gg](\.[Gg][Zz])*$', '.hdr$1'); end niftiheader = niiformat('nifti1'); if (~isempty(regexp(hdrfile, '\.[Gg][Zz]$', 'once')) || (exist('OCTAVE_VERSION', 'builtin') ~= 0)) finput = fopen(hdrfile, 'rb'); input = fread(finput, inf, 'uint8=>uint8'); fclose(finput); if (regexp(hdrfile, '\.[Gg][Zz]$')) if (~exist('gzipdecode', 'file')) error('To process zipped files, you must install gzipdecode.m from the JSONLab toolbox: http://github.com/fangq/jsonlab'); end gzdata = gzipdecode(input); else gzdata = input; end clear input; nii.hdr = memmapstream(gzdata, niftiheader); else fileinfo = dir(hdrfile); if (isempty(fileinfo)) error('specified file does not exist'); end header = memmapfile(hdrfile, ... 'Offset', 0, ... 'Writable', false, ... 'Format', niftiheader(1:end - (fileinfo.bytes < 352), :)); nii.hdr = header.Data(1); end [os, maxelem, dataendian] = computer; if (nii.hdr.sizeof_hdr ~= 348 && nii.hdr.sizeof_hdr ~= 540) nii.hdr.sizeof_hdr = swapbytes(nii.hdr.sizeof_hdr); end if (nii.hdr.sizeof_hdr == 540) % NIFTI-2 format niftiheader = niiformat('nifti2'); if (exist('gzdata', 'var')) nii.hdr = memmapstream(gzdata, niftiheader); else header = memmapfile(hdrfile, ... 'Offset', 0, ... 'Writable', false, ... 'Format', niftiheader(1:end - (fileinfo.bytes < 352), :)); nii.hdr = header.Data(1); end end if (nii.hdr.dim(1) > 7) names = fieldnames(nii.hdr); for i = 1:length(names) nii.hdr.(names{i}) = swapbytes(nii.hdr.(names{i})); end if (nii.hdr.sizeof_hdr > 540) nii.hdr.sizeof_hdr = swapbytes(nii.hdr.sizeof_hdr); end if (dataendian == 'B') dataendian = 'little'; else dataendian = 'big'; end end type2byte = [ 0 0 % unknown % 1 0 % binary (1 bit/voxel) % 2 1 % unsigned char (8 bits/voxel) % 4 2 % signed short (16 bits/voxel) % 8 4 % signed int (32 bits/voxel) % 16 4 % float (32 bits/voxel) % 32 8 % complex (64 bits/voxel) % 64 8 % double (64 bits/voxel) % 128 3 % RGB triple (24 bits/voxel) % 255 0 % not very useful (?) % 256 1 % signed char (8 bits) % 512 2 % unsigned short (16 bits) % 768 4 % unsigned int (32 bits) % 1024 8 % long long (64 bits) % 1280 8 % unsigned long long (64 bits) % 1536 16 % long double (128 bits) % 1792 16 % double pair (128 bits) % 2048 32 % long double pair (256 bits) % 2304 4 % 4 byte RGBA (32 bits/voxel) % ]; type2str = { 'uint8' 0 % unknown % 'uint8' 0 % binary (1 bit/voxel) % 'uint8' 1 % unsigned char (8 bits/voxel) % 'uint16' 1 % signed short (16 bits/voxel) % 'int32' 1 % signed int (32 bits/voxel) % 'single' 1 % float (32 bits/voxel) % 'single' 2 % complex (64 bits/voxel) % 'double' 1 % double (64 bits/voxel) % 'uint8' 3 % RGB triple (24 bits/voxel) % 'uint8' 0 % not very useful (?) % 'int8' 1 % signed char (8 bits) % 'uint16' 1 % unsigned short (16 bits) % 'uint32' 1 % unsigned int (32 bits) % 'int64' 1 % long long (64 bits) % 'uint64' 1 % unsigned long long (64 bits) % 'uint8' 16 % long double (128 bits) % 'uint8' 16 % double pair (128 bits) % 'uint8' 32 % long double pair (256 bits) % 'uint8' 4 % 4 byte RGBA (32 bits/voxel) % }; typeidx = find(type2byte(:, 1) == nii.hdr.datatype); nii.datatype = type2str{typeidx, 1}; nii.datalen = type2str{typeidx, 2}; nii.voxelbyte = type2byte(typeidx, 2); nii.endian = dataendian; if (type2byte(typeidx, 2) == 0) nii.img = []; return end if (type2str{typeidx, 2} > 1) nii.hdr.dim = [nii.hdr.dim(1) + 1 uint16(nii.datalen) nii.hdr.dim(2:end)]; end if (nargin > 1 && strcmp(format, 'niiheader')) return end if (regexp(filename, '\.[Hh][Dd][Rr](\.[Gg][Zz])*$')) filename = regexprep(filename, '\.[Hh][Dd][Rr](\.[Gg][Zz])*$', '.img$1'); end imgbytenum = prod(double(nii.hdr.dim(2:nii.hdr.dim(1) + 1))) * nii.voxelbyte; if (isnii == 0 && ~isempty(regexp(filename, '\.[Gg][Zz]$', 'once'))) finput = fopen(filename, 'rb'); input = fread(finput, inf, 'uint8=>uint8'); fclose(finput); gzdata = gzipdecode(input); nii.img = typecast(gzdata(1:imgbytenum), nii.datatype); else if (~exist('gzdata', 'var')) fid = fopen(filename, 'rb'); if (isnii) fseek(fid, nii.hdr.vox_offset, 'bof'); end nii.img = fread(fid, imgbytenum, [nii.datatype '=>' nii.datatype]); fclose(fid); else nii.img = typecast(gzdata(nii.hdr.vox_offset + 1:nii.hdr.vox_offset + imgbytenum), nii.datatype); end end nii.img = reshape(nii.img, nii.hdr.dim(2:nii.hdr.dim(1) + 1)); if (nargin > 1 && strcmp(format, 'nii')) return end nii0 = nii; nii = niiheader2jnii(nii0); nii.NIFTIData = nii0.img; if (isfield(nii0.hdr, 'extension') && nii0.hdr.extension(1) > 0) if (exist('gzdata', 'var')) nii.NIFTIExtension = cell(1); count = 1; bufpos = nii0.hdr.sizeof_hdr + 4; while (bufpos < nii0.hdr.vox_offset) nii.NIFTIExtension{count}.Size = typecast(gzdata(bufpos + 1:bufpos + 4), 'int32') - 8; nii.NIFTIExtension{count}.Type = typecast(gzdata(bufpos + 5:bufpos + 8), 'int32'); bufpos = bufpos + 8; if (strcmp(dataendian, 'big')) nii.NIFTIExtension{count}.Size = swapbytes(nii.NIFTIExtension{count}.Size); nii.NIFTIExtension{count}.Type = swapbytes(nii.NIFTIExtension{count}.Type); end if (bufpos + nii.NIFTIExtension{count}.Size <= nii0.hdr.vox_offset) nii.NIFTIExtension{count}.x0x5F_ByteStream_ = gzdata(bufpos + 1:bufpos + nii.NIFTIExtension{count}.Size); end bufpos = bufpos + bufpos + nii.NIFTIExtension{count}.Size; count = count + 1; end else fid = fopen(filename, 'rb'); fseek(fid, nii0.hdr.sizeof_hdr + 4, 'bof'); nii.NIFTIExtension = cell(1); count = 1; while (ftell(fid) < nii0.hdr.vox_offset) nii.NIFTIExtension{count}.Size = fread(fid, 1, 'int32=>int32') - 8; nii.NIFTIExtension{count}.Type = fread(fid, 1, 'int32=>int32'); if (strcmp(dataendian, 'big')) nii.NIFTIExtension{count}.Size = swapbytes(nii.NIFTIExtension{count}.Size); nii.NIFTIExtension{count}.Type = swapbytes(nii.NIFTIExtension{count}.Type); end if (ftell(fid) + nii.NIFTIExtension{count}.Size < nii0.hdr.vox_offset) nii.NIFTIExtension{count}.x0x5F_ByteStream_ = fread(fid, nii.NIFTIExtension{count}.Size, 'uint8=>uint8'); end count = count + 1; end fclose(fid); end end if (nargout == 0 && strcmp(format, 'nii') == 0 && strcmp(format, 'jnii') == 0) if (~exist('savejson', 'file')) error('you must first install JSONLab from http://github.com/fangq/jsonlab/'); end if (regexp(format, '\.jnii$')) savejson('', nii, 'FileName', format, varargin{:}); elseif (regexp(format, '\.bnii$')) savebj('', nii, 'FileName', format, varargin{:}); else error('file suffix must be .jnii for text JNIfTI or .bnii for binary JNIfTI'); end end jsonlab-2.9.8/niicodemap.m000066400000000000000000000073361460134415400154630ustar00rootroot00000000000000function newval = niicodemap(name, value) % % newval=niicodemap(name, value) % % Bi-directional conversion from NIFTI codes to human-readable JNIfTI % header string values % % author: Qianqian Fang (q.fang neu.edu) % % input: % name: a header name as a string, currently support the below nii % headers: 'intent_code', 'slice_code', 'datatype', 'qform', % 'sform' and 'xyzt_units' and their corresponding JNIfTI % headers: % 'Intent','SliceType','DataType','QForm','SForm','Unit' % value:the current header value, if it is a code, newval will % output the string version; if it is a string, newval will % return the code % % output: % newval: the converted header value % % For the detailed nii header codes, please see % https://nifti.nimh.nih.gov/pub/dist/src/niftilib/nifti1.h % % example: % newval=niicodemap('slice_code', '') % newval=niicodemap('datatype', 'uint64') % newval=niicodemap('datatype', 2) % % this file was initially developed for the MCX project: https://github.com/fangq/mcx/blob/master/utils/mcxloadnii.m % % this file is part of JNIfTI specification: https://github.com/NeuroJSON/jnifti % % License: Apache 2.0, see https://github.com/NeuroJSON/jnifti for details % % code to name look-up-table if (~exist('containers.Map')) newval = value; return end lut.intent_code = containers.Map([0, 2:24 1001:1011 2001:2005], ... {'', 'corr', 'ttest', 'ftest', 'zscore', 'chi2', 'beta', ... 'binomial', 'gamma', 'poisson', 'normal', 'ncftest', ... 'ncchi2', 'logistic', 'laplace', 'uniform', 'ncttest', ... 'weibull', 'chi', 'invgauss', 'extval', 'pvalue', ... 'logpvalue', 'log10pvalue', 'estimate', 'label', 'neuronames', ... 'matrix', 'symmatrix', 'dispvec', 'vector', 'point', 'triangle', ... 'quaternion', 'unitless', 'tseries', 'elem', 'rgb', 'rgba', 'shape'}); lut.slice_code = containers.Map(0:6, {'', 'seq+', 'seq-', 'alt+', 'alt-', 'alt2+', 'alt-'}); lut.datatype = containers.Map([0, 2, 4, 8, 16, 32, 64, 128, 256, 512, 768, 1024, 1280, 1536, 1792, 2048, 2304], ... {'', 'uint8', 'int16', 'int32', 'single', 'complex64', 'double', 'rgb24', 'int8', ... 'uint16', 'uint32', 'int64', 'uint64', 'double128', 'complex128', ... 'complex256', 'rgba32' }); lut.xyzt_units = containers.Map([0:3 8 16 24 32 40 48], ... {'', 'm', 'mm', 'um', 's', 'ms', 'us', 'hz', 'ppm', 'rad'}); lut.qform = containers.Map(0:4, {'', 'scanner', 'aligned', 'talairach', 'mni'}); lut.unit = lut.xyzt_units; lut.sform = lut.qform; lut.slicetype = lut.slice_code; lut.intent = lut.intent_code; % inverse look up table tul.intent_code = containers.Map(values(lut.intent_code), keys(lut.intent_code)); tul.slice_code = containers.Map(values(lut.slice_code), keys(lut.slice_code)); tul.datatype = containers.Map(values(lut.datatype), keys(lut.datatype)); tul.xyzt_units = containers.Map(values(lut.xyzt_units), keys(lut.xyzt_units)); tul.qform = containers.Map(values(lut.qform), keys(lut.qform)); tul.sform = tul.qform; tul.slicetype = tul.slice_code; tul.intent = tul.intent_code; tul.unit = tul.xyzt_units; % map from code to name, or frmo name to code if (~isfield(lut, lower(name))) error('property can not be found'); end if (~(ischar(value) || isa(value, 'string'))) newval = lut.(lower(name))(value); else newval = tul.(lower(name))(value); end jsonlab-2.9.8/niiformat.m000066400000000000000000000241201460134415400153310ustar00rootroot00000000000000function niiheader = niiformat(format) % % niiheader=niiformat(format) % % Return a NIfTI header format descriptor as an Nx3 cell array % % author: Qianqian Fang (q.fang neu.edu) % % input: % format:'nifti1' - return the header descriptor for NIfTI-1 format % 'nifti2' - return the header descriptor for NIfTI-2 format % % output: % niiheader: an Nx3 cell array in the format similar to the 'Format' % specifier of the memmapfile.m function in MATLAB % It has the following structure: % % column 1: data type string, it can be one of the following % 'int8','int16','int32','int64', % 'uint8','uint16','uint32','uint64', % 'single','double' % column 2: an integer vector denoting the size of the data % column 3: a string denoting the fieldname in the output struct % % this file is part of JNIfTI specification: https://github.com/NeuroJSON/jnifti % % License: Apache 2.0, see https://github.com/NeuroJSON/jnifti for details % header.nifti1 = { ... 'int32' [1 1] 'sizeof_hdr' % !< MUST be 348 % % int sizeof_hdr; % ... 'int8' [1 10] 'data_type' % !< ++UNUSED++ % % char data_type[10]; % ... 'int8' [1 18] 'db_name' % !< ++UNUSED++ % % char db_name[18]; % ... 'int32' [1 1] 'extents' % !< ++UNUSED++ % % int extents; % ... 'int16' [1 1] 'session_error' % !< ++UNUSED++ % % short session_error; % ... 'int8' [1 1] 'regular' % !< ++UNUSED++ % % char regular; % ... 'int8' [1 1] 'dim_info' % !< MRI slice ordering. % % char hkey_un0; % ... 'uint16' [1 8] 'dim' % !< Data array dimensions.% % short dim[8]; % ... 'single' [1 1] 'intent_p1' % !< 1st intent parameter. % % short unused8/9; % ... 'single' [1 1] 'intent_p2' % !< 2nd intent parameter. % % short unused10/11; % ... 'single' [1 1] 'intent_p3' % !< 3rd intent parameter. % % short unused12/13; % ... 'int16' [1 1] 'intent_code' % !< NIFTI_INTENT_* code. % % short unused14; % ... 'int16' [1 1] 'datatype' % !< Defines data type! % % short datatype; % ... 'int16' [1 1] 'bitpix' % !< Number bits/voxel. % % short bitpix; % ... 'int16' [1 1] 'slice_start' % !< First slice index. % % short dim_un0; % ... 'single' [1 8] 'pixdim' % !< Grid spacings. % % float pixdim[8]; % ... 'single' [1 1] 'vox_offset' % !< Offset into .nii file % % float vox_offset; % ... 'single' [1 1] 'scl_slope' % !< Data scaling: slope. % % float funused1; % ... 'single' [1 1] 'scl_inter' % !< Data scaling: offset. % % float funused2; % ... 'int16' [1 1] 'slice_end' % !< Last slice index. % % float funused3; % ... 'int8' [1 1] 'slice_code' % !< Slice timing order. % ... 'int8' [1 1] 'xyzt_units' % !< Units of pixdim[1..4] % ... 'single' [1 1] 'cal_max' % !< Max display intensity % % float cal_max; % ... 'single' [1 1] 'cal_min' % !< Min display intensity % % float cal_min; % ... 'single' [1 1] 'slice_duration' % !< Time for 1 slice. % % float compressed; % ... 'single' [1 1] 'toffset' % !< Time axis shift. % % float verified; % ... 'int32' [1 1] 'glmax' % !< ++UNUSED++ % % int glmax; % ... 'int32' [1 1] 'glmin' % !< ++UNUSED++ % % int glmin; % ... 'int8' [1 80] 'descrip' % !< any text you like. % % char descrip[80]; % ... 'int8' [1 24] 'aux_file' % !< auxiliary filename. % % char aux_file[24]; % ... 'int16' [1 1] 'qform_code' % !< NIFTI_XFORM_* code. % %-- all ANALYZE 7.5 --- % ... 'int16' [1 1] 'sform_code' % !< NIFTI_XFORM_* code. % %below here are replaced% ... 'single' [1 1] 'quatern_b' % !< Quaternion b param. % ... 'single' [1 1] 'quatern_c' % !< Quaternion c param. % ... 'single' [1 1] 'quatern_d' % !< Quaternion d param. % ... 'single' [1 1] 'qoffset_x' % !< Quaternion x shift. % ... 'single' [1 1] 'qoffset_y' % !< Quaternion y shift. % ... 'single' [1 1] 'qoffset_z' % !< Quaternion z shift. % ... 'single' [1 4] 'srow_x' % !< 1st row affine transform. % ... 'single' [1 4] 'srow_y' % !< 2nd row affine transform. % ... 'single' [1 4] 'srow_z' % !< 3rd row affine transform. % ... 'int8' [1 16] 'intent_name' % !< 'name' or meaning of data. % ... 'int8' [1 4] 'magic' % !< MUST be "ni1\0" or "n+1\0". % ... 'int8' [1 4] 'extension' % !< header extension % ... }; header.nifti2 = { ... 'int32' [1 1] 'sizeof_hdr' % !< MUST be 540 % % int sizeof_hdr; % ... 'int8' [1 8] 'magic' % !< MUST be "ni2\0" or "n+2\0". % ... 'int16' [1 1] 'datatype' % !< Defines data type! % % short datatype; % ... 'int16' [1 1] 'bitpix' % !< Number bits/voxel. % % short bitpix; % ... 'int64' [1 8] 'dim' % !< Data array dimensions.% % short dim[8]; % ... 'double' [1 1] 'intent_p1' % !< 1st intent parameter. % % short unused8/9; % ... 'double' [1 1] 'intent_p2' % !< 2nd intent parameter. % % short unused10/11; % ... 'double' [1 1] 'intent_p3' % !< 3rd intent parameter. % % short unused12/13; % ... 'double' [1 8] 'pixdim' % !< Grid spacings. % % float pixdim[8]; % ... 'int64' [1 1] 'vox_offset' % !< Offset into .nii file % % float vox_offset; % ... 'double' [1 1] 'scl_slope' % !< Data scaling: slope. % % float funused1; % ... 'double' [1 1] 'scl_inter' % !< Data scaling: offset. % % float funused2; % ... 'double' [1 1] 'cal_max' % !< Max display intensity % % float cal_max; % ... 'double' [1 1] 'cal_min' % !< Min display intensity % % float cal_min; % ... 'double' [1 1] 'slice_duration' % !< Time for 1 slice. % % float compressed; % ... 'double' [1 1] 'toffset' % !< Time axis shift. % % float verified; % ... 'int64' [1 1] 'slice_start' % !< First slice index. % % short dim_un0; % ... 'int64' [1 1] 'slice_end' % !< Last slice index. % % float funused3; % ... 'int8' [1 80] 'descrip' % !< any text you like. % % char descrip[80]; % ... 'int8' [1 24] 'aux_file' % !< auxiliary filename. % % char aux_file[24]; % ... 'int32' [1 1] 'qform_code' % !< NIFTI_XFORM_* code. % %-- all ANALYZE 7.5 --- % ... 'int32' [1 1] 'sform_code' % !< NIFTI_XFORM_* code. % %below here are replaced% ... 'double' [1 1] 'quatern_b' % !< Quaternion b param. % ... 'double' [1 1] 'quatern_c' % !< Quaternion c param. % ... 'double' [1 1] 'quatern_d' % !< Quaternion d param. % ... 'double' [1 1] 'qoffset_x' % !< Quaternion x shift. % ... 'double' [1 1] 'qoffset_y' % !< Quaternion y shift. % ... 'double' [1 1] 'qoffset_z' % !< Quaternion z shift. % ... 'double' [1 4] 'srow_x' % !< 1st row affine transform. % ... 'double' [1 4] 'srow_y' % !< 2nd row affine transform. % ... 'double' [1 4] 'srow_z' % !< 3rd row affine transform. % ... 'int32' [1 1] 'slice_code' % !< Slice timing order. % ... 'int32' [1 1] 'xyzt_units' % !< Units of pixdim[1..4] % ... 'int32' [1 1] 'intent_code' % !< NIFTI_INTENT_* code. % % short unused14; % ... 'int8' [1 16] 'intent_name' % !< 'name' or meaning of data. % ... 'int8' [1 1] 'dim_info' % !< MRI slice ordering. % % char hkey_un0; % ... 'int8' [1 15] 'reserved' % !< unused buffer % ... 'int8' [1 4] 'extension' % !< header extension % ... }; if (nargin < 1) format = 'nifti1'; end format = lower(format); if (isfield(header, format)) niiheader = header.(format); else error('format must be either nifti1 or nifti2'); end jsonlab-2.9.8/niiheader2jnii.m000066400000000000000000000065241460134415400162350ustar00rootroot00000000000000function nii = niiheader2jnii(nii0) nii = struct(); nii.NIFTIHeader.NIIHeaderSize = nii0.hdr.sizeof_hdr; if (isfield(nii0.hdr, 'data_type')) nii.NIFTIHeader.A75DataTypeName = deblank(char(nii0.hdr.data_type)); nii.NIFTIHeader.A75DBName = deblank(char(nii0.hdr.db_name)); nii.NIFTIHeader.A75Extends = nii0.hdr.extents; nii.NIFTIHeader.A75SessionError = nii0.hdr.session_error; nii.NIFTIHeader.A75Regular = nii0.hdr.regular; end nii.NIFTIHeader.DimInfo.Freq = bitand(uint8(nii0.hdr.dim_info), 7); nii.NIFTIHeader.DimInfo.Phase = bitand(bitshift(uint8(nii0.hdr.dim_info), -3), 7); nii.NIFTIHeader.DimInfo.Slice = bitand(bitshift(uint8(nii0.hdr.dim_info), -6), 7); nii.NIFTIHeader.Dim = nii0.hdr.dim(2:2 + nii0.hdr.dim(1) - 1); nii.NIFTIHeader.Param1 = nii0.hdr.intent_p1; nii.NIFTIHeader.Param2 = nii0.hdr.intent_p2; nii.NIFTIHeader.Param3 = nii0.hdr.intent_p3; nii.NIFTIHeader.Intent = niicodemap('intent', nii0.hdr.intent_code); nii.NIFTIHeader.DataType = niicodemap('datatype', nii0.hdr.datatype); nii.NIFTIHeader.BitDepth = nii0.hdr.bitpix; nii.NIFTIHeader.FirstSliceID = nii0.hdr.slice_start; nii.NIFTIHeader.VoxelSize = nii0.hdr.pixdim(2:2 + nii0.hdr.dim(1) - 1); nii.NIFTIHeader.Orientation = struct('x', 'r', 'y', 'a', 'z', 's'); if (nii0.hdr.pixdim(1) < 0) nii.NIFTIHeader.Orientation = struct('x', 'l', 'y', 'a', 'z', 's'); end nii.NIFTIHeader.NIIByteOffset = nii0.hdr.vox_offset; nii.NIFTIHeader.ScaleSlope = nii0.hdr.scl_slope; nii.NIFTIHeader.ScaleOffset = nii0.hdr.scl_inter; nii.NIFTIHeader.LastSliceID = nii0.hdr.slice_end; nii.NIFTIHeader.SliceType = niicodemap('slicetype', nii0.hdr.slice_code); nii.NIFTIHeader.Unit.L = niicodemap('unit', bitand(uint8(nii0.hdr.xyzt_units), 7)); nii.NIFTIHeader.Unit.T = niicodemap('unit', bitand(uint8(nii0.hdr.xyzt_units), 56)); nii.NIFTIHeader.MaxIntensity = nii0.hdr.cal_max; nii.NIFTIHeader.MinIntensity = nii0.hdr.cal_min; nii.NIFTIHeader.SliceTime = nii0.hdr.slice_duration; nii.NIFTIHeader.TimeOffset = nii0.hdr.toffset; if (isfield(nii0.hdr, 'glmax')) nii.NIFTIHeader.A75GlobalMax = nii0.hdr.glmax; nii.NIFTIHeader.A75GlobalMin = nii0.hdr.glmin; end nii.NIFTIHeader.Description = deblank(char(nii0.hdr.descrip)); nii.NIFTIHeader.AuxFile = deblank(char(nii0.hdr.aux_file)); nii.NIFTIHeader.QForm = nii0.hdr.qform_code; nii.NIFTIHeader.SForm = nii0.hdr.sform_code; nii.NIFTIHeader.Quatern.b = nii0.hdr.quatern_b; nii.NIFTIHeader.Quatern.c = nii0.hdr.quatern_c; nii.NIFTIHeader.Quatern.d = nii0.hdr.quatern_d; nii.NIFTIHeader.QuaternOffset.x = nii0.hdr.qoffset_x; nii.NIFTIHeader.QuaternOffset.y = nii0.hdr.qoffset_y; nii.NIFTIHeader.QuaternOffset.z = nii0.hdr.qoffset_z; nii.NIFTIHeader.Affine(1, :) = nii0.hdr.srow_x; nii.NIFTIHeader.Affine(2, :) = nii0.hdr.srow_y; nii.NIFTIHeader.Affine(3, :) = nii0.hdr.srow_z; nii.NIFTIHeader.Name = deblank(char(nii0.hdr.intent_name)); nii.NIFTIHeader.NIIFormat = deblank(char(nii0.hdr.magic)); if (isfield(nii0.hdr, 'extension')) nii.NIFTIHeader.NIIExtender = nii0.hdr.extension; end nii.NIFTIHeader.NIIQfac_ = nii0.hdr.pixdim(1); nii.NIFTIHeader.NIIEndian_ = nii0.endian; if (isfield(nii0.hdr, 'reserved')) nii.NIFTIHeader.NIIUnused_ = nii0.hdr.reserved; end jsonlab-2.9.8/octavezmat.m000066400000000000000000000123271460134415400155240ustar00rootroot00000000000000function varargout = octavezmat(data, iscompress, zipmethod) % % output = octavezmat(input, iscompress, zipmethod) % or % [output, info] = octavezmat(input, iscompress, zipmethod) % unzipdata = octavezmat(zipdata, info) % % Compress or decompress zlib and gzip memory buffers using zip/unzip/gzip/gunzip on Octave % in case ZMat toolbox (http://github.com/NeuroJSON/zmat) was not installed (ZMat is much faster) % % Author: Qianqian Fang (q.fang neu.edu) % % input: % input: the input data (can be either compressed or before compression), % can be a string, a numerical vector or array % iscompress: (optional) if iscompress is 1, zmat compresses/encodes the input, % if 0, it decompresses/decodes the input. Default value is 1. % % if iscompress is set to a negative integer, (-iscompress) specifies % the compression level. For zlib/gzip, default level is 6 (1-9); for % lzma/lzip, default level is 5 (1-9); for lz4hc, default level is 8 (1-16). % the default compression level is used if iscompress is set to 1. % % zmat removes the trailing newline when iscompress=2 and method='base64' % all newlines are kept when iscompress=3 and method='base64' % % if one defines iscompress as the info struct (2nd output of zmat), zmat % will perform a decoding/decompression operation and recover the original % input using the info stored in the info structure. % method: (optional) compression method, only the below two methods are supported % 'zlib': zlib/zip based data compression (default) % 'gzip': gzip formatted data compression % % 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 % info: (optional) a struct storing additional info regarding the input data, may have % 'type': the class of the input array % 'size': the dimensions of the input array % 'byte': the number of bytes per element in the input array % 'method': a copy of the 3rd input indicating the encoding method % 'status': the zlib/lzma/lz4 compression/decompression function return value, % including potential error codes; see documentation of the respective % libraries for details % 'level': a copy of the iscompress flag; if non-zero, specifying compression % level, see above % % examples: % NO_ZMAT=1 % by setting this flag to 1 in the caller or global workspace, octavezmat won't warn zmat is missing % [ss,info]=octavezmat(ones(10)) % orig=octavezmat(ss,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) % nowarning = getvarfrom({'caller', 'base'}, 'NO_ZMAT'); if (isempty(nowarning) || nowarning == 0) warning('You are recommended to install ZMat (http://github.com/NeuroJSON/zmat) get much faster speed in Octave'); end if (nargin < 1) fprintf(1, 'Format: output = octavezmat(data, iscompress, zipmethod)\n'); return end if (nargin < 2) iscompress = 1; end if (nargin < 3) zipmethod = 'zlib'; end if (isstruct(iscompress)) inputinfo = iscompress; iscompress = 0; end if (~(ischar(data) || islogical(data) || (isnumeric(data) && isreal(data)))) error('input must be a char, non-complex numeric or logical vector or N-D array'); end if (ischar(data)) data = uint8(data); end fname = tempname; tmpfile = fname; outputfile = fname; suff = struct('zlib', '.zip', 'gzip', '.gz'); if (~isfield(suff, zipmethod)) error('zipmethod is not supported'); end if (~iscompress) tmpfile = [fname suff.(zipmethod)]; end fd = fopen(tmpfile, 'wb'); if (~fd) error('unable to create temporary file'); end fwrite(fd, typecast(data(:), 'uint8'), 'uint8'); fclose(fd); if (iscompress) outputfile = [fname suff.(zipmethod)]; end if (~iscompress) if (strcmp(zipmethod, 'zlib')) outputfile = unzip(tmpfile, tempdir); if ((exist('OCTAVE_VERSION', 'builtin') ~= 0)) outputfile = [tempdir filesep outputfile{1}]; else outputfile = outputfile{1}; end elseif (strcmp(zipmethod, 'gzip')) gunzip(tmpfile); end else if (strcmp(zipmethod, 'zlib')) zip(outputfile, tmpfile); elseif (strcmp(zipmethod, 'gzip')) gzip(tmpfile); end end if (exist(tmpfile, 'file')) delete(tmpfile); end fd = fopen(outputfile, 'rb'); if (~fd) error('failed to unzip buffer'); end varargout{1} = fread(fd, [1 inf], 'uint8=>uint8'); fclose(fd); if (exist(outputfile, 'file')) delete(outputfile); end if (nargout > 1) varargout{2} = struct('type', class(data), 'size', size(data), 'method', zipmethod, 'status', 0, 'level', iscompress); end if (exist('inputinfo', 'var') && isfield(inputinfo, 'type')) if (strcmp(inputinfo.type, 'logical')) varargout{1} = logical(varargout{1}); else varargout{1} = typecast(varargout{1}, inputinfo.type); end varargout{1} = reshape(varargout{1}, inputinfo.size); end jsonlab-2.9.8/regrouph5.m000066400000000000000000000107421460134415400152660ustar00rootroot00000000000000function data = regrouph5(root, varargin) % % data=regrouph5(root) % or % data=regrouph5(root,type) % data=regrouph5(root,{'nameA','nameB',...}) % % Processing a loadh5 restored data and merge "indexed datasets", whose % names start with an ASCII string followed by a contiguous integer % sequence number starting from 1, into a cell array. For example, % datasets {data.a1, data.a2, data.a3} will be merged into a cell/struct % array data.a with 3 elements. % % A single subfield .name1 will be renamed as .name. Items with % non-contigous numbering will not be grouped. If .name and % .name1/.name2 co-exist in the input struct, no grouping will be done. % % The grouped subfield will appear at the position of the first % pre-grouped item in the original input structure. % % author: Qianqian Fang (q.fang neu.edu) % % input: % root: the raw input HDF5 data structure (loaded from loadh5.m) % type: if type is set as a cell array of strings, it restrict the % grouping only to the subset of field names in this list; % if type is a string as 'snirf', it is the same as setting % type as {'aux','data','nirs','stim','measurementList'}. % % output: % data: a reorganized matlab structure. % % example: % a=struct('a1',rand(5),'a2','string','a3',true,'d',2+3i,'e',{'test',[],1:5}); % regrouph5(a) % saveh5(a,'test.h5'); % rawdata=loadh5('test.h5') % data=regrouph5(rawdata) % % this file is part of EasyH5 Toolbox: https://github.com/NeuroJSON/easyh5 % % License: GPLv3 or 3-clause BSD license, see https://github.com/NeuroJSON/easyh5 for details % if (nargin < 1) help regrouph5; return end dict = {}; if (~isempty(varargin)) if (ischar(varargin{1}) && strcmpi(varargin{1}, 'snirf')) dict = {'aux', 'data', 'nirs', 'stim', 'measurementList'}; elseif (iscell(varargin{1})) dict = varargin{1}; end end data = struct; if (isstruct(root)) data = repmat(struct, size(root)); names = fieldnames(root); newnames = struct(); firstpos = struct(); for i = 1:length(names) item = regexp(names{i}, '^(.*\D)(\d+)$', 'tokens'); if (~isempty(item) && str2double(item{1}{2}) ~= 0 && ~isfield(root, item{1}{1})) if (~isfield(newnames, item{1}{1})) newnames.(item{1}{1}) = str2double(item{1}{2}); else newnames.(item{1}{1}) = [newnames.(item{1}{1}), str2double(item{1}{2})]; end if (~isfield(firstpos, item{1}{1})) firstpos.(item{1}{1}) = length(fieldnames(data(1))); end else for j = 1:length(root) if (isstruct(root(j).(names{i}))) data(j).(names{i}) = regrouph5(root(j).(names{i})); else data(j).(names{i}) = root(j).(names{i}); end end end end names = fieldnames(newnames); if (~isempty(dict)) names = intersect(names, dict); end for i = length(names):-1:1 len = length(newnames.(names{i})); idx = newnames.(names{i}); if ((min(idx) ~= 1 || max(idx) ~= len) && len ~= 1) for j = 1:len dataname = sprintf('%s%d', names{i}, idx(j)); for k = 1:length(root) if (isstruct(root(k).(dataname))) data(k).(dataname) = regrouph5(root(k).(dataname)); else data(k).(dataname) = root(k).(dataname); end end end pos = firstpos.(names{i}); len = length(fieldnames(data)); data = orderfields(data, [1:pos, len, pos + 1:len - 1]); continue end for j = 1:length(data) data(j).(names{i}) = cell(1, len); end idx = sort(idx); for j = 1:len for k = 1:length(root) obj = root(k).(sprintf('%s%d', names{i}, idx(j))); if (isstruct(obj)) data(k).(names{i}){j} = regrouph5(obj); else data(k).(names{i}){j} = obj; end end end pos = firstpos.(names{i}); len = length(fieldnames(data)); data = orderfields(data, [1:pos, len, pos + 1:len - 1]); try data.(names{i}) = cell2mat(data.(names{i})); catch end end end jsonlab-2.9.8/savebj.m000066400000000000000000001133751460134415400146260ustar00rootroot00000000000000function output = 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-2), 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). % Starting from BJD Draft-2 (JSONLab 3.0 beta or later), all integer and % floating-point numbers are stored in Little-Endian as opposed to % Big-Endian form as in BJD Draft-1/UBJSON Draft-12 (JSONLab 2.1 or older) % % Format specifications: % Binary JData (BJD): https://github.com/NeuroJSON/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]: convert 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 integer 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 [inf|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);all numeric values are stored in % the Big-Endian byte order according to Draft-12 % 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 ['L'|'B']: specify the endianness of the numbers % in the BJData/UBJSON input data. Default: 'L'. % % Starting from JSONLab 2.9, BJData by default uses % [L] Little-Endian for both integers and floating % point numbers. This is a major departure from the % UBJSON specification, where 'B' - Big-Endian - % format is used for integer fields. UBJSON does % not specifically define Endianness for % floating-point numbers, resulting in mixed % implementations. JSONLab 2.0-2.1 used 'B' for % integers and floating-points; JSONLab 1.x uses % 'B' for integers and native-endianness for % floating-point numbers. % FileEndian ['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 equivalent 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,'debug',1) % 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', inf, 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; [os, maxelem, systemendian] = computer; opt.flipendian_ = (systemendian ~= upper(jsonopt('Endian', 'L', opt))); if (jsonopt('PreEncode', 1, opt)) obj = jdataencode(obj, 'Base64', 0, 'UseArrayZipSize', opt.messagepack, opt); end dozip = opt.compression; if (~isempty(dozip)) if (~ismember(dozip, {'zlib', 'gzip', 'lzma', 'lzip', 'lz4', 'lz4hc'}) && isempty(regexp(dozip, '^blosc2', 'once'))) 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); fileendian = jsonopt('FileEndian', 'n', opt); writemode = 'w'; if (jsonopt('Append', 0, opt)) writemode = 'a'; end if (~exist('OCTAVE_VERSION', 'builtin')) fid = fopen(filename, writemode, fileendian, encoding); else fid = fopen(filename, writemode, fileendian); end fwrite(fid, uint8(json)); fclose(fid); end if (nargout > 0 || isempty(filename)) output = json; 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') || isa(item, 'dictionary')) 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 = ''; itemtype = isa(item, 'containers.Map'); dim = size(item); if (isa(item, 'dictionary')) itemtype = 2; dim = item.numEntries; end if (itemtype == 0) error('input is not a containers.Map or dictionary class'); end names = keys(item); val = values(item); if (~iscell(names)) names = num2cell(names, ndims(names)); end if (~iscell(val)) val = num2cell(val, ndims(val)); end Omarker = varargin{1}.OM_; if (~strcmp(Omarker{1}, '{')) om0 = Imsgpk_(length(names), 222, 128, varargin{:}); else om0 = Omarker{1}; end if (~isempty(name)) txt = [N_(decodevarname(name, varargin{:}), varargin{:}) om0]; else txt = om0; end for i = 1:dim(1) if (~isempty(names{i})) txt = [txt obj2ubjson(names{i}, val{i}, ... level + (dim(1) > 1), varargin{:})]; end end txt = [txt Omarker{2}]; if (isa(txt, 'string') && length(txt) > 1) txt = sprintf('%s', txt); 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)]; encodeparam = {}; if (~isempty(regexp(dozip, '^blosc2', 'once'))) compfun = @blosc2encode; encodeparam = {dozip, 'nthread', jsonopt('nthread', 1, opt), 'shuffle', jsonopt('shuffle', 1, opt), 'typesize', jsonopt('typesize', length(typecast(fulldata(1), 'uint8')), opt)}; else compfun = str2func([dozip 'encode']); end txt = [txt, N_('_ArrayZipData_', opt), I_a(compfun(typecast(fulldata(:), 'uint8'), encodeparam{:}), 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 % array 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 rowmat = permute(mat, ndims(mat):-1:1); txt = I_a(rowmat(:), 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 rowmat = permute(mat, ndims(mat):-1:1); txt = I_a(uint8(rowmat(:)), Imarker(1), size(mat), varargin{:}); end end else am0 = Amarker{1}; if (Amarker{1} ~= '[') am0 = char(145); end if (numel(mat) == 1) if (varargin{1}.singletarray == 1) txt = [am0 D_(mat, varargin{:}) Amarker{2}]; else txt = D_(mat, varargin{:}); end else if (~isvector(mat) && isnest == 1) txt = cell2ubjson('', num2cell(mat, 1), level, varargin{:}); else rowmat = permute(mat, ndims(mat):-1:1); txt = D_a(rowmat(:), Fmarker(isa(rowmat, 'double') + 2), size(mat), varargin{:}); end end end %% ------------------------------------------------------------------------- function val = N_(str, varargin) ismsgpack = varargin{1}.messagepack; str = char(str); 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(endiancheck(cast(num, 'uint32'), varargin{:}), 'uint8')]; elseif (val(1) < char(209)) num = uint16(num); val = [char(209) data2byte(endiancheck(cast(num, 'uint16'), varargin{:}), 'uint8')]; end val(1) = char(val(1) - 209 + base1); %% ------------------------------------------------------------------------- function val = I_(num, varargin) if (~isinteger(num)) error('input is not an integer'); end Imarker = varargin{1}.IM_; cid = varargin{1}.IType_; isdebug = varargin{1}.debug; if (isfield(varargin{1}, 'inttype_')) if (isdebug) val = [Imarker(varargin{1}.inttype_) sprintf('<%.0f>', num)]; else val = [Imarker(varargin{1}.inttype_) data2byte(endiancheck(cast(num, cid{varargin{1}.inttype_}), varargin{:}), '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((endiancheck(cast(num, 'uint8'), varargin{:}) & 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(endiancheck(cast(num, cid{i}), varargin{:}), '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(endiancheck(num, varargin{:}), '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(endiancheck(cast(num, cid{id}), varargin{:}), '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(endiancheck(cast(num, varargin{1}.FType_{id}), varargin{:}), '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(:)'); %% ------------------------------------------------------------------------- function newdata = endiancheck(data, varargin) if (varargin{1}.flipendian_) newdata = swapbytes(data); else newdata = data; end jsonlab-2.9.8/savejd.m000066400000000000000000000073461460134415400146300ustar00rootroot00000000000000function varargout = savejd(varargin) % % savejd(rootname, obj, outputfile) % or % buffer=savejd(obj) % buffer=savejd(rootname, obj) % savejd(rootname, obj, opt) % savejd(rootname, obj, 'filename', outputfile, 'Param1',value1, 'Param2',value2,...) % % Save a complex MATLAB/Octave data structure to a hierarchical % container data file including JSON, binary JSON % (BJData/UBJSON/MessagePack) and HDF5 % % author: Qianqian Fang (q.fang neu.edu) % % 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 help savejson), % the MATLAB variable name will be used as the root name. % obj: a MATLAB object (array, cell, cell array, struct, struct array, % class instance). % outputfile: the output file name to the hierarchical container file % *.json,.jnii,.jdt,.jmsh,.jnirs,.jbids: JSON/JData based data files, see https://neurojson.org/jdata/draft2 % *.bjd,.bnii,.jdb,.bmsh,.bnirs,.pmat: binary JData (BJData) files, see https://neurojson.org/bjdata/draft2 % *.ubj: UBJSON-encoded files, see http://ubjson.org % *.msgpack: MessagePack-encoded files, see http://msgpack.org % *.h5,.hdf5,.snirf: HDF5 files, see https://www.hdfgroup.org/ % opt: (optional) for JSON/JData files, these are optional 'param',value pairs % supported by loadjson.m; for BJData/UBJSON/MessagePack files, these are % options supported by loadbj.m; for HDF5 files, these are options % supported by loadh5.m (part of EasyH5 toolbox, http://github.com/NeuroJSON/easyh5/) % % output: % data: a structure (array) or cell (array) storing the hierarchical data % in the container data file % mmap: optional output storing the JSON/binary JSON memory-map table for fast % disk access. see help info for loadjson or loadbj for more details. % % examples: % obj=struct('string','value','array',[1 2 3]); % savejd('obj', obj, 'datafile.json') % newobj=loadjd('datafile.json'); % % 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) error('you must provide file name'); end opt = struct; if (nargin > 2) if (nargin == 3 && ischar(varargin{3})) filename = varargin{3}; else opt = varargin2struct(varargin{3:end}); filename = jsonopt('filename', '.json', opt); end end if (~exist('filename', 'var')) filename = '.json'; end if (regexpi(filename, '\.json$|\.jnii$|\.jdt$|\.jdat$|\.jmsh$|\.jnirs$|\.jbids$')) [varargout{1:nargout}] = savejson(varargin{:}); elseif (regexpi(filename, '\.bjd$|\.bnii$|\.jdb$|\.jbat$|\.bmsh$|\.bnirs$|\.pmat')) [varargout{1:nargout}] = savebj(varargin{:}); elseif (regexpi(filename, '\.ubj$')) [varargout{1:nargout}] = saveubjson(varargin{:}); elseif (regexpi(filename, '\.msgpack$')) [varargout{1:nargout}] = savemsgpack(varargin{:}); elseif (regexpi(filename, '\.h5$|\.hdf5$|\.snirf$')) if (~exist('saveh5', 'file')) error('you must first install EasyH5 from http://github.com/NeuroJSON/easyh5/'); end if (~isfield(opt, 'rootname')) if (nargin >= 3 && ischar(varargin{1})) opt.rootname = varargin{1}; else opt.rootname = inputname(2); end end [varargout{1:nargout}] = saveh5(varargin{2}, filename, opt); else error('file suffix must be one of .json,.jnii,.jdt,.jmsh,.jnirs,.jbids,.bjd,.bnii,.jdb,.bmsh,.bnirs,.ubj,.msgpack,.h5,.hdf5,.snirf,.pmat'); end jsonlab-2.9.8/savejson.m000066400000000000000000000753301460134415400152020ustar00rootroot00000000000000function output = 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 ['%.16g'|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. % EmptyArrayAsNull [0|1]: if set to 1, convert an empty array to % JSON null object; empty cells remain mapped to [] % 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]: convert the 0x[hex code] output by loadjson % back to the string form % SaveBinary [1|0]: 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 integer 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 [inf|int]: only to compress a string if the total % element count is larger than this number. % FormatVersion [3|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 % BuiltinJSON [0|1]: if set to 1, this function attempts to call % jsonencode, if presents (MATLAB R2016b or Octave % 6) first. If jsonencode does not exist or failed, % this function falls back to the jsonlab savejson % % opt can be replaced by a list of ('param',value) pairs. The param % string is equivalent 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}) || isa(varargin{1}, 'string'))) 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', 3, opt); opt.compressarraysize = jsonopt('CompressArraySize', 100, opt); opt.compressstringsize = jsonopt('CompressStringSize', inf, opt); opt.intformat = jsonopt('IntFormat', '%.0f', opt); opt.floatformat = jsonopt('FloatFormat', '%.16g', 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.emptyarrayasnull = jsonopt('EmptyArrayAsNull', 0, opt); opt.inf = jsonopt('Inf', '"$1_Inf_"', opt); opt.nan = jsonopt('NaN', '"_NaN_"', opt); opt.num2cell_ = 0; opt.nosubstruct_ = 0; if (jsonopt('BuiltinJSON', 0, opt) && exist('jsonencode', 'builtin')) try obj = jdataencode(obj, 'Base64', 1, 'AnnotateArray', 1, 'UseArrayZipSize', 1, opt); if (isempty(rootname)) json = jsonencode(obj); else json = jsonencode(struct(rootname, obj)); end if (isempty(regexp(json, '^[{\[]', 'once'))) json = ['[', json, ']']; end if (nargout > 0) output = json; end return catch warning('built-in jsonencode function failed to encode the data, fallback to savejson'); end end if (jsonopt('PreEncode', 1, opt)) obj = jdataencode(obj, 'Base64', 1, 'UseArrayZipSize', 0, opt); end dozip = opt.compression; if (~isempty(dozip)) if (~ismember(dozip, {'zlib', 'gzip', 'lzma', 'lzip', 'lz4', 'lz4hc'}) && isempty(regexp(dozip, '^blosc2', 'once'))) 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')) || (isa(obj, 'dictionary') && ~strcmp(obj.types, 'string'))) 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)) if (jsonopt('UTF8', 1, opt) && exist('unicode2native', 'builtin')) json = unicode2native(json); end encoding = jsonopt('Encoding', '', opt); endian = jsonopt('Endian', 'n', opt); mode = 'w'; if (jsonopt('Append', 0, opt)) mode = 'a'; end if (jsonopt('SaveBinary', 1, opt) == 1) if (isempty(encoding)) fid = fopen(filename, [mode 'b'], endian); else fid = fopen(filename, [mode 'b'], endian, encoding); 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 if (nargout > 0 || isempty(filename)) output = json; 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 (~isempty(varargin{1}.compression) && 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') || isa(item, 'dictionary')) 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 isnum2cell = varargin{1}.num2cell_; if (isnum2cell) item = squeeze(item); if (~isvector(item)) item = permute(item, ndims(item):-1:1); end end dim = size(item); len = numel(item); ws = varargin{1}.whitespaces_; padding0 = repmat(ws.tab, 1, level); nl = ws.newline; bracketlevel = ~varargin{1}.singletcell; if (len > bracketlevel) if (~isempty(name)) txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":[', nl}; name = ''; else txt = {padding0, '[', nl}; end elseif (len == 0) if (~isempty(name)) txt = {padding0, '"' decodevarname(name, varargin{1}.unpackhex) '":[]'}; name = ''; else txt = {padding0, '[]'}; end txt = sprintf('%s', txt{:}); return end if (size(item, 1) > 1) item = num2cell(item, 2:ndims(item))'; end idx = num2cell(1:length(item)); sep = {[',' nl], ''}; txt = [txt{:}, cellfun(@(x, id) [obj2json(name, x, level + (dim(1) > 1) + (len > bracketlevel), varargin{:}), sep{(id == length(item)) + 1}], item, idx, 'UniformOutput', false)]; if (len > bracketlevel) 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 (e < length(names)) txt{end + 1} = ','; end txt{end + 1} = nl; end end txt(end + 1:end + 2) = {padding1, '}'}; if (i < dim(1)) txt(end + 1:end + 2) = {',' nl}; end end if (dim(1) > 1) txt(end + 1:end + 3) = {nl, padding2, ']'}; end if (j < dim(2)) txt(end + 1:end + 2) = {',' nl}; end end if (forcearray) txt(end + 1:end + 3) = {nl, padding0, ']'}; end txt = sprintf('%s', txt{:}); %% ------------------------------------------------------------------------- function txt = map2json(name, item, level, varargin) txt = {}; itemtype = isa(item, 'containers.Map'); dim = size(item); if (isa(item, 'dictionary')) itemtype = 2; dim = item.numEntries; end if (itemtype == 0) error('input is not a containers.Map or dictionary class'); end names = keys(item); val = values(item); if (~iscell(names)) names = num2cell(names, ndims(names)); end if (~iscell(val)) val = num2cell(val, ndims(val)); end if ((itemtype == 1 && ~strcmp(item.KeyType, 'char')) || (itemtype == 2 && ~strcmp(item.types, 'string'))) mm = cell(1, length(names)); for i = 1:length(names) mm{i} = {names{i}, val{i}}; end if (isempty(name)) txt = obj2json('_MapData_', mm, level + 1, varargin{:}); else temp = struct(name, struct()); if (varargin{1}.isoctave) temp.(name).('_MapData_') = mm; else temp.(name).('x0x5F_MapData_') = mm; end txt = obj2json(name, temp.(name), level, varargin{:}); end return end 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)) txt = {padding0, '"', decodevarname(name, varargin{1}.unpackhex), '":{', nl}; else txt = {padding0, '{', nl}; end for i = 1:dim(1) if (isempty(names{i})) txt{end + 1} = obj2json('x0x0_', val{i}, level + 1, varargin{:}); else txt{end + 1} = obj2json(names{i}, val{i}, level + 1, varargin{:}); end if (i < length(names)) txt{end + 1} = ','; end if (i < dim(1)) txt{end + 1} = nl; end end txt(end + 1:end + 3) = {nl, padding0, '}'}; txt = sprintf('%s', txt{:}); %% ------------------------------------------------------------------------- function txt = str2json(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); ws = varargin{1}.whitespaces_; padding1 = repmat(ws.tab, 1, level); padding0 = repmat(ws.tab, 1, level + 1); nl = ws.newline; sep = ws.sep; if (~isempty(name)) if (len > 1) 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 opt = varargin{1}; ws = opt.whitespaces_; padding1 = repmat(ws.tab, 1, level); padding0 = repmat(ws.tab, 1, level + 1); nl = ws.newline; sep = ws.sep; dozip = opt.compression; zipsize = opt.compressarraysize; format = opt.formatversion; isnest = opt.nestarray; if (~opt.nosubstruct_ && (((isnest == 0) && length(size(item)) > 2) || issparse(item) || ~isreal(item) || ... (isempty(item) && any(size(item))) || opt.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, opt.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, opt.unpackhex), numtxt); else txt = sprintf('%s"%s":%s', padding1, decodevarname(name, opt.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]); encodeparam = {}; if (~isempty(regexp(dozip, '^blosc2', 'once'))) compfun = @blosc2encode; encodeparam = {dozip, 'nthread', jsonopt('nthread', 1, opt), 'shuffle', jsonopt('shuffle', 1, opt), 'typesize', jsonopt('typesize', length(typecast(fulldata(1), 'uint8')), opt)}; else compfun = str2func([dozip 'encode']); end txt = sprintf(dataformat, txt, padding0, '"_ArrayZipData_":"', char(base64encode(compfun(typecast(fulldata(:), 'uint8'), encodeparam{:}))), ['"' 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 % array 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; varargin{1}.singletcell = 0; txt = cell2json('', num2cell(mat, 1), level - 1, varargin{:}); return elseif (isvector(mat) && isnum2cell == 1) mat = mat(:).'; 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)) if (varargin{1}.emptyarrayasnull) txt = 'null'; else txt = '[]'; end 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.9.8/savemsgpack.m000066400000000000000000000021031460134415400156420ustar00rootroot00000000000000function 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, 'endian', 'B'); elseif (length(varargin) == 1 && ischar(varargin{1})) msgpk = savebj(rootname, obj, 'FileName', varargin{1}, 'MessagePack', 1, 'endian', 'B'); else msgpk = savebj(rootname, obj, varargin{:}, 'MessagePack', 1, 'endian', 'B'); end jsonlab-2.9.8/saveubjson.m000066400000000000000000000062621460134415400155270ustar00rootroot00000000000000function 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, graphs ...) % 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/NeuroJSON/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,'endian','B')" % 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 and use Big-Endian for all numerical values as in UBJSON % Draft-12. % % 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 equivalent to a field in opt and is case sensitive. % % Please type "help savebj" for details for all supported options. % % output: % ubj: 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, 'endian', 'B'); elseif (length(varargin) == 1 && ischar(varargin{1})) ubj = savebj(rootname, obj, 'FileName', varargin{1}, 'ubjson', 1, 'endian', 'B'); else ubj = savebj(rootname, obj, varargin{:}, 'ubjson', 1, 'endian', 'B'); end jsonlab-2.9.8/test/000077500000000000000000000000001460134415400141435ustar00rootroot00000000000000jsonlab-2.9.8/test/run_jsonlab_test.m000066400000000000000000001044301460134415400176760ustar00rootroot00000000000000function run_jsonlab_test(tests) % % run_jsonlab_test % or % run_jsonlab_test(tests) % run_jsonlab_test({'js','jso','bj','bjo','jmap','bmap','jpath','bugs'}) % % 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 % 'jmap': test jsonmmap features in loadjson % 'bmap': test jsonmmap features in loadbj % 'jpath': test jsonpath % 'bugs': test specific bug fixes % % 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', 'jmap', 'bmap', 'jpath', 'bugs'}; 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 struct', @savejson, struct, '{}', 'compact', 1); test_jsonlab('empty struct with fields', @savejson, repmat(struct('a', 1), 0, 1), '[]'); 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('string')) 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('empty name', @savejson, loadjson('{"":""}'), '{"":""}', 'compact', 1); if (exist('containers.Map')) test_jsonlab('empty name with map', @savejson, loadjson('{"":""}', 'usemap', 1), '{"":""}', 'compact', 1); test_jsonlab('indentation', @savejson, savejson('s', containers.Map({'a', 'b'}, {[], struct('c', 1.1, 'd', struct('e', {1, 2}))})), ... '"{\n\t\"s\":{\n\t\t\"a\":[],\n\t\t\"b\":{\n\t\t\t\"c\":1.1,\n\t\t\t\"d\":[\n\t\t\t\t{\n\t\t\t\t\t\"e\":1\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"e\":2\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t}\n}\n"'); test_jsonlab('key longer than 63', @savejson, loadjson('{"...........":""}', 'usemap', 0), '{"...........":""}', '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('mixed array from string', @savejson, loadjson('["a",{"c":1}, [2,3]]'), '["a",{"c":1},[2,3]]', '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('non-uniform 2d array', @savejson, {[1, 2], [3, 4, 5], [6, 7]}, '[[1,2],[3,4,5],[6,7]]', 'compact', 1); test_jsonlab('non-uniform array with length multiple of first element', @savejson, {[1, 2], [3, 4, 5, 6], [7, 8]}, '[[1,2],[3,4,5,6],[7,8]]', 'compact', 1); test_jsonlab('1d array with flexible white space', @savejson, loadjson(sprintf(' [ +1, \n -2e3 \n , 3.0E+00 ,\r+4e-0] ')), '[1,-2000,3,4]', 'compact', 1); test_jsonlab('2d array with flexible white space', @savejson, loadjson(sprintf(' [\r [\n 1 , \r\n 2\n, 3] ,\n[ 4, 5 , \t 6\t]\n] ')), '[[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 with char keys', @savejson, containers.Map({'Andy', '^_^'}, {true, '-_-'}), ... '{"Andy":true,"^_^":"-_-"}', 'compact', 1, 'usemap', 1); test_jsonlab('containers.Map with number keys', @savejson, containers.Map({1.1, 1.2}, {true, '-_-'}), ... '{"_MapData_":[[1.1,true],[1.2,"-_-"]]}', 'compact', 1, 'usemap', 1); end if (exist('dictionary')) test_jsonlab('dictionary with string keys', @savejson, dictionary([string('Andy'), string('^_^')], {true, '-_-'}), ... '{"Andy":true,"^_^":"-_-"}', 'compact', 1, 'usemap', 1); test_jsonlab('dictionary with cell keys', @savejson, dictionary({'Andy', '^_^'}, {true, '-_-'}), ... '{"_MapData_":[["Andy",true],["^_^","-_-"]]}', 'compact', 1, 'usemap', 1); test_jsonlab('dictionary with number keys', @savejson, dictionary({1.1, 1.2}, {true, '-_-'}), ... '{"_MapData_":[[1.1,true],[1.2,"-_-"]]}', '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"}'), ... '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"}'), ... '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="}'), ... '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); test_jsonlab('make null object roundtrip', @savejson, loadjson('{"a":null}'), '{"a":null}', 'EmptyArrayAsNull', 1, 'compact', 1); test_jsonlab('test no datalink', @savejson, loadjson(savejson('a', struct(encodevarname('_DataLink_'), ... '../examples/example2.json:$.glossary.title'))), '{"a":[{"_DataLink_":"../examples/example2.json:$.glossary.title"}]}', 'compact', 1, 'SingletArray', 1); test_jsonlab('test maxlinklevel', @savejson, loadjson(savejson('a', struct(encodevarname('_DataLink_'), ... '../examples/example2.json:$.glossary.title')), 'maxlinklevel', 1), '{"a":"example glossary"}', '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('string') && isa(string('jdata'), 'string')) 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('empty name', @savebj, loadbj(['{U' 0 'U' 2 '}']), '{U<0>U<2>}', 'debug', 1); if (exist('containers.Map')) test_jsonlab('empty name with map', @savebj, loadbj(['{U' 0 'U' 2 '}'], 'usemap', 1), '{U<0>U<2>}', 'debug', 1); test_jsonlab('key longer than 63', @savebj, loadbj(['{U' 11 '...........U' 2 '}'], 'usemap', 0), '{U<11>...........U<2>}', '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><2><3><4><5><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><4><5><3><1><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><4><5><0><1><0><3><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>iD<1.1>U<1>dSU<3>str}{U<1>iD<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 with char keys', @savebj, containers.Map({'Andy', '^_^'}, {true, '-_-'}), ... '{U<4>AndyTU<3>^_^SU<3>-_-}', 'debug', 1, 'usemap', 1); end if (exist('dictionary')) test_jsonlab('dictionary with string keys', @savebj, dictionary([string('Andy'), string('^_^')], {true, '-_-'}), ... '{U<4>AndyTU<3>^_^SU<3>-_-}', 'debug', 1, 'usemap', 1); test_jsonlab('dictionary with cell keys', @savebj, dictionary({'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); test_jsonlab('test little endian uint32', @savebj, typecast(uint8('abcd'), 'uint32'), 'mabcd', 'endian', 'L'); test_jsonlab('test big endian uint32', @savebj, typecast(uint8('abcd'), 'uint32'), 'mdcba', 'endian', 'B'); test_jsonlab('test little endian double', @savebj, typecast(uint8('01234567'), 'double'), 'D01234567', 'endian', 'L'); test_jsonlab('test big endian double', @savebj, typecast(uint8('01234567'), 'double'), 'D76543210', 'endian', 'B'); test_jsonlab('test default int endian for savebj', @savebj, typecast(uint8('jd'), 'uint16'), 'ujd'); test_jsonlab('test default int endian for saveubjson', @saveubjson, typecast(uint8('jd'), 'uint16'), 'Idj'); test_jsonlab('test default float endian for savebj', @savebj, typecast(uint8('1e05'), 'single'), 'd1e05'); test_jsonlab('test default float endian for saveubjson', @saveubjson, typecast(uint8('12345678'), 'double'), 'D87654321'); end %% if (ismember('jmap', tests)) fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); fprintf('Test JSON mmap\n'); fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); test_jsonlab('mmap of a 1D numerical array', @savejson, loadjson('[1,2,3]', 'mmaponly', 1), '[["$",[1,7]]]', 'compact', 1); test_jsonlab('mmap of a 1D mixed array', @savejson, loadjson('[1,"2",3]', 'mmaponly', 1), '[["$",[1,9]]]', 'compact', 1); test_jsonlab('mmap of a 2D array', @savejson, loadjson('[[1,2,3],[4,5,6]]', 'mmaponly', 1), '[["$",[1,17]]]', 'compact', 1); test_jsonlab('mmap of concatenated json', @savejson, loadjson('[1,2,3][4,5,6]', 'mmaponly', 1), '[["$",[1,7]],["$1",[8,7]]]', 'compact', 1); test_jsonlab('mmap of concatenated json objects', @savejson, loadjson('[1,2,3]{"a":[4,5]}', 'mmaponly', 1), '[["$",[1,7]],["$1",[8,11]],["$1.a",[13,5]]]', 'compact', 1); test_jsonlab('mmap of an array with an object', @savejson, loadjson('[1,2,{"a":3}]', 'mmaponly', 1), ... '[["$",[1,13]],["$[0]",[2,1]],["$[1]",[4,1]],["$[2]",[6,7]],["$[2].a",[11,1]]]', 'compact', 1); test_jsonlab('mmap of an object', @savejson, loadjson('{"a":1,"b":[2,3]}', 'mmaponly', 1), ... '[["$",[1,17]],["$.a",[6,1]],["$.b",[12,5]]]', 'compact', 1); test_jsonlab('mmap of object with white-space', @savejson, loadjson('{"a":1 , "b" : [2,3]}', 'mmaponly', 1), ... '[["$",[1,23]],["$.a",[6,1]],["$.b",[18,5,2]]]', 'compact', 1); test_jsonlab('mmapinclude option', @savejson, loadjson('[[1,2,3],{"a":[4,5]}]', 'mmaponly', 1, 'mmapinclude', '.a'), ... '[["$[1].a",[15,5]]]', 'compact', 1); test_jsonlab('mmapexclude option', @savejson, loadjson('[[1,2,3],{"a":[4,5]}]', 'mmaponly', 1, 'mmapexclude', {'[0]', '[1]', '[2]'}), ... '[["$",[1,21]]]', 'compact', 1); test_jsonlab('json with indentation', @savejson, loadjson(savejson({[1, 2, 3], struct('a', [4, 5])}), 'mmaponly', 1, 'mmapinclude', '.a'), ... '[["$[1].a",[22,7]]]', 'compact', 1); end %% if (ismember('bmap', tests)) fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); fprintf('Test Binary JSON mmap\n'); fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); test_jsonlab('mmap of a 1D numerical array', @savejson, loadbj(savebj([1, 2, 3]), 'mmaponly', 1), '[["$",[1,9]]]', 'compact', 1); test_jsonlab('mmap of a 1D mixed array', @savejson, loadbj(savebj({1, '2', 3}), 'mmaponly', 1), '[["$",[1,8]],["$[0]",[2,2]],["$[1]",[4,2]],["$[2]",[6,2]]]', 'compact', 1); test_jsonlab('mmap of a 2D array', @savejson, loadbj(savebj([[1, 2, 3], [4, 5, 6]]), 'mmaponly', 1), '[["$",[1,12]]]', 'compact', 1); test_jsonlab('mmap of an array with an object', @savejson, loadbj(savebj({1, 2, struct('a', 3)}), 'mmaponly', 1), ... '[["$",[1,13]],["$[0]",[2,2]],["$[1]",[4,2]],["$[2]",[6,7]],["$[2].a",[10,2]]]', 'compact', 1); test_jsonlab('mmap of an object', @savejson, loadbj(savebj(struct('a', 1, 'b', [2, 3])), 'mmaponly', 1), ... '[["$",[1,18]],["$.a",[5,2]],["$.b",[10,8]]]', 'compact', 1); test_jsonlab('mmapinclude option', @savejson, loadbj(savebj({[1, 2, 3], struct('a', [4, 5])}), 'mmaponly', 1, 'mmapinclude', '.a'), ... '[["$[1].a",[15,8]]]', 'compact', 1); test_jsonlab('mmapexclude option', @savejson, loadbj(savebj({[1, 2, 3], struct('a', [4, 5])}), 'mmaponly', 1, 'mmapexclude', {'[0]', '[1]', '[2]'}), ... '[["$",[1,24]]]', 'compact', 1); test_jsonlab('test multiple root objects with N padding', @savejson, loadbj([savebj({[1, 2, 3], struct('a', [4, 5])}) 'NNN' savebj(struct('b', [4, 5]))], 'mmaponly', 1, 'mmapinclude', '.b'), ... '[["$1.b",[32,8]]]', 'compact', 1); end %% if (ismember('jpath', tests)) fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); fprintf('Test JSONPath\n'); fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); testdata = struct('book', struct('title', {'Minch', 'Qui-Gon', 'Ben'}, 'author', {'Yoda', 'Jinn', 'Kenobi'}), 'game', struct('title', 'Mario', 'new', struct('title', 'Minecraft'))); test_jsonlab('jsonpath of .key', @savejson, jsonpath(testdata, '$.game.title'), '"Mario"', 'compact', 1); test_jsonlab('jsonpath of ..key', @savejson, jsonpath(testdata, '$.book..title'), '["Minch","Qui-Gon","Ben"]', 'compact', 1); test_jsonlab('jsonpath of ..key cross objects', @savejson, jsonpath(testdata, '$..title'), '["Minch","Qui-Gon","Ben","Mario","Minecraft"]', 'compact', 1); test_jsonlab('jsonpath of [index]', @savejson, jsonpath(testdata, '$..title[1]'), '["Qui-Gon"]', 'compact', 1); test_jsonlab('jsonpath of [-index]', @savejson, jsonpath(testdata, '$..title[-1]'), '["Minecraft"]', 'compact', 1); test_jsonlab('jsonpath of [start:end]', @savejson, jsonpath(testdata, '$..title[0:2]'), '["Minch","Qui-Gon","Ben"]', 'compact', 1); test_jsonlab('jsonpath of [:end]', @savejson, jsonpath(testdata, '$..title[:2]'), '["Minch","Qui-Gon","Ben"]', 'compact', 1); test_jsonlab('jsonpath of [start:]', @savejson, jsonpath(testdata, '$..title[1:]'), '["Qui-Gon","Ben","Mario","Minecraft"]', 'compact', 1); test_jsonlab('jsonpath of [-start:-end]', @savejson, jsonpath(testdata, '$..title[-2:-1]'), '["Mario","Minecraft"]', 'compact', 1); test_jsonlab('jsonpath of [-start:]', @savejson, jsonpath(testdata, '$..title[:-3]'), '["Minch","Qui-Gon","Ben"]', 'compact', 1); test_jsonlab('jsonpath of [:-end]', @savejson, jsonpath(testdata, '$..title[-1:]'), '["Minecraft"]', 'compact', 1); test_jsonlab('jsonpath of object with [index]', @savejson, jsonpath(testdata, '$.book[1]'), '{"title":"Qui-Gon","author":"Jinn"}', 'compact', 1); test_jsonlab('jsonpath of element after [index]', @savejson, jsonpath(testdata, '$.book[1:2].author'), '["Jinn","Kenobi"]', 'compact', 1); test_jsonlab('jsonpath of [*] and deep scan', @savejson, jsonpath(testdata, '$.book[*]..author'), '["Yoda","Jinn","Kenobi"]', 'compact', 1); test_jsonlab('jsonpath of [*] after deep scan', @savejson, jsonpath(testdata, '$.book[*]..author[*]'), '["Yoda","Jinn","Kenobi"]', 'compact', 1); test_jsonlab('jsonpath use [] instead of .', @savejson, jsonpath(testdata, '$[book][2][author]'), '"Kenobi"', 'compact', 1); test_jsonlab('jsonpath use [] with [start:end]', @savejson, jsonpath(testdata, '$[book][1:2][author]'), '["Jinn","Kenobi"]', 'compact', 1); test_jsonlab('jsonpath use . after [start:end]', @savejson, jsonpath(testdata, '$[book][0:1].author'), '["Yoda","Jinn"]', 'compact', 1); test_jsonlab('jsonpath use [''*''] and ["*"]', @savejson, jsonpath(testdata, '$["book"][:-2][''author'']'), '["Yoda","Jinn"]', 'compact', 1); test_jsonlab('jsonpath use combinations', @savejson, jsonpath(testdata, '$..["book"][:-2].author[*][0]'), '["Yoda"]', 'compact', 1); if (exist('containers.Map')) testdata = loadjson(savejson('', testdata), 'usemap', 1); test_jsonlab('jsonpath use combinations', @savejson, jsonpath(testdata, '$..["book"].author[*][0]'), '["Yoda"]', 'compact', 1); end if (exist('istable')) testdata = struct('book', table({'Minch', 'Qui-Gon', 'Ben'}, {'Yoda', 'Jinn', 'Kenobi'}, 'variablenames', {'title', 'author'}), 'game', struct('title', 'Mario')); test_jsonlab('jsonpath use combinations', @savejson, jsonpath(testdata, '$..["book"].author[*][0]'), '["Yoda"]', 'compact', 1); end testdata = struct('book', struct(encodevarname('_title'), {'Minch', 'Qui-Gon', 'Ben'}, encodevarname(' author.last.name '), {'Yoda', 'Jinn', 'Kenobi'}), encodevarname('game.arcade'), struct('title', 'Mario')); test_jsonlab('jsonpath encoded field name in []', @savejson, jsonpath(testdata, '$..["book"][_title][*][0]'), '["Minch"]', 'compact', 1); test_jsonlab('jsonpath encoded field name after .', @savejson, jsonpath(testdata, '$..["book"]._title[*][0]'), '["Minch"]', 'compact', 1); test_jsonlab('jsonpath encoded field name after ..', @savejson, jsonpath(testdata, '$.._title'), '["Minch","Qui-Gon","Ben"]', 'compact', 1); test_jsonlab('jsonpath multiple encoded field name between quotes', @savejson, jsonpath(testdata, '$..["book"]['' author.last.name ''][*][1]'), '["Jinn"]', 'compact', 1); test_jsonlab('jsonpath multiple encoded field name between []', @savejson, jsonpath(testdata, '$..["book"][ author.last.name ][*][1]'), '["Jinn"]', 'compact', 1); test_jsonlab('jsonpath escape . using \.', @savejson, jsonpath(testdata, '$.game\.arcade'), '{"title":"Mario"}', 'compact', 1); test_jsonlab('jsonpath escape . using []', @savejson, jsonpath(testdata, '$.[game.arcade]'), '{"title":"Mario"}', 'compact', 1); test_jsonlab('jsonpath scan struct array', @savejson, jsonpath(testdata, '$.book[*]..author[*]'), '[]', 'compact', 1); clear testdata; end %% if (ismember('bugs', tests)) fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); fprintf('Test bug fixes\n'); fprintf(sprintf('%s\n', char(ones(1, 79) * 61))); test_jsonlab('simplify cell arrays mixing numbers and chars', @savejson, loadjson('[1,0,"-","L",900]'), '[1,0,"-","L",900]', 'compact', 1); test_jsonlab('simplify cell arrays with string elements', @savejson, loadjson('["j","s","o","n"]'), '["j","s","o","n"]', 'compact', 1); end jsonlab-2.9.8/test/test_jsonlab.m000066400000000000000000000022311460134415400170060ustar00rootroot00000000000000function 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 end jsonlab-2.9.8/transposemat.m000066400000000000000000000025441460134415400160670ustar00rootroot00000000000000function data = transposemat(input) % % data=transposemat(input) % % Iterate over struct/cell and transpose 2D or higher-dimensional numerical % array to match Octave loaded HDF5 array elements with loadh5 default setting % % author: Qianqian Fang (q.fang neu.edu) % % input: % name: a matlab variable, can be a cell, struct, containers.Map, numeric array or strings % % output: % newname: the restored original string % % example: % a=struct('a', ones(2,3), 'b', 'a string', 'c', uint8(zeros(2,3,4))); % b=transposemat(a) % % this file is part of EasyH5 Toolbox: https://github.com/NeuroJSON/easyh5 % % License: GPLv3 or 3-clause BSD license, see https://github.com/NeuroJSON/easyh5 for details % if (isstruct(input)) data = structfun(@transposemat, input, 'UniformOutput', false); elseif (iscell(input)) data = cellfun(@transposemat, input, 'UniformOutput', 'false'); elseif (isa(input, 'containers.Map')) allkeys = keys(input); for i = 1:length(allkeys) input(allkeys(i)) = transposemat(allkeys(i)); end elseif (isnumeric(input) && (ndims(input) > 2 || all(size(input) > 1))) data = permute(input, ndims(input):-1:1); elseif (ischar(input) && ndims(input) == 2 && size(input, 1) == 1 && size(input, 2) > 1 && input(end) == ' ') data = input(1:end - 1); else data = input; end jsonlab-2.9.8/varargin2struct.m000066400000000000000000000021621460134415400165030ustar00rootroot00000000000000function 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 < len) opt.(lower(varargin{i})) = varargin{i + 1}; i = i + 1; else error('input must be in the form of ...,''name'',value,... pairs or structs'); end i = i + 1; end jsonlab-2.9.8/zlibdecode.m000066400000000000000000000044731460134415400154560ustar00rootroot00000000000000function 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/NeuroJSON/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 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 nozmat = getvarfrom({'caller', 'base'}, 'NO_ZMAT'); if ((exist('zmat', 'file') == 2 || exist('zmat', 'file') == 3) && (isempty(nozmat) || nozmat == 0)) 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) [varargout{1:nargout}] = octavezmat(varargin{1}, 0, 'zlib'); return 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.9.8/zlibencode.m000066400000000000000000000036571460134415400154730ustar00rootroot00000000000000function 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/NeuroJSON/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 nozmat = getvarfrom({'caller', 'base'}, 'NO_ZMAT'); if ((exist('zmat', 'file') == 2 || exist('zmat', 'file') == 3) && (isempty(nozmat) || nozmat == 0)) [varargout{1:nargout}] = zmat(varargin{1}, 1, 'zlib'); return elseif (isoctavemesh) [varargout{1:nargout}] = octavezmat(varargin{1}, 1, 'zlib'); return end error(javachk('jvm')); input = varargin{1}(:)'; if (ischar(input)) input = uint8(input); elseif (isa(input, 'string')) input = uint8(char(input)); else input = typecast(input, 'uint8'); end 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', 'zlib', 'status', 0); end jsonlab-2.9.8/zstddecode.m000066400000000000000000000027151460134415400154770ustar00rootroot00000000000000function varargout = zstddecode(varargin) % % output = zstddecode(input) % or % output = zstddecode(input,info) % % Decompressing an Zstd-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/NeuroJSON/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store Zstd-compressed data % info (optional): a struct produced by the zmat/zstdencode 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]=zstdencode(eye(10)); % orig=zstddecode(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, 'zstd', varargin{2:end}); end else error('you must install ZMat toolbox to use this feature: http://github.com/NeuroJSON/zmat'); end jsonlab-2.9.8/zstdencode.m000066400000000000000000000027151460134415400155110ustar00rootroot00000000000000function varargout = zstddecode(varargin) % % output = zstddecode(input) % or % output = zstddecode(input,info) % % Decompressing an Zstd-compressed byte-stream to recover the original data % This function depends on the ZMat toolbox (http://github.com/NeuroJSON/zmat) % % authors:Qianqian Fang (q.fang neu.edu) % % input: % input: a string, int8/uint8 vector or numerical array to store Zstd-compressed data % info (optional): a struct produced by the zmat/zstdencode 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]=zstdencode(eye(10)); % orig=zstddecode(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, 'zstd', varargin{2:end}); end else error('you must install ZMat toolbox to use this feature: http://github.com/NeuroJSON/zmat'); end