o
    éT•j -  ã                   @   s^   d Z ddlZddlmZ ddlmZ ededd� 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)Údeque)ÚwarnzlThe asynchat module is deprecated and will be removed in Python 3.12. The recommended replacement is asyncioé   )Ú
stacklevelc                   @   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 | ||¡ d S ©Nó    )Úac_in_bufferÚincomingr   Úproducer_fifoÚasyncoreÚ
dispatcherÚ__init__)ÚselfÚsockÚmap© r   ú/usr/lib/python3.10/asynchat.pyr   K   s   zasync_chat.__init__c                 C   ó   t dƒ‚©Nzmust be implemented in subclass©ÚNotImplementedError©r   Údatar   r   r   Úcollect_incoming_dataY   ó   z async_chat.collect_incoming_datac                 C   s   | j  |¡ d S ©N)r
   Úappendr   r   r   r   Ú_collect_incoming_data\   s   z!async_chat._collect_incoming_datac                 C   s   d  | j¡}| jd d …= |S r   )Újoinr
   )r   Údr   r   r   Ú	_get_data_   s   zasync_chat._get_datac                 C   r   r   r   ©r   r   r   r   Úfound_terminatord   r   zasync_chat.found_terminatorc                 C   sB   t |tƒr| jrt|| jƒ}nt |tƒr|dk rt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   Útermr   r   r   Úset_terminatorg   s
   
zasync_chat.set_terminatorc                 C   s   | j S r   )r+   r"   r   r   r   Úget_terminatorr   s   zasync_chat.get_terminatorc                 C   s¼  z|   | j¡}W n ty   Y d S  ty   |  ¡  Y d S w t|tƒr.| jr.tt| j	ƒ}| j
| | _
| j
rÜt| j
ƒ}|  ¡ }|sL|  | j
¡ d| _
n‹t|tƒr�|}||k rg|  | j
¡ d| _
| j| | _np|  | j
d |… ¡ | j
|d … | _
d| _|  ¡  nVt|ƒ}| j
 |¡}|dkr¬|dkr�|  | j
d |… ¡ | j
|| d … | _
|  ¡  n+t| j
|ƒ}|rÎ||krÌ|  | j
d | … ¡ | j
| d … | _
d S |  | j
¡ d| _
| j
s7d S d S )Nr   r   éÿÿÿÿ)Ú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   Úlbr+   ÚnÚterminator_lenÚindexr   r   r   Úhandle_readz   sV   þ


	
Ízasync_chat.handle_readc                 C   ó   |   ¡  d S r   )Úinitiate_sendr"   r   r   r   Úhandle_writeÂ   ó   zasync_chat.handle_writec                 C   r=   r   )Úcloser"   r   r   r   Úhandle_closeÅ   r@   zasync_chat.handle_closec                 C   sx   t |tttfƒstdt|ƒƒ‚| j}t|ƒ|kr0tdt|ƒ|ƒD ]}| j	 
|||| … ¡ q n| j	 
|¡ |  ¡  d S )Nz#data argument must be byte-ish (%r)r   )r$   r'   Ú	bytearrayÚ
memoryviewÚ	TypeErrorÚtypeÚac_out_buffer_sizer5   Úranger   r   r>   )r   r   ÚsabsÚir   r   r   ÚpushÈ   s   ÿÿzasync_chat.pushc                 C   s   | j  |¡ |  ¡  d S r   )r   r   r>   )r   Ú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   Ú	connectedr"   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  | j r„| jr†| j d }|s| j d= |d u r|  ¡  d S | j}z|d |… }W n ty@   | ¡ }|r:| j  |¡ n| j d= Y q w t|tƒrO| j	rOt
|| jƒ}z|  |¡}W n tyd   |  ¡  Y d S w |r‚|t|ƒk ss|t|ƒk r~||d … | j d< d S | j d= d S d S d S )Nr   )r   rP   rB   rG   rE   ÚmoreÚ
appendleftr$   r%   r&   r'   r(   Úsendr3   r4   r5   )r   ÚfirstÚobsr   Únum_sentr   r   r   r>   è   s@   
úþþÛzasync_chat.initiate_sendc                 C   s    d| _ | jd d …= | j ¡  d S r   )r	   r
   r   Úclearr"   r   r   r   Údiscard_buffers  s   zasync_chat.discard_buffers)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r1   rG   r&   r(   r   r   r   r!   r#   r-   r.   r<   r?   rB   rK   rM   rO   rQ   rR   r>   rZ   r   r   r   r   r   <   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 r   )r   Úbuffer_size)r   r   ra   r   r   r   r     s   
zsimple_producer.__init__c                 C   sF   t | jƒ| jkr| jd | j… }| j| jd … | _|S | j}d| _|S r   )r5   r   ra   )r   Úresultr   r   r   rS     s   zsimple_producer.moreN)r`   )r[   r\   r]   r   rS   r   r   r   r   r_     s    
r_   c                 C   sD   t |ƒd }|r |  |d |… ¡s |d8 }|r |  |d |… ¡r|S )NrN   )r5   Úendswith)ÚhaystackÚneedleÚlr   r   r   r7   7  s
   ÿr7   )r^   r   Úcollectionsr   Úwarningsr   ÚDeprecationWarningr   r   r_   r7   r   r   r   r   Ú<module>   s   ü \ 