.. 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`