o
    fL*                     @   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_chatzThis 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   P/var/www/html/venv/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rt| j}|  }|s7| | j d| _nt	|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(