[1.@sqdZddlZddlmZGdddejZGdddZGdd d Zd d ZdS) aA 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@seZdZdZdZdZdZdZddddZdd Z d d Z d d Z ddZ ddZ ddZddZddZddZddZddZddZd d!Zd"d#Zd$d%Zd&d'ZdS)( async_chatzThis is an abstract class. You must derive from this class, and add the two methods collect_incoming_data() and found_terminator()irzlatin-1NcCs8d|_g|_t|_tjj|||dS)N) ac_in_bufferincomingr producer_fifoasyncore dispatcher__init__)selfZsockmapr /usr/lib/python3.4/asynchat.pyr Cs   zasync_chat.__init__cCstddS)Nzmust be implemented in subclass)NotImplementedError)r datar r rcollect_incoming_dataQsz async_chat.collect_incoming_datacCs|jj|dS)N)rappend)r rr r r_collect_incoming_dataTsz!async_chat._collect_incoming_datacCs&dj|j}|jdd=|S)Nr)joinr)r dr r r _get_dataWszasync_chat._get_datacCstddS)Nzmust be implemented in subclass)r)r r r rfound_terminator\szasync_chat.found_terminatorcCsdt|tr-|jr-t||j}n*t|trW|dkrWtdn||_dS)zdSet the input delimiter. Can be a fixed string of any length, an integer, or None. rz-the number of received bytes must be positiveN) isinstancestr use_encodingbytesencodingint ValueError terminator)r Ztermr r rset_terminator_s zasync_chat.set_terminatorcCs|jS)N)r)r r r rget_terminatorjszasync_chat.get_terminatorcCsry|j|j}WnHtk r.dSYn3tk r`}z|jdSWYdd}~XnXt|tr|jrtt|j }n|j ||_ x|j rmt |j }|j }|s|j |j d|_ qt|trz|}||kr4|j |j d|_ |j||_qj|j |j d||j |d|_ d|_|jqt |}|j j|}|dkr|dkr|j |j d|n|j ||d|_ |jqt|j |}|rQ||krM|j |j d| |j | d|_ nPq|j |j d|_ qWdS)Nrr)Zrecvac_in_buffer_sizeBlockingIOErrorOSError handle_errorrrrrrrlenr!rrrrfindfind_prefix_at_end)r rZwhyZlbrnZterminator_lenindexr r r handle_readrsR             zasync_chat.handle_readcCs|jdS)N) initiate_send)r r r r handle_writeszasync_chat.handle_writecCs|jdS)N)close)r r r r handle_closeszasync_chat.handle_closecCst|tttfs0tdt|n|j}t||krxQtdt||D]$}|j j ||||qdWn|j j ||j dS)Nz#data argument must be byte-ish (%r)r) rr bytearray memoryview TypeErrortypeac_out_buffer_sizer(rangerrr.)r rZsabsir r rpushs %zasync_chat.pushcCs|jj||jdS)N)rrr.)r Zproducerr r rpush_with_producerszasync_chat.push_with_producercCsdS)z4predicate for inclusion in the readable for select()r"r )r r r rreadableszasync_chat.readablecCs|jp|j S)z4predicate for inclusion in the writable for select())r connected)r r r rwritableszasync_chat.writablecCs|jjddS)zAautomatically close this channel once the outgoing queue is emptyN)rr)r r r rclose_when_doneszasync_chat.close_when_donecCspxi|jrk|jrk|jd}|sO|jd=|dkrO|jdSn|j}y|d|}WnDtk r|j}|r|jj|n |jd=wYnXt|tr|j rt ||j }ny|j |}Wn t k r|jdSYnX|rg|t|ks@|t|krZ||d|jdr.rDr r r rr4s,       H       (rc@s+eZdZdddZddZdS)simple_producericCs||_||_dS)N)r buffer_size)r rrJr r rr s zsimple_producer.__init__cCset|j|jkrK|jd|j}|j|jd|_|S|j}d|_|SdS)Nr)r(rrJ)r resultr r rr?s  zsimple_producer.moreN)rErFrGr r?r r r rrIs rIc@s[eZdZdddZddZddZdd Zd d Zd d ZdS)fifoNcCs(|st|_nt||_dS)N)rlist)r rMr r rr !sz fifo.__init__cCs t|jS)N)r(rM)r r r r__len__'sz fifo.__len__cCs|j S)N)rM)r r r ris_empty*sz fifo.is_emptycCs |jdS)Nr)rM)r r r rrB-sz fifo.firstcCs|jj|dS)N)rMr)r rr r rr90sz fifo.pushcCs$|jrd|jjfSdSdS)Nr"r)rN)rMpopleft)r r r rpop3s zfifo.pop) rErFrGr rNrOrBr9rQr r r rrL s     rLcCsEt|d}x.|r@|j|d| r@|d8}qW|S)Nr")r(endswith)ZhaystackZneedlelr r rr*Is#r*) rHr collectionsrr rrIrLr*r r r r/s  )