o
    �Úa_)  ã                   @   s.  d dl mZ d dlZd dlZd dlZzd dlZW n ey'   d dlmZ Y nw zd dl	Z	W n ey;   d dl
Z	Y nw d dlmZmZmZmZmZmZ ejejejejdœZG dd„ deƒZedkr•d dlZedƒZej d	 e¡¡ ej d
¡ e d¡ e ¡  ej d e d¡¡¡ e  ¡  dS dS )é    )Úabsolute_importN)Ú
SerialBaseÚSerialExceptionÚto_bytesÚ	iterbytesÚSerialTimeoutExceptionÚPortNotOpenError)ÚdebugÚinfoÚwarningÚerrorc                       sÚ   e Zd ZdZdZ‡ fdd„Zdd„ Z‡ fdd„Zd	d
„ Zdd„ Z	e
dd„ ƒZd,dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Ze
dd„ ƒZdd„ Zd d!„ Zd"d#„ Ze
d$d%„ ƒZe
d&d'„ ƒZe
d(d)„ ƒZe
d*d+„ ƒZ‡  ZS )-ÚSerialzSSerial port implementation that simulates a loop back connection in plain software.)é2   éK   én   é†   é–   éÈ   i,  iX  i°  i  i`	  iÀ  i€%  i K  i –  i á  i Â c                    s2   d| _ d | _d | _d| _tt| ƒj|i |¤Ž d S )Ni   F)Úbuffer_sizeÚqueueÚloggerÚ_cancel_writeÚsuperr   Ú__init__)ÚselfÚargsÚkwargs©Ú	__class__© úA/usr/lib/python3/dist-packages/serial/urlhandler/protocol_loop.pyr   /   s
   zSerial.__init__c                 C   s~   | j rtdƒ‚d| _t | j¡| _| jdu rtdƒ‚|  | j¡ |  	¡  d| _ | j
s.|  ¡  | js5|  ¡  |  ¡  |  ¡  dS )zx        Open port with current settings. This may throw a SerialException
        if the port cannot be opened.
        zPort is already open.Nz.Port must be configured before it can be used.T)Úis_openr   r   r   ÚQueuer   Ú_portÚfrom_urlÚportÚ_reconfigure_portÚ_dsrdtrÚ_update_dtr_stateÚ_rtsctsÚ_update_rts_stateÚreset_input_bufferÚreset_output_buffer©r   r   r   r    Úopen6   s   
zSerial.openc                    sD   | j rd| _ z| j d ¡ W n
 tjy   Y nw tt| ƒ ¡  d S )NF)r!   r   Ú
put_nowaitÚFullr   r   Úcloser-   r   r   r    r1   Q   s   ÿzSerial.closec                 C   sP   t | jtjƒrd| j  k rdk sn td | j¡ƒ‚| jr&| j d¡ dS dS )zx        Set communication parameters on opened port. For the loop://
        protocol all settings are ignored!
        r   l        zinvalid baudrate: {!r}z_reconfigure_port()N)Ú
isinstanceÚ	_baudrateÚnumbersÚIntegralÚ
ValueErrorÚformatr   r
   r-   r   r   r    r&   Z   s
   &ÿzSerial._reconfigure_portc              
   C   s¸   t  |¡}|jdkrtd |j¡ƒ‚z6t  |jd¡ ¡ D ])\}}|dkr?t 	¡  t 
d¡| _| j t|d  ¡ | j d¡ qtd |¡ƒ‚W d
S  ty[ } ztd	 |¡ƒ‚d
}~ww )z(extract host and port from an URL stringÚloopznexpected a string in the form "loop://[?logging={debug|info|warning|error}]": not starting with loop:// ({!r})TÚloggingzpySerial.loopr   zenabled loggingzunknown option: {!r}zPexpected a string in the form "loop://[?logging={debug|info|warning|error}]": {}N)ÚurlparseÚurlsplitÚschemer   r7   Úparse_qsÚqueryÚitemsr9   ÚbasicConfigÚ	getLoggerr   ÚsetLevelÚLOGGER_LEVELSr	   r6   )r   ÚurlÚpartsÚoptionÚvaluesÚer   r   r    r$   e   s,   

ýùþ€ÿzSerial.from_urlc                 C   ó4   | j stƒ ‚| jr| j d | j ¡ ¡¡ | j ¡ S )z9Return the number of bytes currently in the input buffer.zin_waiting -> {:d}©r!   r   r   r	   r7   r   Úqsizer-   r   r   r    Ú
in_waiting~   ó
   
zSerial.in_waitingé   c                 C   sì   | j stƒ ‚| jdur| jdkrt ¡ | j }nd}tƒ }|dkrr| j rrz
| jj| jd�}W n tjyB   | jdkr@Y t
|ƒS Y nw |durP||7 }|d8 }n	 t
|ƒS |rkt ¡ |krk| jrf| j 	d¡ 	 t
|ƒS |dkrr| j s$t
|ƒS )zÑ        Read size bytes from the serial port. If a timeout is set it may
        return less characters as requested. With no timeout it will block
        until the requested number of bytes is read.
        Nr   ©ÚtimeoutrN   zread timeout)r!   r   Ú_timeoutÚtimeÚ	bytearrayr   ÚgetÚEmptyr   r
   Úbytes)r   ÚsizerP   ÚdataÚbr   r   r    Úread‰   s6   
òÿ
üîzSerial.readc                 C   s   | j  d ¡ d S )N)r   r/   r-   r   r   r    Úcancel_readª   s   zSerial.cancel_readc                 C   s
   d| _ d S )NT)r   r-   r   r   r    Úcancel_write­   s   
zSerial.cancel_writec                 C   s´   d| _ | js	tƒ ‚t|ƒ}dt|ƒ | j }| jdurF|| jkrF| j}|dkr=| j s=t t	|dƒ¡ |d8 }|dkr=| j r*| j rBdS t
dƒ‚t|ƒD ]}| jj|| jd� qJt|ƒS )z²        Output the given byte string over the serial port. Can block if the
        connection is blocked. May raise SerialException if the connection is
        closed.
        Fg      $@Nr   g      à?zWrite timeoutrO   )r   r!   r   r   Úlenr3   Ú_write_timeoutrR   ÚsleepÚminr   r   r   Úput)r   rX   Útime_used_to_sendÚ	time_leftÚbyter   r   r    Úwrite°   s"   þzSerial.writec                 C   ó`   | j stƒ ‚| jr| j d¡ z| j ¡ r"| j ¡  | j ¡ sW dS W dS  tjy/   Y dS w )z9Clear input buffer, discarding all that is in the buffer.zreset_input_buffer()N©r!   r   r   r
   r   rK   Ú
get_nowaitrU   r-   r   r   r    r+   Ë   s   

ÿÿzSerial.reset_input_bufferc                 C   rf   )zs        Clear output buffer, aborting the current output and
        discarding all that is in the buffer.
        zreset_output_buffer()Nrg   r-   r   r   r    r,   ×   s   

ÿÿzSerial.reset_output_bufferc                 C   rI   )z0Return how many bytes the in the outgoing bufferzout_waiting -> {:d}rJ   r-   r   r   r    Úout_waitingæ   rM   zSerial.out_waitingc                 C   ó"   | j r| j  d | j¡¡ dS dS )z[        Set break: Controls TXD. When active, to transmitting is
        possible.
        z_update_break_state({!r})N)r   r
   r7   Ú_break_stater-   r   r   r    Ú_update_break_stateñ   s   ÿzSerial._update_break_statec                 C   rj   )z)Set terminal status line: Request To Sendz'_update_rts_state({!r}) -> state of CTSN)r   r
   r7   Ú
_rts_stater-   r   r   r    r*   ù   ó   ÿzSerial._update_rts_statec                 C   rj   )z-Set terminal status line: Data Terminal Readyz'_update_dtr_state({!r}) -> state of DSRN©r   r
   r7   Ú
_dtr_stater-   r   r   r    r(   þ   rn   zSerial._update_dtr_statec                 C   s,   | j stƒ ‚| jr| j d | j¡¡ | jS )z(Read terminal status line: Clear To SendzCTS -> state of RTS ({!r}))r!   r   r   r
   r7   rm   r-   r   r   r    Úcts  s
   z
Serial.ctsc                 C   s    | j r| j  d | j¡¡ | jS )z)Read terminal status line: Data Set ReadyzDSR -> state of DTR ({!r})ro   r-   r   r   r    Údsr  s   z
Serial.dsrc                 C   ó"   | j stƒ ‚| jr| j d¡ dS )z)Read terminal status line: Ring Indicatorzreturning dummy for RIF©r!   r   r   r
   r-   r   r   r    Úri  ó
   z	Serial.ric                 C   rs   )z)Read terminal status line: Carrier Detectzreturning dummy for CDTrt   r-   r   r   r    Úcd  rv   z	Serial.cd)rN   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ú	BAUDRATESr   r.   r1   r&   r$   ÚpropertyrL   rZ   r[   r\   re   r+   r,   ri   rl   r*   r(   rq   rr   ru   rw   Ú__classcell__r   r   r   r    r   )   s:    	


!




r   Ú__main__zloop://z{}
z	write...
zhello
zread: {!r}
é   )!Ú
__future__r   r9   r4   rR   r:   ÚImportErrorÚurllib.parseÚparser   r"   Úserial.serialutilr   r   r   r   r   r   ÚDEBUGÚINFOÚWARNINGÚERRORrC   r   rx   ÚsysÚsÚstdoutre   r7   ÚflushrZ   r1   r   r   r   r    Ú<module>   sB   ÿÿ ü  
ö