
    _Mhe                     (   d Z ddlZddlZddlZddlZddlZddlmZ ddlZddl	Z
ddlZddlmZmZ ddlmZmZmZmZmZmZmZmZmZ ddlmZ ddlmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z. dd	l/m0Z0 d
 Z1d Z2d Z3d Z4 G d de          Z5d Z6 G d d          Z7d Z8ee         d         d         Z9ee         d         d         Z:ee         d         d         Z;ee         d         d         Z< G d d          Z= G d d          Z>dS )a<   Classes for read / write of matlab (TM) 5 files

The matfile specification last found here:

https://www.mathworks.com/access/helpdesk/help/pdf_doc/matlab/matfile_format.pdf

(as of December 5 2008)

=================================
 Note on functions and mat files
=================================

The document above does not give any hints as to the storage of matlab
function handles, or anonymous function handles. I had, therefore, to
guess the format of matlab arrays of ``mxFUNCTION_CLASS`` and
``mxOPAQUE_CLASS`` by looking at example mat files.

``mxFUNCTION_CLASS`` stores all types of matlab functions. It seems to
contain a struct matrix with a set pattern of fields. For anonymous
functions, a sub-fields of one of these fields seems to contain the
well-named ``mxOPAQUE_CLASS``. This seems to contain:

* array flags as for any matlab matrix
* 3 int8 strings
* a matrix

It seems that whenever the mat file contains a ``mxOPAQUE_CLASS``
instance, there is also an un-named matrix (name == '') at the end of
the mat file. I'll call this the ``__function_workspace__`` matrix.

When I saved two anonymous functions in a mat file, or appended another
anonymous function to the mat file, there was still only one
``__function_workspace__`` un-named matrix at the end, but larger than
that for a mat file with a single anonymous function, suggesting that
the workspaces for the two functions had been merged.

The ``__function_workspace__`` matrix appears to be of double class
(``mxCLASS_DOUBLE``), but stored as uint8, the memory for which is in
the format of a mini .mat file, without the first 124 bytes of the file
header (the description and the subsystem_offset), but with the version
U2 bytes, and the S2 endian test bytes. There follow 4 zero bytes,
presumably for 8 byte padding, and then a series of ``miMATRIX``
entries, as in a standard mat file. The ``miMATRIX`` entries appear to
be series of un-named (name == '') matrices, and may also contain arrays
of this same mini-mat format.

I guess that:

* saving an anonymous function back to a mat file will need the
  associated ``__function_workspace__`` matrix saved as well for the
  anonymous function to work correctly.
* appending to a mat file that has a ``__function_workspace__`` would
  involve first pulling off this workspace, appending, checking whether
  there were any more anonymous functions appended, and then somehow
  merging the relevant workspaces, and saving at the end of the mat
  file.

The mat files I was playing with are in ``tests/data``:

* sqr.mat
* parabola.mat
* some_functions.mat

See ``tests/test_mio.py:test_mio_funcs.py`` for the debugging
script I was working with.

Small fragments of current code adapted from matfile.py by Heiko
Henkelmann; parts of the code for simplify_cells=True adapted from
http://blog.nephics.com/2019/08/28/better-loadmat-for-scipy/.
    N)BytesIO   )native_codeswapped_code)	MatFileReader	docfillermatdims
read_dtypearr_to_charsarr_dtype_numberMatWriteErrorMatReadErrorMatReadWarning)
VarReader5)MatlabObjectMatlabFunctionMDTYPESNP_TO_MTYPESNP_TO_MXTYPESmiCOMPRESSEDmiMATRIXmiINT8miUTF8miUINT32mxCELL_CLASSmxSTRUCT_CLASSmxOBJECT_CLASSmxCHAR_CLASSmxSPARSE_CLASSmxDOUBLE_CLASSmclass_info
mat_struct)ZlibInputStreamc                     t          | t          j                  o0| j        dk    o%| j        dk    ot          | d         t
                    S )zBDetermine if elem is an array and if first array item is a struct.r   )
isinstancenpndarraysizendimr"   )elems    U/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/scipy/io/matlab/_mio5.py_has_structr,   i   sF    tRZ(( ,di!m ,$)a- ,tAw
++-    c                    g }| D ]}t          |t                    r#|                    t          |                     :t	          |          r#|                    t          |                     l|                    |           |S )zyConstruct lists from cell arrays (loaded as numpy ndarrays), recursing
    into items if they contain mat_struct objects.)r%   r"   append_matstruct_to_dictr,   _inspect_cell_array)r'   	elem_listsub_elems      r+   r1   r1   o   s     I ' 'h
++ 	'/99::::"" 	'0::;;;;X&&&&r-   c                     i }| j         D ]^}| j        |         }t          |t                    rt	          |          ||<   7t          |          rt          |          ||<   Y|||<   _|S )z/Construct nested dicts from mat_struct objects.)_fieldnames__dict__r%   r"   r0   r,   r1   )matobjdfr*   s       r+   r0   r0   }   s}    
A  q!dJ'' 	%d++AaDD 	&t,,AaDDAaDDHr-   c                     | D ]c}t          | |         t                    rt          | |                   | |<   6t          | |                   rt	          | |                   | |<   d| S )z,Convert mat objects in dict to nested dicts.)r%   r"   r0   r,   r1   )r8   keys     r+   _simplify_cellsr<      sm     1 1afj)) 	1'#//AcFF3   	1(300AcFHr-   c                   t     e Zd ZdZe	 	 	 	 	 	 	 	 	 d fd	            Zd Zd Zd Zd	 Z	dd
Z
ddZd Z xZS )MatFile5Readera   Reader for Mat 5 mat files
    Adds the following attribute to base class

    uint16_codec - char codec to use for uint16 char arrays
        (defaults to system default codec)

    Uses variable reader that has the following standard interface (see
    abstract class in ``miobase``::

       __init__(self, file_reader)
       read_header(self)
       array_from_header(self)

    and added interface::

       set_stream(self, stream)
       read_full_tag(self)

    NFTc                     t                                          |||||||||
	  	         |	st          j                    }	|	| _        d| _        d| _        dS )zInitializer for matlab 5 file format reader

    %(matstream_arg)s
    %(load_args)s
    %(struct_arg)s
    uint16_codec : {None, string}
        Set codec to use for uint16 char arrays (e.g., 'utf-8').
        Use system default codec if None
        N)super__init__sysgetdefaultencodinguint16_codec_file_reader_matrix_reader)self
mat_stream
byte_order	mat_dtype
squeeze_mechars_as_stringsmatlab_compatiblestruct_as_record verify_compressed_data_integrityrD   simplify_cells	__class__s              r+   rA   zMatFile5Reader.__init__   sr    * 	,		 		 		  	4133L( "r-   c                     | j                             d           | j                             d          }| j                             d           |dk    rdpdS )z3 Guess byte order.
        Sets stream pointer to 0~      r   s   IM<>)rH   seekread)rG   mis     r+   guess_byte_orderzMatFile5Reader.guess_byte_order   sY     	S!!!_!!!$$QU{"s)c)r-   c                    i }t           | j                 d         d         }t          | j        |          }|d                                                             d          |d<   |d         dz	  }|d         dz  }d	||fz  |d
<   |S )z Read in mat 5 file header dtypesfile_headerdescriptions    	
 
__header__version      z%d.%d__version__)r   rI   r
   rH   itemstrip)rG   hdict	hdr_dtypehdrv_majorv_minors         r+   read_file_headerzMatFile5Reader.read_file_header   s    DO,X6}E	)44!-05577==lKKli.A%i.4'&'7);;mr-   c                 V    t          |           | _        t          |           | _        dS )za Run when beginning read of variables

        Sets up readers from parameters in `self`
        N)r   rE   rF   rG   s    r+   initialize_readzMatFile5Reader.initialize_read   s*     't,,(..r-   c                    | j                                         \  }}|dk    st          d          | j                                        |z   }|t
          k    rSt          | j        |          }| j                            |           | j	        }| j                                        \  }}n!d}| j                            | j                   |t          k    st          d|z            | j                            |          }||fS )a   Read header, return header, next position

        Header has to define at least .name and .is_global

        Parameters
        ----------
        None

        Returns
        -------
        header : object
           object that can be passed to self.read_var_array, and that
           has attributes .name and .is_global
        next_position : int
           position in stream of next variable
        r   zDid not read any bytesFz$Expecting miMATRIX type here, got %d)rE   read_full_tag
ValueErrorrH   tellr   r#   rF   
set_streamrO   r   	TypeErrorread_header)rG   mdtype
byte_countnext_posstreamcheck_stream_limitheaders          r+   read_var_headerzMatFile5Reader.read_var_header   s   " ".<<>>
A~~5666?''))J6\!!$T_jAAF**6222!%!F!%!4!B!B!D!DFJJ!&**4?;;;!!BVKLLL$001CDDxr-   c                 8    | j                             ||          S )a   Read array, given `header`

        Parameters
        ----------
        header : header object
           object with fields defining variable header
        process : {True, False} bool, optional
           If True, apply recursive post-processing during loading of
           array.

        Returns
        -------
        arr : array
           array with post-processing applied or not according to
           `process`.
        )rF   array_from_header)rG   r{   processs      r+   read_var_arrayzMatFile5Reader.read_var_array  s    " "44VWEEEr-   c                 
   t          |t                    r|g}n|t          |          }| j                            d           |                                  |                                 }g |d<   |                                 sf|                                 \  }}|j	        dn|j	        
                    d          }||v r"d| d}t          j        |t          d	           |d
k    rd}d}nd}|||vr| j                            |           	 |                     ||          }n?# t          $ r2}	t          j        d| d|	 dt           d	           d|	 }Y d}	~	nd}	~	ww xY w| j                            |           |||<   |j        r|d                             |           |)|                    |           t)          |          dk    rn|                                 f| j        rt-          |          S |S )z get variables from stream as dictionary

        variable_names   - optional list of variable names to get

        If variable_names is None, then get all variables in file
        Nr   __globals__Nonelatin1zDuplicate variable name "z{" in stream - replacing previous with new
Considerscipy.io.matlab.varmats_from_mat to split file into single variable filesrT   )
stacklevel __function_workspace__FTzUnreadable variable "z", because ""zRead error: )r%   strlistrH   rW   rn   rk   end_of_streamr|   namedecodewarningswarnr   r   r   Warning	is_globalr/   removelenrP   r<   )
rG   variable_namesmdictrh   next_positionr   msgr   reserrs
             r+   get_variableszMatFile5Reader.get_variables%  st    nc** 	2,-NN'!.11NQ%%''!m$$&& $	!%!5!5!7!7C X-6638??83L3LDu}}6 6 6 6  c>a@@@@rzz/  )d..H.H$$]333+))#w77 + + +DDDDcDDD+ + + + +S**	+
 O  ///E$K} 2m$++D111)%%d+++~&&!++I $$&& $	J  	"5)))Ls   D- -
E)7(E$$E)c                 B   | j                             d           |                                  |                                  g }|                                 s|                                 \  }}|j        dn|j                            d          }|dk    rd}| j        	                    |          }|j
        rd}nt          j        |j        d          }|                    |||f           | j                             |           |                                 |S )	z list variables from stream r   Nr   r   r   r   logicalunknown)rH   rW   rn   rk   r   r|   r   r   rF   shape_from_header
is_logicalr!   getmclassr/   )rG   varsrh   r   r   shapeinfos          r+   list_variableszMatFile5Reader.list_variables`  s   Q$$&& 	0!%!5!5!7!7C X-6638??83L3LDrzz/'99#>>E~ > "sz9==KKud+,,,O  /// $$&& 	0 r-   )	NFFTFTTNF)TN)__name__
__module____qualname____doc__r   rA   rZ   rk   rn   r|   r   r   r   __classcell__)rQ   s   @r+   r>   r>      s         &  ! !"&#("&26" %$# $# $# $# $# Y$#L* * *	 	 	
/ 
/ 
/!  !  ! FF F F F&9 9 9 9v      r-   r>   c                 R   t          |           }|                     d           t          t                   d         d         j        }|                     |          }|                     d           |                                 |                                 |                                 }g }|	                                s|}|
                                \  }}|j        dn|j                            d          }|                     |           ||z
  }	|                     |	          }
t                      }|                    |           |                    |
           |                    d           |                    ||f           |	                                |S )a-   Pull variables out of mat 5 file as a sequence of mat file objects

    This can be useful with a difficult mat file, containing unreadable
    variables. This routine pulls the variables out in raw form and puts them,
    unread, back into a file stream for saving or reading. Another use is the
    pathological case where there is more than one variable of the same name in
    the file; this routine returns the duplicates, whereas the standard reader
    will overwrite duplicates in the returned dictionary.

    The file pointer in `file_obj` will be undefined. File pointers for the
    returned file-like objects are set at 0.

    Parameters
    ----------
    file_obj : file-like
        file object containing mat file

    Returns
    -------
    named_mats : list
        list contains tuples of (name, BytesIO) where BytesIO is a file-like
        object containing mat file contents as for a single variable. The
        BytesIO contains a string with the original header and a single var. If
        ``var_file_obj`` is an individual BytesIO instance, then save as a mat
        file with something like ``open('test.mat',
        'wb').write(var_file_obj.read())``

    Examples
    --------
    >>> import scipy.io
    >>> import numpy as np
    >>> from io import BytesIO
    >>> from scipy.io.matlab._mio5 import varmats_from_mat
    >>> mat_fileobj = BytesIO()
    >>> scipy.io.savemat(mat_fileobj, {'b': np.arange(10), 'a': 'a string'})
    >>> varmats = varmats_from_mat(mat_fileobj)
    >>> sorted([name for name, str_obj in varmats])
    ['a', 'b']
    r   r\   r]   Nr   r   )r>   rW   r   r   itemsizerX   rn   rk   rr   r   r|   r   r   r   writer/   )file_objrdrhdr_lenraw_hdrr   
named_matsstart_positionrh   r   rw   var_strout_objs               r+   varmats_from_matr   y  s   P 
"
"CMM!k"8,];DGmmG$$GMM!MMOOMJ!! +& 0022])vvsxx/H/Hn%%%"^3
--
++))ggQ4/*** !! + r-   c                       e Zd ZdZdS )EmptyStructMarkerz= Class to indicate presence of empty matlab struct on output N)r   r   r   r    r-   r+   r   r     s        GGGGr-   r   c                    t          | t          j                  r| S | dS t          | d          rt          j        |           S t          | d          ot          | d          ot          | d          }t          | t          j                  rn7|s5t          | d          r%d | j                                        D             } d}|rg }g }|                                 D ]b\  }}t          |t                    rH|d	         d
vr>|	                    t          |          t          f           |	                    |           c|r#t          j        t          |          g|          S t          S 	 t          j        |           }n+# t          $ r t          j        | t                    }Y nw xY w|j        j        t          t          j        fv r|j        dk    r|| k    rdS |S )a   Convert input object ``source`` to something we can write

    Parameters
    ----------
    source : object

    Returns
    -------
    arr : None or ndarray or EmptyStructMarker
        If `source` cannot be converted to something we can write to a matfile,
        return None.  If `source` is equivalent to an empty dictionary, return
        ``EmptyStructMarker``.  Otherwise return `source` converted to an
        ndarray with contents for writing to matfile.
    N	__array__keysvaluesitemsr6   c                 D    i | ]\  }}|                     d           ||S )_)
startswith).0r;   values      r+   
<dictcomp>z to_writeable.<locals>.<dictcomp>  s>     2 2 2e ^^C002#u 2 2 2r-   Tr   _0123456789dtyper   )r%   r&   r'   hasattrasarraygenericr6   r   r   r/   objectarraytupler   
asanyarrayrq   r   typeobject_r   )source
is_mappingr   r   fieldr   narrs          r+   to_writeabler     s    &"*%% ~tv{## "z&!!!&&)) +gfh.G.G +&'**  &"*%%  GFJ77 2 2v/D/D/F/F 2 2 2
 %"LLNN 	% 	%LE55#&& %!HM11c%jj&1222e$$$ 	%8U6]]OU333$$3}V$$ 3 3 3}V62223z62:...zRDFNNtKs   1F %F.-F.r\   r]   tag_fulltag_smalldataarray_flagsc                       e Zd ZdZ ej        de          Zeed<   d Z	d Z
d ZddZd	 Zd
 Z	 	 	 ddZd Zd Zd Zd ZddZd Zd Zd Zd Zd Zd ZdS )
VarWriter5z% Generic matlab matrix writing class r   rv   c                     |j         | _         |j        | _        |j        | _        |j        | _        d | _        d| _        d S )NF)file_streamunicode_stringslong_field_namesoned_as	_var_name_var_is_global)rG   file_writers     r+   rA   zVarWriter5.__init__  sB    &2*: + <"*#r-   c                 b    | j                             |                    d                     d S )NForder)r   r   tobytesrG   arrs     r+   write_byteszVarWriter5.write_bytes  s-    s{{{5566666r-   c                 :    | j                             |           d S r   )r   r   )rG   ss     r+   write_stringzVarWriter5.write_string  s    q!!!!!r-   Nc                 x   |t           |j        j        dd                  }|j        j        t          k    r>|                                                    |j                                                  }|j        |j	        z  }|dk    r| 
                    |||           dS |                     |||           dS )z write tag and data Nr      )r   r   r   	byteorderr   byteswapviewnewbyteorderr(   r   write_smalldata_elementwrite_regular_element)rG   r   rv   rw   s       r+   write_elementzVarWriter5.write_element  s    >!#)-"34F9,..,,..%%ci&<&<&>&>??CXcl*
??((fjAAAAA&&sFJ?????r-   c                     t          j        dt                    }|dz  |z   |d<   |                    d          |d<   |                     |           d S )Nr      byte_count_mdtyper   r   data)r&   zerosNDT_TAG_SMALLr   r   )rG   r   rv   rw   tags        r+   r   z"VarWriter5.write_smalldata_element!  sY    hr=))$."$4#> kkk,,Fr-   c                     t          j        dt                    }||d<   ||d<   |                     |           |                     |           |dz  }|r"| j                            dd|z
  z             d S d S )Nr   rv   rw   ra       )r&   r   NDT_TAG_FULLr   r   r   )rG   r   rv   rw   r   bc_mod_8s         r+   r   z VarWriter5.write_regular_element)  s    hr<((H&L> 	;""7aj#9:::::	; 	;r-   Fr   c                 b   | j         }| j        }| j                                        | _        |                     | j                   t          j        dt                    }t          |d<   d|d<   |dz  |dz  z  |dz  z  }	||	dz  z  |d<   ||d	<   |                     |           |                     t          j        |d
                     t          j        |          }|dk    r|                     |t          d           n|                     |t                     d| _         d| _        dS )a   Write header for given data options
        shape : sequence
           array shape
        mclass      - mat5 matrix class
        is_complex  - True if matrix is complex
        is_logical  - True if matrix is logical
        nzmax        - max non zero elements for sparse arrays

        We get the name and the global flag from the object, and reset
        them to defaults after we've used them
        r   	data_typera   rw      rT   r   flags_classnzmaxi4r   r   r   FN)r   r   r   rr   _mat_tag_posr   mat_tagr&   r   NDT_ARRAY_FLAGSr   r   r   r   r   r   )
rG   r   r   
is_complexr   r  r   r   afflagss
             r+   write_headerzVarWriter5.write_header5  s0   $ ~'	 ,1133&&&Xb/**";<a)q.0:?B"UaZ/=728E666777z$2::((vq9999tV,,,#r-   c                 "   | j                                         }| j                             |           ||z
  dz
  }|dk    rt          d          || j        d<   |                     | j                   | j                             |           d S )Nra   l        z-Matrix too large to save with Matlab 5 formatrw   )r   rr   rW   r   r
  r   )rG   	start_poscurr_posrw   s       r+   update_matrix_tagzVarWriter5.update_matrix_tag`  s    #((**i(((	)A-
 !+ , , ,%/\"&&&h'''''r-   c                 L    || _         || _        |                     |           dS )a   Write variable at top level of mat file

        Parameters
        ----------
        arr : array_like
            array-like object to create writer for
        name : str, optional
            name as it will appear in matlab workspace
            default is empty string
        is_global : {False, True}, optional
            whether variable will be global on load into matlab
        N)r   r   r   )rG   r   r   r   s       r+   	write_topzVarWriter5.write_topk  s&     (

3r-   c                 N   | j                                         }t          j                            |          r,|                     |           |                     |           dS t          |          }|#t          d| dt          |           d          t          |t                    r|                     |           nt          |t                    rt          d          |t          u r|                                  n|j        j        r|                     |           nh|j        j        r|                     |           nF|j        j        dv r#| j        rd}nd}|                     ||           n|                     |           |                     |           dS )	z Write `arr` to stream at top and sub levels

        Parameters
        ----------
        arr : array_like
            array-like object to create writer for
        NzCould not convert z (type z
) to arrayzCannot write matlab functions)USUTF8ascii)r   rr   scipysparseissparsewrite_sparser  r   rt   r   r%   r   write_objectr   r   r   write_empty_structr   fieldswrite_struct	hasobjectwrite_cellskindr   
write_charwrite_numeric)rG   r   mat_tag_posr   codecs        r+   r   zVarWriter5.write  s    &++--<  %% 	c""""";///FC  <RRRT#YYRRRSSSdL)) 	%d####n-- 	% ?@@@&&&##%%%%Z 	%d####Z! 		%T""""Z_
**#  OOD%((((t$$${+++++r-   c                 2   |j         j        dk    }|j         j        dk    }	 t          |j         j        dd                   }n\# t          $ rO |r|                    d          }n-|r|                    d          }n|                    d          }t          }Y nw xY w|                     t          || j	                  |||           |r6| 
                    |j                   | 
                    |j                   d S | 
                    |           d S )Ncbr   c128i1f8)r  r   )r   r%  r   r   KeyErrorastyper    r  r	   r   r   realimag)rG   r   imagflogifr   s        r+   r'  zVarWriter5.write_numeric  s5   	#%	#%	$"39=#45FF 		$ 		$ 		$  'jj(( 'jj&&jj&&#FFF		$ 	'#t|44 %*%* 	 	, 	, 	,  	$sx(((sx(((((s#####s   A ABBr  c                    |j         dk    st          j        |dk              rWdt          j        |j        dg          z  }|                     |t                     |                     |t          d           dS t          |          }|j
        }|                     |t                     |j        j        dk    r|j         rt          j        |          }t          j        dt!          ||          |j                                                  }|                                                    |          }t          j        t+          |          fd	|          }|                     |t          
           dS )z5 Write string array `arr` with given `codec`
        r   r   r   rT   Nr  r   r   r   bufferS1rv   )r(   r&   allmaxr)   r  r   r   r   r   r   r   r%  mathprodr'   r   Tcopyrd   encoder   r   )rG   r   r)  r   n_charsst_arrsts          r+   r&  zVarWriter5.write_char  s[    8q==BF3"9--= 2638Q-000Ee\222((fa888F 3 	%...9>S  SX 
 i&&GZb&6sG&D&D'*uzz||5 5 5F %%e,,B*CGG:#'$&( ( (C 	3v.....r-   c                 P   |                                 }|                                 |j        j        dk    }|j        j        dk    }|j        }|                     t          || j                  t          |||dk    rdn|           | 	                    |j
                            d                     | 	                    |j                            d                     | 	                    |j        j                   |r!| 	                    |j        j                   dS dS )z  Sparse matrices are 2D
        r+  r,  r   r   )r  r   r  r  N)tocscsort_indicesr   r%  nnzr  r	   r   r   r   indicesr1  indptrr   r2  r3  )rG   r   Ar  r   nzs         r+   r  zVarWriter5.write_sparse  s    IIKK	glc)
glc)
U'#t|44(%/%/%'1WW" 	 	6 	6 	6 	19++D1122218??40011116;''' 	,qv{+++++	, 	,r-   c                     |                      t          || j                  t                     t	          j        |                              d          }|D ]}|                     |           d S )Nr   )r  r	   r   r   r&   
atleast_2dflattenr   )rG   r   rL  els       r+   r$  zVarWriter5.write_cells  st    '#t|44&	( 	( 	( M#&&s++ 	 	BJJrNNNN	 	r-   c                    |                      dt                     |                     t          j        dt          j                             |                     t          j        g t          j                             d S )N)r   r   r   r   )r  r   r   r&   r   int32int8rm   s    r+   r   zVarWriter5.write_empty_struct  sh    &.11128ARX66677728Bbg66677777r-   c                     |                      t          || j                  t                     |                     |           d S r   )r  r	   r   r   _write_itemsr   s     r+   r"  zVarWriter5.write_struct  sE    '#t|44(	* 	* 	*#r-   c                    d |j         j        D             }t          d |D                       dz   }| j        rdpd}||k    rt	          d|dz
  z            |                     t          j        |gd                     |                     t          j        |d	|z            t          
           t          j	        |          
                    d          }|D ]"}|D ]}|                     ||                    #d S )Nc                     g | ]
}|d          S r7  r   )r   r9   s     r+   
<listcomp>z+VarWriter5._write_items.<locals>.<listcomp>  s    444qad444r-   c                 ,    g | ]}t          |          S r   )r   )r   	fieldnames     r+   rY  z+VarWriter5._write_items.<locals>.<listcomp>  s    AAAc)nnAAAr-   r   @       z+Field names are restricted to %d charactersr  r   zS%dr;  r   )r   descrr=  r   rq   r   r&   r   r   rO  rP  r   )rG   r   
fieldnameslength
max_lengthrL  rQ  r9   s           r+   rV  zVarWriter5._write_items  s9   44CIO444
AAjAAABB1D+29r
JJ(l, - - -28VHD999:::HZu'7888 	 	 	 	 M#&&s++ 	" 	"B " "

2a5!!!!"	" 	"r-   c                     |                      t          || j                  t                     |                     t          j        |j        d          t                     | 	                    |           dS )zmSame as writing structs, except different mx class, and extra
        classname element after header
        r  r   r;  N)
r  r	   r   r   r   r&   r   	classnamer   rV  r   s     r+   r  zVarWriter5.write_object#  sz     	'#t|44(	* 	* 	*28CM==="( 	 	* 	* 	*#r-   r   )FFr   )r  )r   r   r   r   r&   r   r  r
  r   rA   r   r   r   r   r   r  r  r  r   r'  r&  r  r$  r   r"  rV  r  r   r-   r+   r   r      sf       //bhr<((G GH$ $ $7 7 7" " "@ @ @ @  
; 
; 
; !& %)$ )$ )$ )$V	( 	( 	(  (%, %, %,N$ $ $2)/ )/ )/ )/V, , ,(  8 8 8  
" " ""    r-   r   c                   B    e Zd ZdZe	 	 	 	 	 dd            Zd Zd	dZdS )
MatFile5Writerz Class for writing mat5 files FNrowc                 |    || _         || _        || _        |r|| _        ng | _        || _        || _        d| _        dS )a<   Initialize writer for matlab 5 format files

        Parameters
        ----------
        %(do_compression)s
        %(unicode_strings)s
        global_vars : None or sequence of strings, optional
            Names of variables to be marked as global for matlab
        %(long_fields)s
        %(oned_as)s
        N)r   do_compressionr   global_varsr   r   _matrix_writer)rG   r   rh  r   ri  r   r   s          r+   rA   zMatFile5Writer.__init__1  sT    $ ',. 	"*D!D 0"r-   c                 @   t          j        dt                    }dt          j         dt          j                     |d<   d|d<   t          j        ddt          j        d          	          |d
<   | j	        
                    |                                           d S )Nr   zMATLAB 5.0 MAT-file Platform: z, Created on: r^      r`   S2iIM  r8  endian_test)r&   r   NDT_FILE_HDRosr   timeasctimer'   uint16r   r   r   )rG   rh   s     r+   write_file_headerz MatFile5Writer.write_file_headerN  s    hr<((>rw > >-1\^^> >MIZb,0-/Yv->->@ @ @M 	s{{}}-----r-   c                 B   || j                                         dk    }|r|                                  t          |           | _        |                                D ]?\  }}|d         dk    r|| j        v }| j        rt                      }|| j        _         | j        	                    ||
                    d          |           t          j        |                                          }t          j        dt                     }t"          |d<   t%          |          |d<   | j                             |                                           | j                             |           | j        	                    ||
                    d          |           AdS )a   Write variables in `mdict` to stream

        Parameters
        ----------
        mdict : mapping
           mapping with method ``items`` returns name, contents pairs where
           ``name`` which will appear in the matlab workspace in file load, and
           ``contents`` is something writeable to a matlab file, such as a NumPy
           array.
        write_header : {None, True, False}, optional
           If True, then write the matlab file header before writing the
           variables. If None (the default) then write the file header
           if we are at position 0 in the stream. By setting False
           here, and setting the stream position to the end of the file,
           you can append variables to a matlab file
        Nr   r   r   r   rv   rw   )r   rr   rt  r   rj  r   ri  rh  r   r  rB  zlibcompressgetvaluer&   emptyr  r   r   r   r   )	rG   r   r  r   varr   ry   out_strr   s	            r+   put_variableszMatFile5Writer.put_variablesY  s   $ +0022a7L 	%""$$$(.. 	U 	UID#Aw#~~ 00I" U 28#/#--c4;;x3H3H)TTT-(9(9::hr<00 ,H$'LLL! &&s{{}}555 &&w////#--c4;;x3H3H)TTTT	U 	Ur-   )FFNFrf  r   )r   r   r   r   r   rA   rt  r|  r   r-   r+   re  re  .  sp        (( %!&!"'# # # Y#8	. 	. 	.&U &U &U &U &U &Ur-   re  )?r   r>  rp  rq  rB   rv  ior   r   numpyr&   scipy.sparser  _byteordercodesr   r   _miobaser   r   r	   r
   r   r   r   r   r   _mio5_utilsr   _mio5_paramsr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    r!   r"   _streamsr#   r,   r1   r0   r<   r>   r   r   r   ro  r  r   r  r   re  r   r-   r+   <module>r     s  E EN  				  



                 6 6 6 6 6 6 6 64 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
 $ # # # # #C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C C & % % % % %- - -      a a a a a] a a aHA A AHH H H H H H H H5 5 5r {#H-m<{#H-j9$X.?+&x0?k k k k k k k k\	QU QU QU QU QU QU QU QU QU QUr-   