- Copyright (C) 2011-2020 Qianqian Fang <q.fang at neu.edu>
- License: BSD or GNU General Public License version 3 (GPL v3), see License*.txt
- Version: 2.0 (Magnus Prime)
- JData Specification Version: Draft 3 (http://github.com/fangq/jdata)
- URL: http://openjdata.org/jsonlab
JSONLab v2.0 - code named "Magnus Prime" - is a stable release of JSONLab and a new milestone towards a stable, complete reference implementation for the JData Specification (http://openjdata.org) for portable scientific data storage.
There have been many major updates added to this release since the previous
release v1.9.8 in Oct. 2019. A list of the major changes are summarized below
(with key features marked by *), including the support to _ArrayShape_
to
efficiently encode special matrices and the addition of jsave/jload
to save
and restore variables in MATLAB/Octave like save/load commands (experimental):
- 2020-06-02*[15ca7ae] add keeptype option to jsave and saveubjson
- 2020-06-02 [7f2cbc4] make jsave and jload work on octave
- 2020-06-01*[8829d6b] apply data compression to strings, new datatype char
- 2020-06-01 [270cbf6] fix loadmsgpack ND array issue
- 2020-06-01*[919f502] add jsave and jload for portable data sharing,update doc
- 2020-05-31 [df3a4fa] debug arrayshape related changes and test all demo scripts
- 2020-05-31*[fc0b285] adding support to _ArrayShape_ to record special matrices
- 2020-05-15*[d88d454] jsonlab is compatible with matlab R2008
- 2020-05-13 [86efe89] flag to prevent embedding ND array size specifier
- 2020-05-07 [a189a50] use more robust integer type testing
- 2020-05-06*[82f5249] saveubjson now implments BJData spec Draft1,https://github.com/fangq/bjdata
- 2020-05-03 [34bca22] add prj file to compile a matlab package, close #60
- 2020-05-03 [82dfdcc] handle empty array in loadmsgpack, fix #63, patch by stfnp
- 2020-03-08 [7499bd8] Merge pull request #61 from j2L4e/patch-1
- 2020-02-09*[6984111] add UseMap option to avoid key name conversion
- 2019-11-16 [e46221a] if _ArraySize_ has a single length, treat as a row vector
- 2019-11-01 [f2bfb65] fix a uint8 upper bound bug
- 2019-10-24 [cc4491d] avoid escaping base64 str, avoid double processing preencoded arrayzipdata
- 2019-10-24 [4dc76ef] make example script compatible with matlab R2010
- 2019-10-24 [ad8be26] disable underscore escaping in octave,update all tests and outputs
- 2019-10-24 [d4275c6] reduce jsonopt calls to speed up encoding and decoding
- 2019-10-23 [82c9e91] fix invalid jdatadecode example
- 2019-10-23 [398539d] reoptimize for speed
- 2019-10-22*[650b5ec] enable jdataencode in savejson and saveubjson
Please note that JSONLab v2.0 is now compliant with JData Spec Draft 3, in comparison v1.9.8 is compatible with Draft 2; v1.9 and previous releases are compatible with Draft 1. JSONLab v2.0 can read all data files generated by v1.9.8, but v1.9.8 can not read the new UBJSON markers introduced in v2.0.
The saveubjson/loadubjson now supports Binary JData specification (BJData) Draft 1 (https://github.com/fangq/bjdata). The BJData spec is largely compatible with UBJSON spec Draft 12, with the following differences (we are working with the UBJSON maintainer to merge these two specifications):
- BJData adds 4 new numeric data types:
uint16 [u]
,uint32 [m]
,uint64 [M]
andfloat16 [h]
('''new in JSONLab v2.0''') - BJData supports an optimized ND array container (supported in JSONLab since 2013)
- BJData does not convert
NaN/Inf/-Inf
to null (supported in JSONLab since 2013)
To avoid using the new type markers, one should attach 'UBJSON',1
in the saveubjson
command as
saveubjson('',data,'FileName','myfile.ubj','UBJSON',1);
To read data files generated by JSONLab v1.9 or older versions, you need to attach
option 'FormatVersion', 1.9
in all the loadjson/savejson function calls.
To convert an older file (JSON/UBJSON) to the new format, you should run
data=loadjson('my_old_data_file.json','FormatVersion',1.9)
savejson('',data,'FileName','new_file.json')
You are strongly encouraged to convert all previously generated data files using the new format.
JSONLab is a free and open-source 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, widely used for data-exchange in applications. UBJSON ([http://ubjson.org/ Universal Binary JSON]) is a binary JSON format, specifically designed to complement the limitations of JSON, permitting the storage of binary data with strongly typed data records, resulting in smaller file sizes and fast encoding and decoding. MessagePack is another binary JSON-like data format widely used in data exchange in web/native applications. It is slightly more compact than UBJSON, but is not directly readable compared to UBJSON.
We envision that both JSON and its binary counterparts will play important rules not only for light-weight data storage, but also for storage and interchange of scientific data. It has both the flexibility and generality as in other general-purpose file specifications, such as [http://www.hdfgroup.org/HDF5/whatishdf5.html HDF5] but has significantly reduced complexity and excellent readability.
Towards this goal, we have developed the JData Specification (http://github.com/fangq/jdata) to standardize serializations of complex scientific data structures, such as N-D arrays, sparse/complex-valued arrays, trees, maps, tables and graphs using JSON/binary JSON constructs. The text and binary formatted JData files are syntactically compatible with JSON/UBJSON formats, and can be readily parsed using existing JSON and UBJSON parsers.
The installation of JSONLab is no different from installing any other MATLAB toolbox. You only need to download/unzip the JSONLab package to a folder, and add the folder's path to MATLAB/Octave's path list by using the following command:
addpath('/path/to/jsonlab');
If you want to add this path permanently, you 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
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.
JSONLab has been available as an official Fedora package since 2015. You may install it directly using the below command
sudo dnf install octave-jsonlab
To enable data compression/decompression, you need to install octave-zmat
using
sudo dnf install octave-zmat
JSONLab is also available on Arch Linux. You may install it using the below command
sudo pikaur -S jsonlab
JSONLab provides a pair of functions, loadjson
-- a JSON-to-MATLAB parser,
and savejson
-- a MATLAB-to-JSON encoder, for the text-based JSON, and
two equivallent function pairs -- loadubjson
and saveubjson
for binary
JSON and loadmsgpack
and savemsgpack
for MessagePack. The load*
functions
for the 3 supported data formats share almost the same input parameters;
similarly for the 3 save*
functions (savejson/saveubjson/savemsgpack
)
These encoders and decoders are capable of converting/storing many different
data structures supported by MATLAB, thanks to jdataencode/jdatadecode -
a pair of in-memory data converters that translate complex data structures
to the easy-to-serialized forms according to the JData specifications.
The detailed help information can be found in the Contents.m file.
In addition, we also 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 jsave/jload
use is by default
a binary JData file with self-contained metadata. The file size is comparable
(can be smaller if use lzma
compression) to .mat
files. This feature
is currently experimental.
In the below section, we simply provide a few examples on how to use
each of the core functions for encoding/decoding JSON/UBJSON/MessagePack data
jsonmesh=struct('MeshNode',[0 0 0;1 0 0;0 1 0;1 1 0;0 0 1;1 0 1;0 1 1;1 1 1],...
'MeshElem',[1 2 4 8;1 3 4 8;1 2 6 8;1 5 6 8;1 5 7 8;1 3 7 8],...
'MeshSurf',[1 2 4;1 2 6;1 3 4;1 3 7;1 5 6;1 5 7;...
2 8 4;2 8 6;3 8 4;3 8 7;5 8 6;5 8 7],...
'MeshCreator','FangQ','MeshTitle','T6 Cube',...
'SpecialData',[nan, inf, -inf]);
savejson(jsonmesh)
savejson('jmesh',jsonmesh)
savejson('',jsonmesh,'Compact',1)
savejson('jmesh',jsonmesh,'outputfile.json')
savejson('',jsonmesh,'ArrayIndent',0,'FloatFormat','\t%.5g','FileName','outputfile2.json')
savejson('cpxrand',eye(5)+1i*magic(5))
savejson('ziparray',eye(10),'Compression','zlib','CompressArraySize',1)
savejson('',jsonmesh,'ArrayToStruct',1)
savejson('',eye(10),'UseArrayShape',1)
loadjson('{}')
dat=loadjson('{"obj":{"string":"value","array":[1,2,3]}}')
dat=loadjson(['examples' filesep 'example1.json'])
dat=loadjson(['examples' filesep 'example1.json'],'SimplifyCell',0)
a={single(rand(2)), struct('va',1,'vb','string'), 1+2i};
saveubjson(a)
saveubjson('rootname',a,'testdata.ubj')
saveubjson('zeros',zeros(100),'Compression','gzip')
obj=struct('string','value','array',single([1 2 3]),'empty',[],'magic',uint8(magic(5)));
ubjdata=saveubjson('obj',obj);
dat=loadubjson(ubjdata)
class(dat.obj.array)
isequaln(obj,dat.obj)
dat=loadubjson(saveubjson('',eye(10),'Compression','zlib','CompressArraySize',1))
jd=jdataencode(struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5)))
savejson('',jd)
rawdata=struct('a',rand(5)+1i*rand(5),'b',[],'c',sparse(5,5));
jd=jdataencode(rawdata)
newjd=jdatadecode(jd)
isequaln(newjd,rawdata)
jsave % save workspace to jamdata.jamm
jsave mydata.jamm
jsave('mydata.jamm','vars',{'var1','var2'})
jsave('mydata.jamm','compression','lzma')
jsave('mydata.json','compression','gzip')
jload % load from jamdata.jamm
jload mydata.jamm
jload('mydata.jamm','vars',{'var1','var2'})
jload('mydata.jamm','simplifycell',0)
jload('mydata.json')
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
functions.
Please run these examples and understand how JSONLab works before you use it to process your data.
JSONLab has several known limitations. We are striving to make it more general and robust. Hopefully in a few future releases, the limitations become less.
Here are the known issues:
- 3D or higher dimensional cell/struct-arrays will be converted to 2D arrays
- When processing names containing multi-byte characters, Octave and MATLAB can give different field-names; you can use
feature('DefaultCharacterSet','latin1')
in MATLAB to get consistant resultssavejson
can only export the properties from MATLAB classes, but not the methodssaveubjson
converts a logical array into auint8
([U]
) array- a special N-D array format, as defined in the JData specification, is implemented in
saveubjson
. You may usesaveubjson(...,'NestArray',1)
to create UBJSON Draft-12 compliant filesloadubjson
can not parse all UBJSON Specification (Draft 12) compliant files, however, it can parse all UBJSON files produced bysaveubjson
.
JSONLab is an open-source project. This means you can not only use it and modify it as you wish, but also you can contribute your changes back to JSONLab so that everyone else can enjoy the improvement. For anyone who want to contribute, please download JSONLab source code from its source code repositories by using the following command:
git clone https://github.com/fangq/jsonlab.git jsonlab
or browsing the github site at
https://github.com/fangq/jsonlab
Please report any bugs or issues to the below URL:
https://github.com/fangq/jsonlab/issues
Sometimes, you may find it is necessary to modify JSONLab to achieve your goals, or attempt to modify JSONLab functions to fix a bug that you have encountered. If you are happy with your changes and willing to share those changes to the upstream author, you are recommended to create a pull-request on github.
To create a pull-request, you first need to "fork" jsonlab on Github by clicking on the "fork" button on top-right of jsonlab's github page. Once you forked jsonlab to your own directory, you should then implement the changes in your own fork. After thoroughly testing it and you are confident the modification is complete and effective, you can then click on the "New pull request" button, and on the left, select fangq/jsonlab as the "base". Then type in the description of the changes. You are responsible to format the code updates using the same convention (tab-width: 8, indentation: 4 spaces) as the upstream code.
We appreciate any suggestions and feedbacks from you. Please use the following mailing list to report any questions you may have regarding JSONLab:
https://github.com/fangq/jsonlab/issues
(Subscription to the mailing list is needed in order to post messages).
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
- 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.
- 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.