U
    luf,                     @   s  d Z ddlZddlmZ ddlmZ dd  ZZdd Z	d	d Z
d
d Zdd Zdd Zdd Zdd Zdd ZeddkZe ZddlZddlmZmZ ddlmZmZmZ ddlmZ ddlm Z  dddZ!d ddZ"d!ddZ#G dd dZ$ddgZ%dS )"zzmq Socket class    N   )ffi)libc                 C   s   t d| S )Nzsize_t*)r   newlength r   ;/tmp/pip-unpacked-wheel-h6ekxre8/zmq/backend/cffi/socket.py<lambda>       r
   c                   C   s   t dtt dfS Nz	uint64_t*Zuint64_tr   r   nspsizeofr   r   r   r	   r
      r   c                   C   s   t dtt dfS Nzint64_t*Zint64_tr   r   r   r   r	   r
      r   c                   C   s   t dtt dfS Nzint*intr   r   r   r   r	   r
      r   c                 C   s    t d|  tt d|  fS )Nchar[%d]charr   r   r   r   r	   r
      s    c                 C   s   t d| t dfS r   r   r   r   valr   r   r	   r
      r   c                 C   s   t d| t dfS r   r   r   r   r   r	   r
      r   c                 C   s   t d| t dfS r   r   r   r   r   r	   r
      r   c                 C   s"   t d|d  | t d| fS )Nr   r   r   r   )r   r   r   r   r	   r
      s    ZZMQ_FD_T   )SocketOption_OptType)ZMQError	_check_rc_check_version)Frame)_retry_sys_callc                 C   sH   t | dtj}|tjks&tr,|tjkr,t S |tjkr>t|S t	 S d S N	_opt_type)
getattrr   r   int64ZMQ_FD_64BITfdnew_int64_pointerbytesnew_binary_datanew_int_pointer)optionr   opt_typer   r   r	   new_pointer_from_opt)   s    
r,   c                 C   s\   zt | } W n tk
r&   tj}Y nX | j}|tjkrLt||d d  S t|d S d S )Nr   )r   
ValueErrorr   r   r!   r'   r   buffer)r*   Zopt_pointerr   r+   r   r   r	   value_from_opt_pointer5   s    
r/   c                 C   sN   t | dtj}|tjks&tr.|tjkr.t|S |tjkrBt||S t	|S d S r    )
r"   r   r   r#   r$   r%   value_int64_pointerr'   value_binary_datavalue_int_pointer)r*   valuer   r+   r   r   r	   initialize_opt_pointerF   s    

r4   c                   @   s   e Zd ZdZdZdZdZdZdZdZ	d&ddZ
edd Zdd	 Zed
d Zd'ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd(ddZd)d!d"Zd*d$d%ZdS )+SocketNFr   c                 C   sf   |d krt j}|| _|| _|r4td|| _d| _nd| _t	|j
|| _| jtjkr\t d| _d S )Nzvoid *TF)zmqZCOPY_THRESHOLDcopy_thresholdcontextr   cast_zmq_socket_shadowCZ
zmq_socketZ_zmq_ctxNULLr   _closed)selfr8   socket_typeZshadowr7   r   r   r	   __init__Y   s    zSocket.__init__c                 C   s   t td| jS )z+The address of the underlying libzmq socketZsize_t)r   r   r9   r:   r?   r   r   r	   
underlyingi   s    zSocket.underlyingc              
   C   sn   | j r
dS z| tj W nN tk
rh } z0|jtjkrHd| _ W Y dS |jtjkrVn W 5 d}~X Y nX dS )zthorough check of whether the socket has been closed,
        even if by another entity (e.g. ctx.destroy).

        Only used by the `closed` property.

        returns True if closed, False otherwise
        TNF)r>   getr6   ZTYPEr   errnoENOTSOCKZETERM)r?   er   r   r	   _check_closed_deepn   s    
zSocket._check_closed_deepc                 C   s   |   S )N)rH   rB   r   r   r	   closed   s    zSocket.closedc                 C   sZ   d}| j sFt| drF| jd k	r@|d k	r4| tj| t| j}d| _ |dk rVt| d S )Nr   r:   T)	r>   hasattrr:   setr6   ZLINGERr<   Z	zmq_closer   )r?   Zlingerrcr   r   r	   close   s    
zSocket.closec                 C   s   t |tr|d}n|}t |tr.|d}t| j|}|dk rtrt	 t
jkr|ddd }d|t}tt	 |dnDt	 t
jkr|ddd }d| d	}tt	 |dnt| d S )
Nutf8r   z://r   zJipc path "{}" is longer than {} characters (sizeof(sockaddr_un.sun_path)).)msgz(No such file or directory for ipc path "z".)
isinstancestrencoder'   decoder<   Zzmq_bindr:   IPC_PATH_MAX_LENZ	zmq_errno	errno_modZENAMETOOLONGsplitformatr   ENOENTr   )r?   addressZ	address_brL   pathrP   r   r   r	   bind   s(    


 zSocket.bindc                 C   s8   t dd t|tr|d}t| j|}t| d S )N      unbindrN   )r   rQ   rR   rS   r<   Z
zmq_unbindr:   r   r?   rZ   rL   r   r   r	   r`      s
    


zSocket.unbindc                 C   s.   t |tr|d}t| j|}t| d S )NrN   )rQ   rR   rS   r<   Zzmq_connectr:   r   ra   r   r   r	   connect   s    

zSocket.connectc                 C   s8   t dd t|tr|d}t| j|}t| d S )Nr]   
disconnectrN   )r   rQ   rR   rS   r<   Zzmq_disconnectr:   r   ra   r   r   r	   rc      s
    


zSocket.disconnectc                 C   s   d }t |trtdzt|}W n tk
r<   tj}Y nX |j}t |trl|tjkrdtd| t	|}t
|||\}}ttj| j|td|| d S )Nzunicode not allowed, use bytesznot a bytes sockopt: %szvoid*)rQ   rR   	TypeErrorr   r-   r   r   r!   r'   lenr4   r   r<   Zzmq_setsockoptr:   r   r9   )r?   r*   r3   r   r+   c_value_pointerZc_sizetr   r   r	   rK      s(    



z
Socket.setc                 C   s   zt |}W n tk
r&   tj}Y nX |j}t|dd\}}ttj| j	||| |d }t
|||}|tj jkr|tjkr|dr|d d }|S )N   r   r       rO   )r   r-   r   r   r!   r,   r   r<   Zzmq_getsockoptr:   r/   r6   Z
ROUTING_IDr'   endswith)r?   r*   r+   rf   Zc_sizet_pointerszvr   r   r	   rD      s.        
z
Socket.getc                 C   s   t d}t|ts t| }t d|}t|t|}t	| t
t||t| ttj|| j| t|}t	| dS )zSend a copy of a bufferable
zmq_msg_t*zchar[]N)r   r   rQ   r'   
memoryviewtobytesr<   Zzmq_msg_init_sizere   r   Zmemcpyzmq_msg_datar   zmq_msg_sendr:   zmq_msg_close)r?   bufflagszmq_msgZ	c_messagerL   Zrc2r   r   r	   
_send_copy   s    


zSocket._send_copyc                 C   s2   |  }|j}ttj|| j| |j}|  |S )z1Send a Frame on this socket in a non-copy manner.)Z	fast_copyrt   r   r<   rp   r:   trackerrM   )r?   framers   Z
frame_copyrt   rv   r   r   r	   _send_frame  s    zSocket._send_framec           	      C   s   t |trtd|r,t |ts,| ||S d}t |trR|rL|jsLtd|}n@| jr~t|}|j	| jk r~| || t
jS t||| jd}d}| ||}|r|  |S d S )Nz.Message must be in bytes, not a unicode objectFzNot a tracked message)trackr7   T)rQ   rR   rd   r   ru   rv   r-   r7   rm   nbytesr6   Z_FINISHED_TRACKERrx   rM   )	r?   datars   copyry   Zclose_framerw   rr   rv   r   r   r	   send  s(    


zSocket.sendTc           	      C   s   |rt d}t| ntj|d}|j}zttj|| j	| W n$ t
k
rf   |r`t|  Y nX |sp|S t t|t|}|d d  }t|}t| |S )Nrl   )ry   )r   r   r<   Zzmq_msg_initr6   r   rt   r   Zzmq_msg_recvr:   	Exceptionrq   r.   ro   Zzmq_msg_sizer   )	r?   rs   r|   ry   rt   rw   _bufferZ_bytesrL   r   r   r	   recv.  s$    


zSocket.recvrO   c                 C   sN   t dd |dk rtj}|dkr&tj}t|tr:|d}t	| j
|| dS )a   s.monitor(addr, flags)

        Start publishing socket events on inproc.
        See libzmq docs for zmq_monitor for details.

        Note: requires libzmq >= 3.2

        Parameters
        ----------
        addr : str
            The inproc url used for monitoring. Passing None as
            the addr will cause an existing socket monitor to be
            deregistered.
        events : int [default: zmq.EVENT_ALL]
            The zmq event bitmask for which events will be sent to the monitor.
        r]   monitorr   NrN   )r   r6   Z	EVENT_ALLr   r=   rQ   rR   rS   r<   Zzmq_socket_monitorr:   )r?   addreventsr   r   r	   r   F  s    


zSocket.monitor)NNr   N)N)r   FF)r   TF)rO   )__name__
__module____qualname__r8   r@   r:   r>   Z_refr;   r7   rA   propertyrC   rH   rI   rM   r\   r`   rb   rc   rK   rD   ru   rx   r}   r   r   r   r   r   r	   r5   P   s2   





r5   rU   )r   )r   )r   )&__doc__rE   rV   Z_cffir   r   r<   r   Znew_sizet_pointerZnew_uint64_pointerr&   r)   r(   Zvalue_uint64_pointerr0   r2   r1   r   r$   Zget_ipc_path_max_lenrU   r6   Zzmq.constantsr   r   Z	zmq.errorr   r   r   messager   utilsr   r,   r/   r4   r5   __all__r   r   r   r	   <module>   s4   



  