o
    r¨ÊhL*  ã                   @   sj   d Z ddlZddlmZ ddlmZ ddlmZ G dd„ dejƒZ	G dd	„ d	ƒ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)Úasyncore_25)Úlong)Úas_bytesc                   @   sš   e 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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   Nc                 C   s(   d| _ d| _tƒ | _tj | ||¡ d S ©Nó    )Úac_in_bufferÚac_out_bufferÚfifoÚproducer_fifoÚasyncoreÚ
dispatcherÚ__init__)ÚselfÚconnÚmap© r   úO/var/www/html/env/lib/python3.10/site-packages/supervisor/medusa/asynchat_25.pyr   ?   s   zasync_chat.__init__c                 C   ó   t dƒ‚©Nzmust be implemented in subclass©ÚNotImplementedError©r   Údatar   r   r   Úcollect_incoming_dataE   ó   z async_chat.collect_incoming_datac                 C   r   r   r   ©r   r   r   r   Úfound_terminatorH   r   zasync_chat.found_terminatorc                 C   s
   || _ dS )zRSet the input delimiter.  Can be a fixed string of any length, an integer, or NoneN©Ú
terminator)r   Útermr   r   r   Úset_terminatorK   s   
zasync_chat.set_terminatorc                 C   s   | j S ©Nr   r   r   r   r   Úget_terminatorO   s   zasync_chat.get_terminatorc                 C   sž  z|   | j¡}W n tjy   |  ¡  Y d S w |  j|7  _| jrÍt| jƒ}|  ¡ }|s7|  | j¡ d| _n‘t	|t
ƒsAt	|tƒrr|}||k rX|  | j¡ d| _|  j|8  _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s"d S d S )Nr   r   éÿÿÿÿ)ÚrecvÚac_in_buffer_sizeÚsocketÚerrorÚhandle_errorr   Úlenr#   r   Ú
isinstanceÚintr   r   r   ÚfindÚfind_prefix_at_end)r   r   Úlbr   ÚnÚterminator_lenÚindexr   r   r   Úhandle_readW   sN   þ

	
Ïzasync_chat.handle_readc                 C   ó   |   ¡  d S r"   )Úinitiate_sendr   r   r   r   Úhandle_write˜   ó   zasync_chat.handle_writec                 C   r4   r"   )Úcloser   r   r   r   Úhandle_close›   r7   zasync_chat.handle_closec                 C   s$   t |ƒ}| j t|ƒ¡ |  ¡  d S r"   )r   r   ÚpushÚsimple_producerr5   r   r   r   r   r:   ž   s   zasync_chat.pushc                 C   s   | j  |¡ |  ¡  d S r"   )r   r:   r5   )r   Úproducerr   r   r   Úpush_with_producer£   s   zasync_chat.push_with_producerc                 C   s   t | jƒ| jkS )z4predicate for inclusion in the readable for select())r*   r   r&   r   r   r   r   Úreadable§   ó   zasync_chat.readablec                 C   s   | j dko| j ¡ o| j S )z4predicate for inclusion in the writable for select()r   )r	   r   Úis_emptyÚ	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µ   r?   zasync_chat.close_when_donec                 C   sŽ   	 t | jƒrD| j ¡ }|d u r| js| j ¡  |  ¡  d S t|tƒr0| j ¡  |  j|7  _d S | ¡ }|r>| j| | _d S | j ¡  nd S qr"   )	r*   r   Úfirstr	   Úpopr8   r+   ÚbytesÚmore)r   Úpr   r   r   r   Úrefill_buffer»   s&   




ëzasync_chat.refill_bufferc                 C   s„   | j }t| jƒ|k r|  ¡  | jr>| jr@z|  | jd |… ¡}|r,| j|d … | _W d S W d S  tjy=   |  ¡  Y d S w d S d S r"   )	Úac_out_buffer_sizer*   r	   rI   rA   Úsendr'   r(   r)   )r   ÚobsÚnum_sentr   r   r   r5   Ó   s   ÿþùzasync_chat.initiate_sendc                 C   s*   d| _ d| _| jr| j ¡  | js	d S d S r   )r   r	   r   rE   r   r   r   r   Údiscard_buffersä   s
   
ÿzasync_chat.discard_buffers)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r&   rJ   r   r   r   r!   r#   r3   r6   r9   r:   r=   r>   rB   rC   rI   r5   rN   r   r   r   r   r   6   s(    
A
r   c                   @   s   e Zd Zddd„Zdd„ ZdS )r;   é   c                 C   s   || _ || _d S r"   )r   Úbuffer_size)r   r   rT   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   )r*   r   rT   )r   Úresultr   r   r   rG   ò   s   zsimple_producer.moreN)rS   )rO   rP   rQ   r   rG   r   r   r   r   r;   ì   s    
r;   c                   @   s>   e Zd Zddd„Zdd„ Zdd„ Zdd	„ Zd
d„ Zdd„ ZdS )r
   Nc                 C   s   |sg | _ d S || _ d S r"   ©Úlist)r   rW   r   r   r   r   ý   s   

zfifo.__init__c                 C   s
   t | jƒS r"   )r*   rW   r   r   r   r   Ú__len__  ó   
zfifo.__len__c                 C   s
   | j g kS r"   rV   r   r   r   r   r@     rY   zfifo.is_emptyc                 C   s
   | j d S )Nr   rV   r   r   r   r   rD   	  rY   z
fifo.firstc                 C   s   | j  |¡ d S r"   )rW   Úappendr   r   r   r   r:     s   z	fifo.pushc                 C   s   | j rd| j  d¡fS dS )Né   r   )r   N)rW   rE   r   r   r   r   rE     s   zfifo.popr"   )	rO   rP   rQ   r   rX   r@   rD   r:   rE   r   r   r   r   r
   ü   s    
r
   c                 C   sD   t |ƒd }|r |  |d |… ¡s |d8 }|r |  |d |… ¡r|S )Nr[   )r*   Úendswith)ÚhaystackÚneedleÚlr   r   r   r.   $  s
   ÿr.   )rR   r'   Úsupervisor.medusar   r   Úsupervisor.compatr   r   r   r   r;   r
   r.   r   r   r   r   Ú<module>   s    7(