U
    dR…f&  ã                   @   s~   d dl mZm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	 ej
dkpXej
 d¡ZG dd„ deƒZG d	d
„ d
eƒZdS )é    )Úabsolute_importÚdivisionNé   )ÚTTransportExceptionÚdarwinZfreebsdc                   @   sr   e Zd ZdZddddejddf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„ ZdS )ÚTSocketz&Socket implementation for client side.Né¸  c                 C   sr   |r|| _ n6|r*|| _d| _d| _d| _ nd| _|| _|| _d| _ || _|rT|d nd| _|rf|d n| j| _dS )ar  Initialize a TSocket

        TSocket can be initialized in 3 ways:
        * host + port. can configure to use AF_INET/AF_INET6
        * unix_socket
        * socket. should pass already opened socket here.

        @param host(str)    The host to connect to.
        @param port(int)    The (TCP) port to connect to.
        @param unix_socket(str) The filename of a unix socket to connect to.
        @param sock(socket)     Initialize with opened socket directly.
            If this param used, the host, port and unix_socket params will
            be ignored.
        @param socket_family(str) socket.AF_INET or socket.AF_INET6. only
            take effect when using host/port
        @param socket_timeout   socket timeout in ms
        @param connect_timeout  connect timeout in ms, only used in
            connection, will be set to socket_timeout if not set.
        Néè  )ÚsockÚunix_socketÚhostÚportÚsocket_familyÚsocket_timeoutÚconnect_timeout)Úselfr   r   r   r
   r   r   r   © r   ú>/tmp/pip-unpacked-wheel-jqs7l_7o/thriftpy2/transport/socket.pyÚ__init__   s     ÿzTSocket.__init__c                 C   sv   | j rt tjtj¡}n"t | jtj¡}| tjtjd¡ t 	ddd¡}| tj
tj|¡ | tj
tjd¡ || _d S )Nr   Úiir   )r   ÚsocketÚAF_UNIXÚSOCK_STREAMr   Ú
setsockoptÚIPPROTO_TCPÚTCP_NODELAYÚstructÚpackÚ
SOL_SOCKETÚ	SO_LINGERÚSO_KEEPALIVEr
   )r   Ú_sockZlingerr   r   r   Ú
_init_sock;   s    zTSocket._init_sockc                 C   s
   || _ d S ©N©r
   )r   r
   r   r   r   Ú
set_handleI   s    zTSocket.set_handlec                 C   s>   |r|dkr|d nd| _ | j | _| jdk	r:| j | j ¡ dS )zgBackward compat api, will bind the timeout to both connect_timeout
        and socket_timeout.
        r   r	   N)r   r   r
   Ú
settimeout)r   Úmsr   r   r   Úset_timeoutL   s    
zTSocket.set_timeoutc                 C   s
   t | jƒS r#   )Úboolr
   ©r   r   r   r   Úis_openV   s    zTSocket.is_openc              	   C   s   |   ¡  | jp| j| jf}z8| jr0| j | j¡ | j |¡ | jrP| j | j¡ W n8 t	j
tfk
rŠ   |  ¡  ttjdt|ƒ d‚Y nX d S )NzCould not connect to %s©ÚtypeÚmessage)r"   r   r   r   r   r
   r&   Úconnectr   r   ÚerrorÚOSErrorÚcloser   ZNOT_OPENÚstr©r   Úaddrr   r   r   ÚopenY   s    
þzTSocket.openc              
   C   s˜   z| j  |¡}W qz tjk
rt } zD|jtjkr8W Y ¢2q |jd tjkrbtrb|  	¡  d}W Y ¢
qzn‚ W 5 d }~X Y q X qzq t
|ƒdkr”ttjdd‚|S )Nr   Ú zTSocket read 0 bytesr,   )r
   Úrecvr   r0   ÚerrnoZEINTRÚargsÚ
ECONNRESETÚ
MAC_OR_BSDr2   Úlenr   ZEND_OF_FILE)r   ÚszÚbuffÚer   r   r   Úreadm   s     
ÿzTSocket.readc                 C   s   | j  |¡ d S r#   )r
   Úsendall)r   r?   r   r   r   Úwrite‡   s    zTSocket.writec                 C   s   d S r#   r   r*   r   r   r   ÚflushŠ   s    zTSocket.flushc                 C   s`   | j s
d S z| j  tj¡ W n tk
r0   Y nX z| j  ¡  W n tk
rT   Y nX d | _ d S r#   ©r
   Úshutdownr   Ú	SHUT_RDWRr1   r2   r*   r   r   r   r2      s    zTSocket.close)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚAF_INETr   r"   r%   r(   r+   r6   rA   rC   rD   r2   r   r   r   r   r      s      þ
(
r   c                   @   sH   e Zd ZdZdddejddfdd„Zdd„ Zd	d
„ Zdd„ Z	dd„ Z
dS )ÚTServerSocketz&Socket implementation for server side.Nr   é€   c                 C   sL   |r|| _ d| _d| _nd| _ || _|| _|| _|r<|d nd| _|| _dS )aE  Initialize a TServerSocket

        TSocket can be initialized in 2 ways:
        * host + port. can configure to use AF_INET/AF_INET6
        * unix_socket

        @param host(str)    The host to connect to
        @param port(int)    The (TCP) port to connect to
        @param unix_socket(str) The filename of a unix socket to connect to
        @param socket_family(str) socket.AF_INET or socket.AF_INET6. only
            take effect when using host/port
        @param client_timeout   client socket timeout
        @param backlog          backlog for server socket
        Nr	   )r   r   r   r   Úclient_timeoutÚbacklog)r   r   r   r   r   rO   rP   r   r   r   r       s    zTServerSocket.__init__c              
   C   s  | j rnt tjtj¡}z| | j ¡ W q~ tjtfk
rj } z |jd tj	krZt
 | j ¡ W 5 d }~X Y q~X nt | jtj¡}| tjtjd¡ ttdƒrîz| tjtjd¡ W n< tjk
rì } z|d tjtjfkrÚn‚ W 5 d }~X Y nX | d ¡ || _d S )Nr   r   ÚSO_REUSEPORT)r   r   r   r   r/   r0   r1   r:   r9   ZECONNREFUSEDÚosÚunlinkr   r   r   ÚSO_REUSEADDRÚhasattrrQ   ZENOPROTOOPTÚEINVALr&   r
   )r   r!   Úerrr   r   r   r"   ¿   s$     

zTServerSocket._init_sockc                 C   s8   |   ¡  | jp| j| jf}| j |¡ | j | j¡ d S r#   )r"   r   r   r   r
   ÚbindÚlistenrP   r4   r   r   r   rY   ×   s    zTServerSocket.listenc                 C   s*   | j  ¡ \}}| jr | | j¡ t|dS )Nr$   )r
   ÚacceptrO   r&   r   )r   ÚclientÚ_r   r   r   rZ   Þ   s    zTServerSocket.acceptc                 C   s`   | j s
d S z| j  tj¡ W n tk
r0   Y nX z| j  ¡  W n tk
rT   Y nX d | _ d S r#   rE   r*   r   r   r   r2   ä   s    zTServerSocket.close)rH   rI   rJ   rK   r   rL   r   r"   rY   rZ   r2   r   r   r   r   rM      s    þ
rM   )Ú
__future__r   r   r9   rR   r   r   Úsysr7   r   ÚplatformÚ
startswithr<   Úobjectr   rM   r   r   r   r   Ú<module>   s    