o
    f -                     @   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_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__)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
rt| j
}|  }|sL| | j
 d| _
nt|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    \ 