.. highlightlang:: us
.. index:: obj_save
.. _obj_save:
obj_save
========
.. us.tag obj_save NOTREADYENGLISH obj New410 Changed500 Changed5100 Changed5603
:ref:`obj_save` saves an object as an XML file or as an binary file on the hard
drive or as a string.
.. function:: ret = obj_save(obj, ssFilename)
ret = obj_save(obj, ssFilename, ssFormat)
ssXMLString = obj_save(obj, "")
.. us.return
**Return Value**
If *ssFilename* is a complete file name, *ret* is not equal 0, if the function
was successful and 0 if an error occurred. If the file name has the extension
``.uso`` (for Uni Script Object) the file will be saved in a binary format.
*ssXMLString*:
If *ssFilename* is an empty string (``""``), the return value is a string
with the XML code of the *obj* object or if *ssFormat* is set to ``"binary"``,
``"b"`` or ``"uncompressed-binary"`` or ``"u"`` the object is returned in a
binary format.
.. us.params
**Parameters**
.. uparam:: obj
*obj* is the object created with :ref:`obj_create`.
.. uparam:: ssFilename
*ssFilename* is the complete file name or an empty string. See *ret*
.. uparam:: ssFormat
*ssFormat* is a format string to specify the number format (see :ref:`printf`)
(The default value is ``"%.20g"``), or the string ``"binary"`` or ``"b"``,
``"uncompressed-binary"`` or ``"u"`` to save the file in a binary format.
.. us.example
**Example**
.. highlightlang:: us
::
obj = obj_create()
obj[1] = 123
obj.a = "Hello"
obj.c = obj_create()
obj.c.d = 456
obj.save("d:\\test.xml")
creates the following XML file:
.. highlightlang:: xml
::
123
Hello
456
An empty string saves the object in an xml string::
s = obj.save("")
``"binary"`` creates a binary format::
s = obj.save("", "binary")
mem_dump(s)
.. us.comment
**Comment**
**Notes**
* Saving the data in a binary fomat is approx 50 times faster than in an xml
format.
* Saving the data as string is appropriate for objects smaller than some MB.
Bigger objects should be saved in the binary format.
**XML-Scheme**
RelaxNG scheme for the XML file (see also
http://relaxng.org/compact-tutorial-20030326.html):
.. relax
::
obj = element obj { obj_attlist, (obj_inner | simple)* }
obj_attlist = attribute id { xsd:positiveInteger }?
simple =
number
| \string
| complex
| number-matrix
| string-matrix
| complex-matrix
| variant-matrix
obj_inner = element obj { obj_inner_attlist, simple* }
obj_inner_attlist =
key_or_ikey,
attribute id { xsd:positiveInteger }?,
attribute ref { xsd:positiveInteger }?
#
number = element number { key_or_ikey, xsd:double }
\string = element string { string_attlist, text }
string_attlist =
key_or_ikey,
attribute encoding { xsd:string "base64" }?
complex = element complex { key_or_ikey, cpx }
#
mat_number = element number { xsd:double }
mat_string = element string { mat_string_attlist, text }
mat_string_attlist = attribute encoding { xsd:string "base64" }?
mat_complex = element complex { cpx }
#
number-matrix = element number-matrix { matrix_attlist, mat_number+ }
string-matrix = element string-matrix { matrix_attlist, mat_string+ }
complex-matrix = element complex-matrix { matrix_attlist, mat_complex+ }
variant-matrix =
element variant-matrix {
matrix_attlist, (mat_number | mat_string | mat_complex)+
}
cpx = xsd:string { pattern = "[\-+]?[0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?[\-+][0-9]*\.?[0-9]+([eE][\-+]?[0-9]+)?i" }
key_or_ikey =
attribute key { text }
| attribute ikey { xsd:double }
row_cols =
attribute rows { xsd:positiveInteger },
attribute cols { xsd:positiveInteger }
matrix_attlist = key_or_ikey, row_cols
.. relax-end
**Binary format**
::
header: "USO" version-number
object: 'o' len ikey id-or-ref
object: 'p' len key id-or-ref
endofobj: ')'
double: 'n' ikey data
double: 'm' key data
string: 's' ikey string
string: 't' key string
complex: 'c' ikey cdata
complex: 'd' key cdata
matrix: 'N' len ikey shape data
matrix: 'M' len key shape data
smatrix: 'S' len ikey shape string
smatrix: 'T' len key shape string
cmatrix: 'C' len ikey shape cdata
cmatrix: 'D' len key shape cdata
vmatrix: 'V' len ikey shape vdata
vmatrix: 'W' len key shape vdata
All values are saved in little-endian byte order (LEBO).
The header (4 bytes) is followed by the object 'o' with the ID=1 and the key
ikey=0.0. The object is followed by an abitray number of objects and other
data elements. Each object is terminated with an endofobj: ')'.
.. list-table::
:header-rows: 0
* - version-number
- byte, version number is 1.
* - len
- Each matrix and object tag is followed by the element length.
The length is a 64-Bit integer.
* - ikey
- Number key (double - 8 Bytes).
* - key
- keylen (int32) in bytes, followed by any number of UTF-16 characters.
All UNICODE characters can be used for keys except null characters.
* - id_or_ref
- (int32), ID of the object (1, 2, ...) or, if id_or_ref
is negative, reference of an object.
* - shape
- nrows (int32) ncols (int32). Number of rows and columns of a matrix
The matrix elements are saved column wise: a[1;1], a[2;1], ...
* - string
- len (int32) in bytes, followed by UTF-16 characters or bytes (also 0-bytes).
* - data
- Matrix with double numbers (double - 8 Bytes). If the format is not
``"uncompressed-binary"``, the data is saved as a block with
LZ4 compression (https://code.google.com/p/lz4/). If ``len`` is equal
``nrows*ncols*8``, the data is uncompressed. In this version, only
matrices with double numbers are compressed. String
matrices, complex matrices, variant matrices and objects are not
compressed.
* - cdata
- Matrix with complex elements (two double values: real, imag).
* - vdata
- Variant matrix. Elements can be numbers, complex numbers, strings or
Objects. The value starts with the byte 'n', 'c', 's' or 'o'.
**Circular Reference**
The function can also save nested objects with references, e.g.
.. highlightlang:: us
::
obj = obj_create()
obj.val = 123
obj.next = obj_create()
obj.next.val = 456
obj.next.next = obj
obj.save("d:\\test1.xml")
creates the follow XML file (note attributes ``id`` and ``ref``):
.. highlightlang:: xml
::
456
123
.. us.history
**History**
.. list-table::
:header-rows: 1
* - Version
- Description
* - R2014.3
- Objects can be saved in a binary format.
* - 5.10.0
- An empty string can be used as a file name.
* - 5.0.0
- Unicode changes.
* - 4.1.0
- New.
.. seealso::
:ref:`overview-uniscript-objects`,
:ref:`obj_load`,
:ref:`obj_copy`
:sub:`id-699932`