B
    \ c@,                 @   sD   d Z ddlZddlmZ G dd dejZG dd dZdd	 ZdS )
a  A class supporting chat-style (command/response) protocols.

This class adds support for 'chat' style protocols - where one side
sends a 'command', and the other sends a response (examples would be
the common internet protocols - smtp, nntp, ftp, etc..).

The handle_read() method looks at the input stream for the current
'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n'
for multi-line output), calling self.found_terminator() on its
receipt.

for example:
Say you build an async nntp client using this class.  At the start
of the connection, you'll have self.terminator set to '\r\n', in
order to process the single-line greeting.  Just before issuing a
'LIST' command you'll set it to '\r\n.\r\n'.  The output of the LIST
command will be accumulated (using your own 'collect_incoming_data'
method) up to the terminator, and then control will be returned to
you - by calling your self.found_terminator() method.
    N)dequec               @   s   e Zd ZdZdZdZdZ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 Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' ZdS ))
async_chatzThis is an abstract class.  You must derive from this class, and add
    the two methods collect_incoming_data() and found_terminator()i   r   zlatin-1Nc             C   s(   d| _ g | _t | _tj| || d S )N    )ac_in_bufferincomingr   producer_fifoasyncore
dispatcher__init__)selfZsockmap r   lib/python3.7/asynchat.pyr
   C   s    zasync_chat.__init__c             C   s   t dd S )Nzmust be implemented in subclass)NotImplementedError)r   datar   r   r   collect_incoming_dataQ   s    z async_chat.collect_incoming_datac             C   s   | j | d S )N)r   append)r   r   r   r   r   _collect_incoming_dataT   s    z!async_chat._collect_incoming_datac             C   s   d | j}| jd d = |S )Nr   )joinr   )r   dr   r   r   	_get_dataW   s    zasync_chat._get_datac             C   s   t dd S )Nzmust be implemented in subclass)r   )r   r   r   r   found_terminator\   s    zasync_chat.found_terminatorc             C   sB   t |tr| jrt|| j}nt |tr8|dk r8td|| _dS )zdSet the input delimiter.

        Can be a fixed string of any length, an integer, or None.
        r   z-the number of received bytes must be positiveN)
isinstancestruse_encodingbytesencodingint
ValueError
terminator)r   Ztermr   r   r   set_terminator_   s
    zasync_chat.set_terminatorc             C   s   | j S )N)r   )r   r   r   r   get_terminatorj   s    zasync_chat.get_terminatorc          
   C   s  y|  | j}W n< tk
r$   d S  tk
rL } z|   d S d }~X Y nX t|trj| jrjtt| j	}| j
| | _
xV| j
rt| j
}|  }|s| | j
 d| _
qzt|tr|}||k r| | j
 d| _
| j| | _n2| | j
d |  | j
|d  | _
d| _|   qzt|}| j
|}|dkrr|dkrT| | j
d |  | j
|| d  | _
|   qzt| j
|}|r||kr| | j
d |   | j
| d  | _
P qz| | j
 d| _
qzW d S )Nr   r   )Zrecvac_in_buffer_sizeBlockingIOErrorOSErrorhandle_errorr   r   r   r   r   r   lenr!   r   r   r   r   findfind_prefix_at_end)r   r   ZwhyZlbr   nZterminator_lenindexr   r   r   handle_readr   sR    

	



zasync_chat.handle_readc             C   s   |    d S )N)initiate_send)r   r   r   r   handle_write   s    zasync_chat.handle_writec             C   s   |    d S )N)close)r   r   r   r   handle_close   s    zasync_chat.handle_closec             C   s|   t |tttfstdt|| j}t||krdx>tdt||D ]}| j	
||||   qBW n| j	
| |   d S )Nz#data argument must be byte-ish (%r)r   )r   r   	bytearray
memoryview	TypeErrortypeac_out_buffer_sizer'   ranger   r   r-   )r   r   Zsabsir   r   r   push   s    
zasync_chat.pushc             C   s   | j | |   d S )N)r   r   r-   )r   Zproducerr   r   r   push_with_producer   s    zasync_chat.push_with_producerc             C   s   dS )z4predicate for inclusion in the readable for select()   r   )r   r   r   r   readable   s    zasync_chat.readablec             C   s   | j p| j S )z4predicate for inclusion in the writable for select())r   	connected)r   r   r   r   writable   s    zasync_chat.writablec             C   s   | j d dS )zAautomatically close this channel once the outgoing queue is emptyN)r   r   )r   r   r   r   close_when_done   s    zasync_chat.close_when_donec             C   s  x| j r| jr| j d }|s>| j d= |d kr>|   d S | j}y|d | }W n8 tk
r   | }|r~| j | n| j d= wY nX t|tr| j	rt
|| j}y| |}W n tk
r   |   d S X |r|t|k s|t|k r
||d  | j d< n| j d= d S W d S )Nr   )r   r<   r0   r5   r3   more
appendleftr   r   r   r   r   sendr%   r&   r'   )r   firstZobsr   Znum_sentr   r   r   r-      s8    
zasync_chat.initiate_sendc             C   s    d| _ | jd d = | j  d S )Nr   )r   r   r   clear)r   r   r   r   discard_buffers  s    zasync_chat.discard_buffers)NN)__name__
__module____qualname____doc__r#   r5   r   r   r
   r   r   r   r   r    r!   r,   r.   r0   r8   r9   r;   r=   r>   r-   rD   r   r   r   r   r   4   s,   
H(r   c               @   s   e Zd ZdddZdd ZdS )simple_producer   c             C   s   || _ || _d S )N)r   buffer_size)r   r   rK   r   r   r   r
     s    zsimple_producer.__init__c             C   sJ   t | j| jkr6| jd | j }| j| jd  | _|S | j}d| _|S d S )Nr   )r'   r   rK   )r   resultr   r   r   r?     s    zsimple_producer.moreN)rJ   )rE   rF   rG   r
   r?   r   r   r   r   rI     s   
rI   c             C   s4   t |d }x"|r.| |d | s.|d8 }qW |S )Nr:   )r'   endswith)ZhaystackZneedlelr   r   r   r)   /  s    r)   )rH   r   collectionsr   r	   r   rI   r)   r   r   r   r   <module>/   s    \ 