
    +c                         d dl Z d dlZd dlmZ d dlmZ d dlmZmZ d dl	m
Z
 d dlmZmZmZ d dlmZmZ d dlmZ d	d
lmZmZmZmZmZ  G d d      ZddZ G d d      Z G d d      Z G d de      Zy)    N)count)Optional)AuthenticatorBEGIN)get_bus)MessageMessageTypeParser)	ProxyBase
unwrap_msg)message_bus   )MessageFiltersFilterHandleReplyMatcherRouterClosedcheck_replyablec                   x    e Zd ZdZdej
                  dej                  fdZdddefdZ	d	efd
Z
d Zd Zd Zy)DBusConnectionaP  A plain D-Bus connection with no matching of replies.

    This doesn't run any separate tasks: sending and receiving are done in
    the task that calls those methods. It's suitable for implementing servers:
    several worker tasks can receive requests and send replies.
    For a typical client pattern, see :class:`DBusRouter`.
    readerwriterc                     || _         || _        t               | _        t	        d      | _        d | _        t        j                         | _	        y )Nr   )start)
r   r   r
   parserr   outgoing_serialunique_nameasyncioLock	send_lock)selfr   r   s      4/usr/lib/python3/dist-packages/jeepney/io/asyncio.py__init__zDBusConnection.__init__   s:    h$1~     Nserialmessagec                R  K   | j                   4 d{    |t        | j                        }| j                  j	                  |j                  |             | j                  j                          d{    ddd      d{    y7 x7 7 	# 1 d{  7  sw Y   yxY ww)z.Serialise and send a :class:`~.Message` objectN)r   nextr   r   write	serialisedrainr    r&   r%   s      r!   sendzDBusConnection.send    s     >> 	& 	&~d223KKg//78++##%%%		& 	& 	& &		& 	& 	& 	&sW   B'BB'AB6B7B;B'BB'BB'B$BB$ B'returnc                    K   	 | j                   j                         }||S | j                  j                  d       d{   }|st        | j                   j                  |       e7 (w)z5Return the next available message from the connectionNi   )r   get_next_messager   readEOFErroradd_data)r    msgbs      r!   receivezDBusConnection.receive(   s`     ++..0C
kk&&t,,AKK  # 
 -s   >A+ A))A+c                    K   | j                   j                          | j                   j                          d{    y7 w)zClose the D-Bus connectionN)r   closewait_closedr    s    r!   r8   zDBusConnection.close4   s,     kk%%'''s   8AA Ac                    K   | S wN r:   s    r!   
__aenter__zDBusConnection.__aenter__9           c                 @   K   | j                          d {    y 7 wr<   )r8   r    exc_typeexc_valexc_tbs       r!   	__aexit__zDBusConnection.__aexit__<   s     jjls   )__name__
__module____qualname____doc__r   StreamReaderStreamWriterr"   r   r-   r6   r8   r>   rF   r=   r#   r!   r   r      sR    (w33 (W=Q=Q ( 6: &' &
$w 
$(
r#   r   c                   K   t        |       }t        j                  |       d{   \  }}t               }|D ]b  }|j	                  |       |j                          d{    |j                  d       d{   }|st        d      |j                  |       d |j	                  t               |j                          d{    t        ||      }t        |      4 d{   }t        j                  t        t        |      j                         d       d{   }	|	d   |_        ddd      d{    |S 7 7 7 7 7 c7 +7 # 1 d{  7  sw Y   |S xY ww)zHOpen a plain D-Bus connection

    :return: :class:`DBusConnection`
    Ni   z#Socket closed before authentication
   r   )r   r   open_unix_connectionr   r)   r+   r1   r2   feedr   r   
DBusRouterwait_forProxyr   Hellor   )
busbus_addrr   r   authrreq_datar5   connrouter
reply_bodys
             r!   open_dbus_connectionr\   @   sG    
 s|H"77AANFF OE Xlln++d##@AA

1 LL
,,. &&)D $ ) )6"++E+v,F,L,L,NPRSS
%a=) ) K1 B 	# )S) ) ) ) Ks   $E'E:E'!E"E':E;AE'E	E''E(E'+6E!E"E0E';E<E'E'E'	E'E'EE'E$EE$E'c                       e Zd ZdZdZdZdZdefdZe	d        Z
dddZdefd	Zdd
ddeej                      fdZd Zd ZdefdZd Zy)rQ   zA 'client' D-Bus connection which can wait for a specific reply.

    This runs a background receiver task, and makes it possible to send a
    request and wait for the relevant reply.
    NrY   c                     || _         t               | _        t               | _        t        j                  | j                               | _        y r<   )	_connr   _repliesr   _filtersr   create_task	_receiver	_rcv_task)r    rY   s     r!   r"   zDBusRouter.__init__j   s5    
$&( ,,T^^-=>r#   c                 .    | j                   j                  S r<   )r_   r   r:   s    r!   r   zDBusRouter.unique_namep   s    zz%%%r#   r$   c                Z   K   | j                   j                  ||       d{    y7 w)z&Send a message, don't wait for a replyr$   N)r_   r-   r,   s      r!   r-   zDBusRouter.sendt   s      jjoogfo555s   !+)+r.   c                   K   t        |       | j                  j                         rt        d      t	        | j
                  j                        }| j                  j                  |t        j                               5 }| j                  ||       d{    | d{   cddd       S 7 7 # 1 sw Y   yxY ww)zSend a method call message and wait for the reply

        Returns the reply message (method return or error message type).
        zThis DBusRouter has stoppedr$   N)r   rd   doner   r(   r_   r   r`   catchr   Futurer-   )r    r&   r%   	reply_futs       r!   send_and_get_replyzDBusRouter.send_and_get_replyx   s     
 	 >> <==djj001]]  )9: 	%i))GF)333#O	% 	%3#	% 	%sB   A>B? B3B/	B3!B1"B3%
B?/B31B33B<8B?r   )queuebufsizerm   c                ^    t        | j                  ||xs t        j                  |            S )ar  Create a filter for incoming messages

        Usage::

            with router.filter(rule) as queue:
                matching_msg = await queue.get()

        :param MatchRule rule: Catch messages matching this rule
        :param asyncio.Queue queue: Send matching messages here
        :param int bufsize: If no queue is passed in, create one with this size
        )r   ra   r   Queue)r    rulerm   rn   s       r!   filterzDBusRouter.filter   s%     DMM41P'--:PQQr#   c                    K   | S wr<   r=   r:   s    r!   r>   zDBusRouter.__aenter__   r?   r@   c                 F  K   | j                   j                         r| j                   j                          y| j                   j                          t	        j
                  t        j                        5  | j                    d {    d d d        y7 # 1 sw Y   yxY ww)NF)rd   rh   resultcancel
contextlibsuppressr   CancelledErrorrB   s       r!   rF   zDBusRouter.__aexit__   sy     >> NN!!#
  NN!!#$$W%;%;< %nn$$% %%s0   A3B!5BBB
	B!BBB!r4   c                     | j                   j                  |      ryt        | j                  j	                  |            D ]  }	 |j
                  j                  |         y# t        j                  $ r Y 7w xY w)zHandle one received messageN)	r`   dispatchlistra   matchesrm   
put_nowaitr   	QueueFull)r    r4   rr   s      r!   	_dispatchzDBusRouter._dispatch   sk    ==!!#&4==0056 	F'',	 $$ s   A##A98A9c                    K   	 	 | j                   j                          d{   }| j                  |       47 # | j                  j	                          w xY ww)z'Receiver loop - runs in a separate taskN)r_   r6   r   r`   drop_all)r    r4   s     r!   rc   zDBusRouter._receiver   sJ     	% JJ..00s# 0 MM""$s   A; 9; AA)rG   rH   rI   rJ   _nursery_mgr_send_cancel_scope_rcv_cancel_scoper   r"   propertyr   r-   r   rl   r   r   rp   rr   r>   rF   r   rc   r=   r#   r!   rQ   rQ   `   s    
 L?^ ? & & -1 6%7 % ?CA RXgmm%< R	W 	%r#   rQ   c                   ,    e Zd ZdZdZdZddZd Zd Zy)open_dbus_routerzOpen a D-Bus 'router' to send and receive messages

    Use as an async context manager::

        async with open_dbus_router() as router:
            ...
    Nc                     || _         y r<   )rU   )r    rU   s     r!   r"   zopen_dbus_router.__init__   s	    r#   c                    K   t        | j                         d {   | _        t        | j                        | _        | j                  j                          d {   S 7 E7 wr<   )r\   rU   rY   rQ   req_ctxr>   r:   s    r!   r>   zopen_dbus_router.__aenter__   sH     .txx88	!$)),\\,,... 9.s"   A%A!A A%A#A%#A%c                    K   | j                   j                  |||       d {    | j                  j                          d {    y 7 '7 wr<   )r   rF   rY   r8   rB   s       r!   rF   zopen_dbus_router.__aexit__   s@     ll$$Xw???iioo 	@s!   !AA!AAAASESSION)	rG   rH   rI   rJ   rY   r   r"   r>   rF   r=   r#   r!   r   r      s"     DG/
 r#   r   c                   .     e Zd ZdZ fdZd Zd Z xZS )rS   a  An asyncio proxy for calling D-Bus methods

    You can call methods on the proxy object, such as ``await bus_proxy.Hello()``
    to make a method call over D-Bus and wait for a reply. It will either
    return a tuple of returned data, or raise :exc:`.DBusErrorResponse`.
    The methods available are defined by the message generator you wrap.

    :param msggen: A message generator object.
    :param ~asyncio.DBusRouter router: Router to send and receive messages.
    c                 2    t         |   |       || _        y r<   )superr"   _router)r    msggenrZ   	__class__s      r!   r"   zProxy.__init__   s     r#   c                 N    dj                  | j                  | j                        S )NzProxy({}, {}))format_msggenr   r:   s    r!   __repr__zProxy.__repr__   s    %%dllDLLAAr#   c                       fd}|S )Nc                     K    | i |}|j                   j                  t        j                  u sJ j                  j                  |       d {   }t        |      S 7 wr<   )headermessage_typer	   method_callr   rl   r   )argskwargsr4   replymake_msgr    s       r!   innerz!Proxy._method_call.<locals>.inner   s[     D+F+C::**k.E.EEEE,,99#>>Ee$$ ?s   AA$A"A$r=   )r    r   r   s   `` r!   _method_callzProxy._method_call   s    	% r#   )rG   rH   rI   rJ   r"   r   r   __classcell__)r   s   @r!   rS   rS      s    	Br#   rS   r   )r   rw   	itertoolsr   typingr   jeepney.authr   r   jeepney.busr   jeepneyr   r	   r
   jeepney.wrappersr   r   jeepney.bus_messagesr   commonr   r   r   r   r   r   r\   rQ   r   rS   r=   r#   r!   <module>r      sa        -  0 0 2 , 
- -`@V% V%p   0I r#   