o
    :‘ði”I  ã                   @   sN  d Z g d¢ZddlZddlZddlmZmZ zddlZW n e	y'   dZY nw edu r?dd„ Z
e
Ze
Ze
ZddlmZ eZnddlm  mZ e ¡ Z[ejZdd	„ Zd
d„ Zg d¢Zdd„ ZG dd„ deƒZG dd„ deƒZi Zd'dd„Zedur¥dd„ Zdd„ Z e ƒ Z!dd„ Z"dd„ Z#dd„ Z$dd „ Z%d!d"„ Z&d(d#d$„Zd%d&„ ZdS dS ))a7  
============================
``ctypes`` Utility Functions
============================

See Also
--------
load_library : Load a C library.
ndpointer : Array restype/argtype with verification.
as_ctypes : Create a ctypes array from an ndarray.
as_array : Create an ndarray from a ctypes array.

References
----------
.. [1] "SciPy Cookbook: ctypes", https://scipy-cookbook.readthedocs.io/items/Ctypes.html

Examples
--------
Load the C library:

>>> _lib = np.ctypeslib.load_library('libmystuff', '.')     #doctest: +SKIP

Our result type, an ndarray that must be of type double, be 1-dimensional
and is C-contiguous in memory:

>>> array_1d_double = np.ctypeslib.ndpointer(
...                          dtype=np.double,
...                          ndim=1, flags='CONTIGUOUS')    #doctest: +SKIP

Our C-function typically takes an array and updates its values
in-place.  For example::

    void foo_func(double* x, int length)
    {
        int i;
        for (i = 0; i < length; i++) {
            x[i] = i*i;
        }
    }

We wrap it using:

>>> _lib.foo_func.restype = None                      #doctest: +SKIP
>>> _lib.foo_func.argtypes = [array_1d_double, c_int] #doctest: +SKIP

Then, we're ready to call ``foo_func``:

>>> out = np.empty(15, dtype=np.double)
>>> _lib.foo_func(out, len(out))                #doctest: +SKIP

)Úload_libraryÚ	ndpointerÚc_intpÚ	as_ctypesÚas_arrayÚas_ctypes_typeé    N)Ú	_flagdictÚflagsobjc                  O   s   t dƒ‚)z±
        Dummy object that raises an ImportError if ctypes is not available.

        Raises
        ------
        ImportError
            If ctypes is not available.

        zctypes is not available.)ÚImportError)ÚargsÚkwds© r   úN/root/parts/websockify/install/lib/python3.10/site-packages/numpy/ctypeslib.pyÚ_dummyA   s   
r   )Úintpc              	   C   s
  t  | ¡} t  |¡}t j | ¡d }|sFddl}ddl}d}|j d¡r'd}n|j d¡r/d}| | g}| d	¡}||ksE| 	d| | ¡ n| g}t j 
|¡}t j |¡s\t j |¡}n|}|D ] }	t j ||	¡}
t j |
¡r€ztj|
 W   S  ty   ‚ w q`td
ƒ‚)a
  
        It is possible to load a library using

        >>> lib = ctypes.cdll[<full_path_name>] # doctest: +SKIP

        But there are cross-platform considerations, such as library file extensions,
        plus the fact Windows will just load the first library it finds with that name.
        NumPy supplies the load_library function as a convenience.

        .. versionchanged:: 1.20.0
            Allow libname and loader_path to take any
            :term:`python:path-like object`.

        Parameters
        ----------
        libname : path-like
            Name of the library, which can have 'lib' as a prefix,
            but without an extension.
        loader_path : path-like
            Where the library can be found.

        Returns
        -------
        ctypes.cdll[libpath] : library object
           A ctypes library object

        Raises
        ------
        OSError
            If there is no library with the expected extension, or the
            library is defective and cannot be loaded.
        é   r   Nz.soÚdarwinz.dylibÚwinz.dllÚ
EXT_SUFFIXzno file with expected extension)ÚosÚfsdecodeÚpathÚsplitextÚsysÚ	sysconfigÚplatformÚ
startswithÚget_config_varÚinsertÚabspathÚisdirÚdirnameÚjoinÚexistsÚctypesÚcdllÚOSError)ÚlibnameÚloader_pathÚextr   r   Úbase_extÚlibname_extÚso_extÚlibdirÚlnÚlibpathr   r   r   r   X   s>   
"


€þýr   c                 C   s   d}| D ]}|t | 7 }q|S ©Nr   )r   )ÚflaglistÚnumÚvalr   r   r   Ú_num_fromflags¢   s   r4   )ÚC_CONTIGUOUSÚF_CONTIGUOUSÚALIGNEDÚ	WRITEABLEÚOWNDATAÚWRITEBACKIFCOPYc                 C   s,   g }t D ]}t| }| |@ r| |¡ q|S ©N)Ú
_flagnamesr   Úappend)r2   ÚresÚkeyÚvaluer   r   r   Ú_flags_fromnumª   s   
€rA   c                   @   s   e Zd Zedd„ ƒZdS )Ú_ndptrc                 C   sº   t |tjƒs
tdƒ‚| jd ur|j| jkrtd| j ƒ‚| jd ur.|j| jkr.td| j ƒ‚| jd urB|j	| jkrBtdt
| jƒ ƒ‚| jd urZ|jj| j@ | jkrZtdt| jƒ ƒ‚|jS )Nzargument must be an ndarrayzarray must have data type %szarray must have %d dimension(s)zarray must have shape %szarray must have flags %s)Ú
isinstanceÚnpÚndarrayÚ	TypeErrorÚ_dtype_ÚdtypeÚ_ndim_ÚndimÚ_shape_ÚshapeÚstrÚ_flags_Úflagsr2   rA   r$   )ÚclsÚobjr   r   r   Ú
from_param´   s"   



ÿz_ndptr.from_paramN)Ú__name__Ú
__module__Ú__qualname__ÚclassmethodrR   r   r   r   r   rB   ³   s    rB   c                   @   s$   e Zd ZdZdd„ Zedd„ ƒZdS )Ú_concrete_ndptrz¹
    Like _ndptr, but with `_shape_` and `_dtype_` specified.

    Notably, this means the pointer has enough information to reconstruct
    the array, which is not generally true.
    c                 C   s   | j S )z¹
        This method is called when this class is used as the .restype
        attribute for a shared-library function, to automatically wrap the
        pointer into an array.
        )Úcontents)Úselfr   r   r   Ú_check_retval_Ï   s   z_concrete_ndptr._check_retval_c                 C   sH   t  | j| jf¡}tj|j }t | t |¡¡j	}t j
||d�jdd�S )z—
        Get an ndarray viewing the data pointed to by this pointer.

        This mirrors the `contents` attribute of a normal ctypes pointer
        ©rH   r   )Úaxis)rD   rH   rG   rK   r$   Úc_charÚitemsizeÚcastÚPOINTERrX   Ú
frombufferÚsqueeze)rY   Ú
full_dtypeÚ
full_ctypeÚbufferr   r   r   rX   ×   s   z_concrete_ndptr.contentsN)rS   rT   rU   Ú__doc__rZ   ÚpropertyrX   r   r   r   r   rW   È   s
    rW   c           
   
   C   sÈ  | dur	t  | ¡} d}|durXt|tƒr| d¡}nt|tt jfƒr)|}t|ƒ}nt|tƒr5|j	}t|ƒ}|du rXz	dd„ |D ƒ}W n t
yS } ztdƒ|‚d}~ww t|ƒ}|durozt|ƒ}W n tyn   |f}Y nw | |||f}zt| W S  tyƒ   Y nw | du r‹d}n| jdur—tt| ƒƒ}n| j}|dur¤|d| 7 }|dur¶|dd	 d
d„ |D ƒ¡ 7 }|durÃ|dd |¡ 7 }| durÎ|durÎt}nt}td| |f| |||dœƒ}	|	t|< |	S )a:  
    Array-checking restype/argtypes.

    An ndpointer instance is used to describe an ndarray in restypes
    and argtypes specifications.  This approach is more flexible than
    using, for example, ``POINTER(c_double)``, since several restrictions
    can be specified, which are verified upon calling the ctypes function.
    These include data type, number of dimensions, shape and flags.  If a
    given array does not satisfy the specified restrictions,
    a ``TypeError`` is raised.

    Parameters
    ----------
    dtype : data-type, optional
        Array data-type.
    ndim : int, optional
        Number of array dimensions.
    shape : tuple of ints, optional
        Array shape.
    flags : str or tuple of str
        Array flags; may be one or more of:

        - C_CONTIGUOUS / C / CONTIGUOUS
        - F_CONTIGUOUS / F / FORTRAN
        - OWNDATA / O
        - WRITEABLE / W
        - ALIGNED / A
        - WRITEBACKIFCOPY / X

    Returns
    -------
    klass : ndpointer type object
        A type object, which is an ``_ndtpr`` instance containing
        dtype, ndim, shape and flags information.

    Raises
    ------
    TypeError
        If a given array does not satisfy the specified restrictions.

    Examples
    --------
    >>> clib.somefunc.argtypes = [np.ctypeslib.ndpointer(dtype=np.float64,
    ...                                                  ndim=1,
    ...                                                  flags='C_CONTIGUOUS')]
    ... #doctest: +SKIP
    >>> clib.somefunc(np.array([1, 2, 3], dtype=np.float64))
    ... #doctest: +SKIP

    Nú,c                 S   s   g | ]}|  ¡  ¡ ‘qS r   )ÚstripÚupper©Ú.0Úxr   r   r   Ú
<listcomp>,  ó    zndpointer.<locals>.<listcomp>zinvalid flags specificationÚanyz_%ddÚ_rm   c                 s   s   � | ]}t |ƒV  qd S r;   )rM   rk   r   r   r   Ú	<genexpr>J  s   € zndpointer.<locals>.<genexpr>zndpointer_%s)rG   rK   rI   rN   )rD   rH   rC   rM   ÚsplitÚintÚintegerrA   r	   r2   Ú	ExceptionrF   r4   ÚtupleÚ_pointer_type_cacheÚKeyErrorÚnamesÚidr"   rW   rB   Útype)
rH   rJ   rL   rO   r2   ÚeÚ	cache_keyÚnameÚbaseÚklassr   r   r   r   ç   sn   5




€ÿ
þ
ÿ
ýÿr   c                 C   s&   |ddd… D ]	}||  } d| _ q| S )z7 Create an ndarray of the given element type and shape Néÿÿÿÿ)rT   )Úelement_typerL   Údimr   r   r   Ú_ctype_ndarray]  s   r…   c                  C   sJ   t } | j| j| j| j| j| j| j| j| j	| j
| j| j| jg}dd„ |D ƒS )zX
        Return a dictionary mapping native endian scalar dtype to ctypes types
        c                 S   s   i | ]}t  |¡|“qS r   )rD   rH   )rl   Úctyper   r   r   Ú
<dictcomp>q  ro   z(_get_scalar_type_map.<locals>.<dictcomp>)r$   Úc_byteÚc_shortÚc_intÚc_longÚ
c_longlongÚc_ubyteÚc_ushortÚc_uintÚc_ulongÚc_ulonglongÚc_floatÚc_doubleÚc_bool)ÚctÚsimple_typesr   r   r   Ú_get_scalar_type_mapf  s   ür—   c              
   C   sx   |   d¡  d¡}|   d¡}zt| }W n ty' } ztd | ¡ƒd ‚d }~ww |jdkr2|j}|S |jdkr:|j}|S )NÚSú=z Converting {!r} to a ctypes typeú>ú<)ÚnewbyteorderÚ_scalar_type_mapry   ÚNotImplementedErrorÚformatÚ	byteorderÚ__ctype_be__Ú__ctype_le__)rH   Údtype_with_endianÚdtype_nativer†   r}   r   r   r   Ú_ctype_from_dtype_scalarw  s$   
ÿþ€ÿ

ýr¥   c                 C   s   | j \}}t|ƒ}t||ƒS r;   )ÚsubdtypeÚ_ctype_from_dtyper…   )rH   Úelement_dtyperL   r†   r   r   r   Ú_ctype_from_dtype_subarrayŠ  s   

r©   c           
      C   s€  g }| j D ]}| j| d d… \}}| ||t|ƒf¡ qt|dd„ d�}t|ƒdkrltdd„ |D ƒƒrld}g }|D ]\}}}| ||f¡ t|t 	|¡ƒ}q:| j
|kr_| d	tj| j
 f¡ td
tjft|dd d�ƒS d}g }|D ]-\}}}|| }	|	dk rƒtdƒ‚|	dkr‘| d	tj|	 f¡ | ||f¡ |t 	|¡ }qr| j
| }	|	dkr³| d	tj|	 f¡ tdtjft|dd d�ƒS )Né   c                 S   s   | d S r0   r   )Úfr   r   r   Ú<lambda>˜  s    z._ctype_from_dtype_structured.<locals>.<lambda>)r?   r   c                 s   s   � | ]
\}}}|d kV  qdS )r   Nr   )rl   Úoffsetr   r†   r   r   r   rr   š  s   € z/_ctype_from_dtype_structured.<locals>.<genexpr>r   Ú Úunion)Ú_fields_Ú_pack_rT   zOverlapping fieldsÚstruct)rz   Úfieldsr=   r§   ÚsortedÚlenÚallÚmaxr$   Úsizeofr^   r]   r|   ÚUnionÚdictrž   Ú	Structure)
rH   Ú
field_datar   Úfield_dtyper­   Úsizer°   r†   Úlast_offsetÚpaddingr   r   r   Ú_ctype_from_dtype_structured�  sH   

ý
ýrÁ   c                 C   s,   | j d ur	t| ƒS | jd urt| ƒS t| ƒS r;   )r³   rÁ   r¦   r©   r¥   r[   r   r   r   r§   Æ  s
   

r§   c                 C   s   t t | ¡ƒS )a
  
        Convert a dtype into a ctypes type.

        Parameters
        ----------
        dtype : dtype
            The dtype to convert

        Returns
        -------
        ctype
            A ctype scalar, union, array, or struct

        Raises
        ------
        NotImplementedError
            If the conversion is not possible

        Notes
        -----
        This function does not losslessly round-trip in either direction.

        ``np.dtype(as_ctypes_type(dt))`` will:

        - insert padding fields
        - reorder fields to be sorted by offset
        - discard field titles

        ``as_ctypes_type(np.dtype(ctype))`` will:

        - discard the class names of `ctypes.Structure`\ s and
          `ctypes.Union`\ s
        - convert single-element `ctypes.Union`\ s into single-element
          `ctypes.Structure`\ s
        - insert padding fields

        Examples
        --------
        Converting a simple dtype:

        >>> dt = np.dtype('int8')
        >>> ctype = np.ctypeslib.as_ctypes_type(dt)
        >>> ctype
        <class 'ctypes.c_byte'>

        Converting a structured dtype:

        >>> dt = np.dtype([('x', 'i4'), ('y', 'f4')])
        >>> ctype = np.ctypeslib.as_ctypes_type(dt)
        >>> ctype
        <class 'struct'>

        )r§   rD   rH   r[   r   r   r   r   Ï  s   6r   c                 C   sF   t | tjƒr|du rtdƒ‚t t| j|ƒ¡}t | |¡j} t	 
| ¡S )a‚  
        Create a numpy array from a ctypes array or POINTER.

        The numpy array shares the memory with the ctypes object.

        The shape parameter must be given if converting from a ctypes POINTER.
        The shape parameter is ignored if converting from a ctypes array

        Examples
        --------
        Converting a ctypes integer array:

        >>> import ctypes
        >>> ctypes_array = (ctypes.c_int * 5)(0, 1, 2, 3, 4)
        >>> np_array = np.ctypeslib.as_array(ctypes_array)
        >>> np_array
        array([0, 1, 2, 3, 4], dtype=int32)

        Converting a ctypes POINTER:

        >>> import ctypes
        >>> buffer = (ctypes.c_int * 5)(0, 1, 2, 3, 4)
        >>> pointer = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_int))
        >>> np_array = np.ctypeslib.as_array(pointer, (5,))
        >>> np_array
        array([0, 1, 2, 3, 4], dtype=int32)

        Nz=as_array() requires a shape argument when called on a pointer)rC   r$   Ú_PointerrF   r`   r…   Ú_type_r_   rX   rD   Úasarray)rQ   rL   Ú
p_arr_typer   r   r   r     s   ÿ
r   c                 C   sp   | j }|d rtdƒ‚|d dkrtdƒ‚|d \}}|r!tdƒ‚t|d ƒ}t||d	 ƒ}| |¡}| |_|S )
a  
        Create and return a ctypes object from a numpy array.  Actually
        anything that exposes the __array_interface__ is accepted.

        Examples
        --------
        Create ctypes object from inferred int ``np.array``:

        >>> inferred_int_array = np.array([1, 2, 3])
        >>> c_int_array = np.ctypeslib.as_ctypes(inferred_int_array)
        >>> type(c_int_array)
        <class 'c_long_Array_3'>
        >>> c_int_array[:]
        [1, 2, 3]

        Create ctypes object from explicit 8 bit unsigned int ``np.array`` :

        >>> exp_int_array = np.array([1, 2, 3], dtype=np.uint8)
        >>> c_int_array = np.ctypeslib.as_ctypes(exp_int_array)
        >>> type(c_int_array)
        <class 'c_ubyte_Array_3'>
        >>> c_int_array[:]
        [1, 2, 3]

        Ústrideszstrided arrays not supportedÚversioné   z,only __array_interface__ version 3 supportedÚdatazreadonly arrays unsupportedÚtypestrrL   )Ú__array_interface__rF   r   r…   Úfrom_addressÚ__keep)rQ   ÚaiÚaddrÚreadonlyÚctype_scalarÚresult_typeÚresultr   r   r   r   1  s   
r   )NNNNr;   )'rf   Ú__all__r   ÚnumpyrD   Únumpy._core.multiarrayr   r	   r$   r
   r   r   r   r   r   r   ÚobjectÚ_ndptr_baseÚnumpy._core._internalÚ_coreÚ	_internalÚnicÚ_getintp_ctypeÚc_void_pr4   r<   rA   rB   rW   rx   r   r…   r—   r�   r¥   r©   rÁ   r§   r   r   r   r   r   Ú<module>   sT    3ÿJ	
u	6	
9) �ª