U
    wWôW‡'  ã                   @   s$  d dl Z d dlZd dlZzd dlZW n  ek
rD   d dlmZ Y nX zd dlZW n ek
rn   d dlZY nX 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 )é    N)Ú
SerialBaseÚSerialExceptionÚto_bytesÚ	iterbytesÚwriteTimeoutErrorÚportNotOpenError)ÚdebugÚinfoZ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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                    s.   d| _ d | _d | _d| _tt| ƒj||Ž 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kr4tdƒ‚|  | j¡ |  	¡  d| _ | j
s\|  ¡  | jsj|  ¡  |  ¡  |  ¡  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   Z_portÚfrom_urlZportÚ_reconfigure_portZ_dsrdtrÚ_update_dtr_stateZ_rtsctsÚ_update_rts_stateÚreset_input_bufferÚreset_output_buffer©r   r   r   r   Úopen4   s    
zSerial.openc                    sF   | j r4d| _ z| j d ¡ W n tjk
r2   Y nX tt| ƒ ¡  d S )NF)r   r   Ú
put_nowaitZFullr   r   Úcloser'   r   r   r   r*   O   s    zSerial.closec                 C   sL   t | jtjƒr&d| j  k r$dk s6n td | j¡ƒ‚| jrH| j d¡ 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ÚnumbersZIntegralÚ
ValueErrorÚformatr   r	   r'   r   r   r   r"   X   s    &zSerial._reconfigure_portc              
   C   sÆ   t  |¡}|jdkr$td |j¡ƒ‚zlt  |jd¡ ¡ D ]T\}}|dkr~t 	¡  t 
d¡| _| j t|d  ¡ | j d¡ q8td |¡ƒ‚q8W n0 tk
rÀ } ztd	 |¡ƒ‚W 5 d
}~X Y nX d
S )z(extract host and port from an URL stringZ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)ÚurlparseZurlsplitZschemer   r/   Zparse_qsZqueryÚitemsr0   ZbasicConfigZ	getLoggerr   ZsetLevelÚLOGGER_LEVELSr   r.   )r   ZurlÚpartsZoptionÚvaluesÚer   r   r   r!   c   s*    

þÿÿÿzSerial.from_urlc                 C   s2   | 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   r/   r   Úqsizer'   r   r   r   Ú
in_waiting|   s
    zSerial.in_waitingé   c                 C   sÊ   | j s
t‚| jdk	r.| jdkr.t ¡ | j }nd}tƒ }|dkrÂ| j rÂz| jj| jd}W n$ tjk
r~   | jdkrzY qÂY nX |dk	rÂ||7 }|d8 }nqÂ|r8t ¡ |kr8| jrÂ| j 	d¡ qÂq8t
|ƒ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   ©Útimeoutr9   zread timeout)r   r   Z_timeoutÚtimeÚ	bytearrayr   ÚgetÚEmptyr   r	   Úbytes)r   Úsizer;   ÚdataÚbr   r   r   Úread‡   s*    


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k	rz|| jkrz| j}|dkrl| j slt t	|dƒ¡ |d8 }qD| j rvdS t
‚t|ƒD ]}| jj|| jd q‚t|ƒ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      à?r:   )r   r   r   r   Úlenr,   Z_write_timeoutr<   ÚsleepÚminr   r   r   Zput)r   rB   Ztime_used_to_sendZ	time_leftZbyter   r   r   Úwrite®   s     
zSerial.writec                 C   sR   | j s
t‚| jr| j d¡ z| j ¡ r4| j ¡  qW n tjk
rL   Y nX dS )z9Clear input buffer, discarding all that is in the buffer.zreset_input_buffer()N©r   r   r   r	   r   r7   Z
get_nowaitr?   r'   r   r   r   r%   É   s    
zSerial.reset_input_bufferc                 C   sR   | j s
t‚| jr| j d¡ z| j ¡ r4| j ¡  qW n tjk
rL   Y nX dS )zs        Clear output buffer, aborting the current output and
        discarding all that is in the buffer.
        zreset_output_buffer()NrK   r'   r   r   r   r&   Õ   s    
zSerial.reset_output_bufferc                 C   s   | j r| j  d | j¡¡ dS )z[        Set break: Controls TXD. When active, to transmitting is
        possible.
        z_update_break_state({!r})N)r   r	   r/   Z_break_stater'   r   r   r   Ú_update_break_stateä   s    zSerial._update_break_statec                 C   s   | j r| j  d | j¡¡ dS )z)Set terminal status line: Request To Sendz'_update_rts_state({!r}) -> state of CTSN)r   r	   r/   Ú
_rts_stater'   r   r   r   r$   ì   s    zSerial._update_rts_statec                 C   s   | j r| j  d | j¡¡ dS )z-Set terminal status line: Data Terminal Readyz'_update_dtr_state({!r}) -> state of DSRN©r   r	   r/   Z
_dtr_stater'   r   r   r   r#   ñ   s    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	   r/   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})rN   r'   r   r   r   Údsrÿ   s    z
Serial.dsrc                 C   s    | 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  s
    z	Serial.ric                 C   s    | j s
t‚| jr| j d¡ dS )z)Read terminal status line: Carrier Detectzreturning dummy for CDTrQ   r'   r   r   r   Úcd  s
    z	Serial.cd)r9   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__Z	BAUDRATESr   r(   r*   r"   r!   Úpropertyr8   rD   rE   rF   rJ   r%   r&   rL   r$   r#   rO   rP   rR   rS   Ú__classcell__r   r   r   r   r   '   s4   	


!


r   Ú__main__zloop://z{}
z	write...
zhello
zread: {!r}
é   )r0   r-   r<   r1   ÚImportErrorZurllib.parseÚparser   r    Zserial.serialutilr   r   r   r   r   r   ÚDEBUGÚINFOZWARNINGZERRORr3   r   rT   ÚsysÚsÚstdoutrJ   r/   ÚflushrD   r*   r   r   r   r   Ú<module>   s6    ü w

