U e5d@, ã @ sD d Z ddlZddlmZ G dd„ dejƒZG dd„ dƒZdd „ ZdS ) 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 Zd ZdZdZdZdZdZd(dd„Zdd „ Z d d„ Z dd „ Zdd„ Zdd„ Z dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ ZdS ))Ú 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 zlatin-1Nc C s( d| _ g | _tƒ | _tj | ||¡ d S ©Nó )Úac_in_bufferÚincomingr Ú producer_fifoÚasyncoreÚ dispatcherÚ__init__)ÚselfZsockÚmap© r ú /usr/lib64/python3.8/asynchat.pyr C s zasync_chat.__init__c C s t dƒ‚d S ©Nzmust be implemented in subclass©ÚNotImplementedError©r Údatar r r Úcollect_incoming_dataQ s z async_chat.collect_incoming_datac C s | j |¡ d S ©N)r Úappendr r r r Ú_collect_incoming_dataT s z!async_chat._collect_incoming_datac C s d | j¡}| jd d …= |S r )Újoinr )r Údr r r Ú _get_dataW s zasync_chat._get_datac C s t dƒ‚d S r r ©r r r r Úfound_terminator\ s zasync_chat.found_terminatorc C sB t |tƒr| jrt|| jƒ}nt |tƒr8|dk r8tdƒ‚|| _dS )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 Ztermr r r Úset_terminator_ s zasync_chat.set_terminatorc C s | j S r )r% r r r r Úget_terminatorj s zasync_chat.get_terminatorc C sØ z| | j¡}W nD tk r& Y d S tk rT } z| ¡ W Y ¢d S d }~X Y nX t|tƒrr| jrrtt| j ƒ}| j | | _ | j �rÔt| j ƒ}| ¡ }|s°| | j ¡ d| _ q~t|tƒ�r|}||k rè| | j ¡ d| _ | j| | _n2| | j d |… ¡ | j |d … | _ d| _| ¡ q~t|ƒ}| j |¡}|dk�rv|dk�rX| | j d |… ¡ | j || d … | _ | ¡ q~t| j |ƒ}|�rÀ||k�rÔ| | j d | … ¡ | j | d … | _ �qÔq~| | j ¡ d| _ q~d S )Nr r éÿÿÿÿ)ZrecvÚ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 ZwhyZlbr% ÚnZterminator_lenÚindexr r r Úhandle_readr sR zasync_chat.handle_readc C s | ¡ d S r )Ú initiate_sendr r r r Úhandle_writeº s zasync_chat.handle_writec C s | ¡ d S r )Úcloser r r r Úhandle_close½ s zasync_chat.handle_closec C sx t |tttfƒstdt|ƒƒ‚| j}t|ƒ|kr`tdt|ƒ|ƒ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_sizer- Úranger r r3 )r r ZsabsÚir r r ÚpushÀ s ÿzasync_chat.pushc C s | j |¡ | ¡ d S r )r r r3 )r Zproducerr r r Úpush_with_producerÌ s zasync_chat.push_with_producerc C s dS )z4predicate for inclusion in the readable for select()é r r r r r ÚreadableÐ s zasync_chat.readablec C s | j p| j S )z4predicate for inclusion in the writable for select())r Ú connectedr r r r ÚwritableØ s zasync_chat.writablec C s | j d¡ dS )zAautomatically close this channel once the outgoing queue is emptyN)r r r r r r Úclose_when_doneÜ s zasync_chat.close_when_donec C s | j �r| j�r| j d }|s:| j d= |d kr:| ¡ d S | j}z|d |… }W n: tk rŠ | ¡ }|rz| j |¡ n| j d= Y q Y nX t|tƒr¨| j r¨t || jƒ}z| |¡}W n t k rÔ | ¡ Y d S X |�r|t|ƒk sö|t|ƒk �r ||d … | j d<