o
    b3                     @   s   d Z ddlZddlmZ ddlmZmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZmZ ddlmZ eejejejejG d	d
 d
e	eZd
gZdS )z
Abstract file handle class
    N)implementer)error
interfacesmain)_ConsumerMixin_dataMustBeBytes	_LogOwner)iocpsupport)ERROR_HANDLE_EOFERROR_IO_PENDING)failurec                   @   sn  e Zd ZdZdZdZdZdZdZdZ	dZ
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d ZdZdZdZdZdZdZ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%d0d1 Z&d2d3 Z'd4d5 Z(dZ)dZ*dZ+d6Z,d7Z-dLd8d9Z.d:d; Z/d<d= Z0e12e3j4fd>d?Z5d@dA Z6dBdC Z7dDdE Z8dFdG Z9dHdI Z:dJdK Z;dS )M
FileHandlez<
    File handle that can read and write asynchronously
       i   FTr   Nc                 C   <   | j |  | js| jsd| _| j d| j| _d S d S d S NTr   )reactoraddActiveHandle_readScheduledreading	callLater_resumeReadingself r   G/usr/lib/python3/dist-packages/twisted/internet/iocpreactor/abstract.pystartReading(   s
   zFileHandle.startReadingc                 C       | j r| j   d | _ d| _d S NF)r   cancelr   r   r   r   r   stopReading.      

zFileHandle.stopReadingc                 C   s(   d | _ |  r| js|   d S d S d S N)r   _dispatchData_readScheduledInOSdoReadr   r   r   r   r   4   s   zFileHandle._resumeReadingc                 C   s   | j s| jS | j }|| j }| j|k r-| | j| j  |  jd7  _| js(dS | j|k s|| j }|r@| | j| d|  | jrl| jt| j }||| j k rW| jd= n||krlt| j| jk rl| j	t
| j d| _d| _ | jS )zt
        Dispatch previously read data. Return True if self.reading and we don't
        have any more data
           Fr   )	_readSizer   readBufferSize_readNextBufferdataReceived_readBuffersdynamicReadBufferslenmaxReadBuffersappend	bytearray)r   sizefull_buffers	remaindertotal_buffer_sizer   r   r   r"   9   s.   




zFileHandle._dispatchDatac                 C   s$   d| _ | |||r|   d S d S r   )r#   _handleReadr$   r   rcdataevtr   r   r   _cbReadY   s   zFileHandle._cbReadc                 C   s   | j rdS |s	|r|tjtfv r!| j|  | tt	j
 dS |r9| ttdtj|d|f  dS | jdks@J | jdksGJ || _|  S )zA
        Returns False if we should stop reading for now
        Fzread error -- %s (%s)unknownr   )disconnectederrno
WSAEDISCONr
   r   removeActiveHandlereadConnectionLostr   Failurer   CONNECTION_DONEconnectionLostr   ConnectionLost	errorcodegetr'   r)   r"   r6   r   r   r   r5   ^   s*   zFileHandle._handleReadc                 C   sR   t | j| }| j |_}| ||\}}|r|tkr d| _d S | ||| d S NT)	_iocpEventr:   r+   buffreadFromHandler   r#   r5   )r   r9   rJ   r7   numBytesReadr   r   r   r$   {   s   
zFileHandle.doReadc                 C      t  r!   NotImplementedError)r   bufflistr9   r   r   r   rK         zFileHandle.readFromHandlec                 C   s   t r!   rN   r   r8   r   r   r   r*         zFileHandle.dataReceivedc                 C      |  | d S r!   rC   r   reasonr   r   r   r@      s   zFileHandle.readConnectionLost    i   c                 C   s   d| _ |   d S rG   )_writeDisconnectingstartWritingr   r   r   r   loseWriteConnection      zFileHandle.loseWriteConnectionc                 C   s   d S r!   r   r   r   r   r   _closeWriteConnection   s   z FileHandle._closeWriteConnectionc                 C   rT   r!   rU   rV   r   r   r   writeConnectionLost   s   zFileHandle.writeConnectionLostc                 C   r   r   )r   r   _writeScheduledwritingr   _resumeWritingr   r   r   r   rZ      s
   zFileHandle.startWritingc                 C   r   r   )r_   r   r`   r   r   r   r   stopWriting   r    zFileHandle.stopWritingc                 C   s   d | _ |   d S r!   )r_   doWriter   r   r   r   ra      r\   zFileHandle._resumeWritingc                 C   s   |  |||r|   d S d S r!   )_handleWriterc   r   r7   numBytesWrittenr9   r   r   r   _cbWrite   s   zFileHandle._cbWritec                 C   s   | j s| jrdS |r | ttdtj	|d|f  dS |  j
|7  _
| j
t| jkrk| jskd| _d| _
|   | jdurQ| jrG| jrQd| _| j  dS | jr_| ttj dS | jrid| _|   dS dS )zA
        Returns false if we should stop writing for now
        Fzwrite error -- %s (%s)r;   rX   r   NT)r<   _writeDisconnectedrC   r   rA   r   rD   r=   rE   rF   offsetr-   
dataBuffer_tempDataLenrb   producerstreamingProducerproducerPausedresumeProducingdisconnectingr   rB   rY   r]   re   r   r   r   rd      sD   

	zFileHandle._handleWritec                 C   s   t | j| j | jk r#| j| jd  d| j | _d| _g | _d| _t| j	| }| jr=t
| j}|| jd   |_}n| j |_}| ||\}}|rZ|tkr\| ||| d S d S d S )NrX   r   )r-   rj   ri   
SEND_LIMITjoin_tempDataBufferrk   rH   rI   rg   
memoryviewrJ   writeToHandler   rd   )r   r9   sendViewrJ   r7   r8   r   r   r   rc      s    
zFileHandle.doWritec                 C   rM   r!   rN   )r   rJ   r9   r   r   r   ru      rQ   zFileHandle.writeToHandlec                 C   s   t | | jr
| jrdS |r>| j| |  jt|7  _| jdur8| jr8t| j	| j | j
kr8d| _| j  |   dS dS )zpReliably write some data.

        The data is buffered until his file descriptor is ready for writing.
        NT)r   	connectedrh   rs   r/   rk   r-   rl   rm   rj   writeBufferSizern   pauseProducingrZ   rR   r   r   r   write   s   
zFileHandle.writec                 C   s   |D ]}t | q| jr|r| jrd S | j| |D ]}|  jt|7  _q| jd urB| jrBt| j	| j | j
krBd| _| j  |   d S rG   )r   rw   rh   rs   extendrk   r-   rl   rm   rj   rx   rn   ry   rZ   )r   iovecir   r   r   writeSequence  s   

zFileHandle.writeSequenceUninitializedi   c                 C   s4   |sddl m} || _g | _d| _t| jg| _d S )Nr   )r   )twisted.internetr   rs   rk   r0   r(   r+   )r   r   r   r   r   __init__'  s   zFileHandle.__init__c                 C   sF   d| _ d| _| jdur| j  d| _|   |   | j|  dS )a  
        The connection was lost.

        This is called when the connection on a selectable object has been
        lost.  It will be called whether the connection was closed explicitly,
        an exception occurred in an event handler, or the other end of the
        connection closed it first.

        Clean up state here, but make sure to call back up to FileDescriptor.
        TFN)r<   rw   rl   stopProducingr   rb   r   r?   rV   r   r   r   rC   /  s   

zFileHandle.connectionLostc                 C   s   dS )Nr&   r   r   r   r   r   getFileHandleD  rS   zFileHandle.getFileHandlec                 C   sP   | j r$| js&| jr|   | j | | dS |   |   d| _dS dS dS )ad  
        Close the connection at the next available opportunity.

        Call this to cause this FileDescriptor to lose its connection.  It will
        first write any data that it has buffered.

        If there is data buffered yet to be written, this method will cause the
        transport to lose its connection as soon as it's done flushing its
        write buffer.  If you have a producer registered, the connection won't
        be closed until the producer is finished. Therefore, make sure you
        unregister your producer when it's finished, or the connection will
        never close.
        r%   N)rw   rp   rh   r   rb   rC   rZ   )r   	_connDoner   r   r   loseConnectionG  s   
zFileHandle.loseConnectionc                 C   s   |    |   dS )z
        Stop consuming data.

        This is called when a producer has lost its connection, to tell the
        consumer to go lose its connection (and break potential circular
        references).
        N)unregisterProducerr   r   r   r   r   stopConsumingc  s   zFileHandle.stopConsumingc                 C   s    | j r| js|   d S d S d S r!   )rw   rp   r   r   r   r   r   ro   p  s   zFileHandle.resumeProducingc                 C      |    d S r!   )r   r   r   r   r   ry   t     zFileHandle.pauseProducingc                 C   r   r!   )r   r   r   r   r   r   w  r   zFileHandle.stopProducingc                 C   rM   r!   rN   r   r   r   r   getHostz     zFileHandle.getHostc                 C   rM   r!   rN   r   r   r   r   getPeer~  r   zFileHandle.getPeerr!   )<__name__
__module____qualname____doc__r.   r(   r   r,   r)   r'   r   r#   r   r   r   r"   r:   r5   r$   rK   r*   r@   rj   ri   r`   r_   rY   rh   rx   r[   r]   r^   rZ   rb   ra   rg   rd   rc   ru   rz   r~   rw   r<   rp   logstrrq   r   rC   r   r   rA   r   rB   r   r   ro   ry   r   r   r   r   r   r   r   r      sl     -
r   )r   r=   zope.interfacer   r   r   r   r   twisted.internet.abstractr   r   r   twisted.internet.iocpreactorr	   rH   "twisted.internet.iocpreactor.constr
   r   twisted.pythonr   IPushProducer	IConsumer
ITransportIHalfCloseableDescriptorr   __all__r   r   r   r   <module>   s$     
l