
Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­Â�Â­
<!DOCTYPE html>
<html>
3

  \@,  ã               @   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_chatz‡This 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j| ||ƒ d S )Nó    )Úac_in_bufferÚincomingr   Úproducer_fifoÚasyncoreÚ
dispatcherÚ__init__)ÚselfZsockÚmap© r   ú /usr/lib64/python3.6/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 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ƒ}| 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 | jƒ}W n: tk
r$   d S  tk
rJ } z| jƒ  d S d }~X nX t|tƒrh| jrhtt| j	ƒ}| j
| | _
�xV| j
�rÌt| j
ƒ}| jƒ }|sª| j| j
ƒ d| _
qxt|tƒ�r|}||k râ| j| j
ƒ d| _
| j| | _n2| j| j
d |… ƒ | j
|d … | _
d| _| jƒ  qxt|ƒ}| j
j|ƒ}|dk�rp|dk�rR| j| j
d |… ƒ | j
|| d … | _
| jƒ  qxt| j
|ƒ}|�r¸||k�r´| j| j
d | … ƒ | j
| d … | _
P qx| j| j
ƒ d| _
qxW 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   | j ƒ  d S )N)Úinitiate_send)r   r   r   r   Úhandle_writeº   s    zasync_chat.handle_writec             C   s   | j ƒ  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	j
|||| … ƒ qBW n| j	j
|ƒ | 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 j|ƒ | 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   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 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 o| j�r| j d }|s<| j d= |d kr<| jƒ  d S | j}y|d |… }W n8 tk
rŠ   |jƒ }|r|| j j|ƒ n| j d= wY nX t|tƒr¨| j	r¨t
|| jƒ}y| j|ƒ}W n tk
rÒ   | jƒ  d S X |�r|t|ƒk sô|t|ƒk �r||d … | j d< n| j d= d S W d S )Nr   )r   r<   r1   r6   r4   Ú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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$   r6   r   r   r
   r   r   r   r   r    r!   r-   r/   r1   r9   r:   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   s6   t |ƒd }x$|r0| j|d |… ƒ r0|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    \ 