ó
O'—^c           @@  s)  d  Z  d d l m Z d d l Z d d l Z d d l m 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 m Z m Z e j d d k Z e rÑ d „  Z n e Z d Z d Z d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   sf   
Convert between bytestreams and higher-level AMQP types.

2007-11-05 Barry Pederson <bp@barryp.org>

i    (   t   absolute_importN(   t   datetime(   t   Decimal(   t   BytesIO(   t   packt   unpacki   (   t   FrameSyntaxError(   t	   int_typest   long_tt   stringt   string_tt   itemsi   c         C@  s   t  |  g ƒ S(   N(   t   bytes(   t   n(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   byte&   s    sC   Table type {0!r} for key {1!r} not handled by amqp. [value: {2!r}]
s9       Table type {0!r} not handled by amqp. [value: {1!r}]
t
   AMQPReaderc           B@  s•   e  Z d  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(   s/   Read higher-level AMQP types from a bytestream.c         C@  s\   t  | t ƒ r! t | ƒ |  _ n' t | d ƒ r< | |  _ n t d ƒ ‚ d |  _ |  _ d S(   si   Source should be either a file-like object with a read() method, or
        a plain (non-unicode) string.t   reads3   AMQPReader needs a file-like object or plain stringi    N(   t
   isinstanceR   R   t   inputt   hasattrt
   ValueErrort   bitcountt   bits(   t   selft   source(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   __init__7   s    	c         C@  s   |  j  j ƒ  d  S(   N(   R   t   close(   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR   D   s    c         C@  s    d |  _  |  _ |  j j | ƒ S(   s   Read n bytes.i    (   R   R   R   R   (   R   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR   G   s    c         C@  se   |  j  s0 t |  j j d ƒ ƒ |  _ d |  _  n  |  j d @d k } |  j d L_ |  j  d 8_  | S(   s   Read a single boolean value.i   i   (   R   t   ordR   R   R   (   R   t   result(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   read_bitL   s    	c         C@  s-   d |  _  |  _ t d |  j j d ƒ ƒ d S(   s#   Read one byte, return as an integeri    t   Bi   (   R   R   R   R   R   (   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt
   read_octetV   s    c         C@  s-   d |  _  |  _ t d |  j j d ƒ ƒ d S(   s   Read an unsigned 16-bit integeri    s   >Hi   (   R   R   R   R   R   (   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt
   read_short[   s    c         C@  s-   d |  _  |  _ t d |  j j d ƒ ƒ d S(   s   Read an unsigned 32-bit integeri    s   >Ii   (   R   R   R   R   R   (   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt	   read_long`   s    c         C@  s-   d |  _  |  _ t d |  j j d ƒ ƒ d S(   s   Read an unsigned 64-bit integeri    s   >Qi   (   R   R   R   R   R   (   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   read_longlonge   s    c         C@  s-   d |  _  |  _ t d |  j j d ƒ ƒ d S(   s   Read float value.i    s   >di   (   R   R   R   R   R   (   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt
   read_floatj   s    c         C@  sH   d |  _  |  _ t d |  j j d ƒ ƒ d } |  j j | ƒ j d ƒ S(   s”   Read a short string that's stored in up to 255 bytes.

        The encoding isn't specified in the AMQP spec, so
        assume it's utf-8

        i    R   i   s   utf-8(   R   R   R   R   R   t   decode(   R   t   slen(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   read_shortstro   s    c         C@  sH   d |  _  |  _ t d |  j j d ƒ ƒ d } |  j j | ƒ j d ƒ S(   s†   Read a string that's up to 2**32 bytes.

        The encoding isn't specified in the AMQP spec, so
        assume it's utf-8

        i    s   >Ii   s   utf-8(   R   R   R   R   R   R$   (   R   R%   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   read_longstrz   s    c         C@  s   d |  _  |  _ t d |  j j d ƒ ƒ d } t |  j j | ƒ ƒ } i  } x; | j j ƒ  | k  rŠ | j ƒ  } | j ƒ  } | | | <qP W| S(   s6   Read an AMQP table, and return as a Python dictionary.i    s   >Ii   (	   R   R   R   R   R   R   t   tellR&   t	   read_item(   R   t   tlent
   table_dataR   t   namet   val(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt
   read_table…   s    c         C@  sô  t  |  j j d ƒ ƒ } | d k r3 |  j ƒ  } n½| d k rN |  j ƒ  } n¢| d k r{ t d |  j j d ƒ ƒ \ } nu| d k r¨ t d |  j j d ƒ ƒ \ } nH| d k rÕ t d	 |  j j d
 ƒ ƒ \ } n| d k rt d |  j j d
 ƒ ƒ \ } nî| d k r/t d |  j j d ƒ ƒ \ } nÁ| d k r\t d |  j j d ƒ ƒ \ } n”| d k r‰t d |  j j d ƒ ƒ \ } ng| d k r¶t d |  j j d ƒ ƒ \ } n:| d k rãt d |  j j d ƒ ƒ \ } n| d k rþ|  j ƒ  } nò | d k rQ|  j ƒ  } t d |  j j d ƒ ƒ \ } t | ƒ t d | ƒ } nŸ | d k rl|  j	 ƒ  } n„ | d k r‡|  j
 ƒ  } ni | d k r¢|  j ƒ  } nN | d k r½|  j ƒ  } n3 | d  k rÒd  } n t d! j | t | ƒ ƒ ƒ ‚ | S("   Ni   iS   is   ib   s   >BiB   s   >biU   s   >hi   iu   s   >HiI   s   >ii   ii   s   >IiL   s   >qi   il   s   >Qif   s   >fid   iD   i
   iF   iA   it   iT   iV   s%   Unknown value in table: {0!r} ({1!r})(   R   R   R   R'   R&   R   R#   R   R   R.   t
   read_arrayR   t   read_timestampt   NoneR   t   formatt   type(   R   t   ftypeR-   t   dR   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR)   ‘   sV    !!!!!!!!!	c         C@  sv   t  d |  j j d ƒ ƒ d } t |  j j | ƒ ƒ } g  } x2 | j j ƒ  | k  rq | j ƒ  } | j | ƒ q@ W| S(   Ns   >Ii   i    (   R   R   R   R   R(   R)   t   append(   R   t   array_lengtht
   array_dataR   R-   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR/   Ò   s    c         C@  s   t  j |  j ƒ  ƒ S(   sÜ   Read and AMQP timestamp, which is a 64-bit integer representing
        seconds since the Unix epoch in 1-second resolution.

        Return as a Python datetime.datetime object,
        expressed as localtime.

        (   R   t   utcfromtimestampR"   (   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR0   Û   s    (   t   __name__t
   __module__t   __doc__R   R   R   R   R   R    R!   R"   R#   R&   R'   R.   R)   R/   R0   (    (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR   5   s    				
									A		t
   AMQPWriterc           B@  s­   e  Z d  Z d d „ Z d „  Z d „  Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z d d „ Z d „  Z d „  Z RS(   s/   Convert higher-level AMQP types to bytestreams.c         C@  s4   | d k r t ƒ  n | |  _ g  |  _ d |  _ d S(   s±   dest may be a file-type object (with a write() method).  If None
        then a BytesIO is created, and the contents can be accessed with
        this class's getvalue() method.i    N(   R1   R   t   outR   R   (   R   t   dest(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR   é   s    	c         C@  sU   |  j  rQ |  j } x' |  j  D] } | j t d | ƒ ƒ q Wg  |  _  d |  _ n  d  S(   NR   i    (   R   R>   t   writeR   R   (   R   R>   t   b(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt
   _flushbitsñ   s    			c         C@  s)   y |  j  j ƒ  Wn t k
 r$ n Xd S(   s7   Pass through if possible to any file-like destinations.N(   R>   R   t   AttributeError(   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR   ù   s    c         C@  s)   y |  j  j ƒ  Wn t k
 r$ n Xd S(   s7   Pass through if possible to any file-like destinations.N(   R>   t   flushRC   (   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyRD      s    c         C@  s   |  j  ƒ  |  j j ƒ  S(   s?   Get what's been encoded so far if we're working with a BytesIO.(   RB   R>   t   getvalue(   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyRE     s    
c         C@  s   |  j  ƒ  |  j j | ƒ d S(   sb   Write a plain Python string with no special encoding in Python 2.x,
        or bytes in Python 3.xN(   RB   R>   R@   (   R   t   s(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR@     s    
c         C@  sh   | r d n d } |  j  d } | d k r> |  j j d ƒ n  |  j d c | | >O<|  j  d 7_  d S(   s   Write a boolean value.i   i    i   iÿÿÿÿN(   R   R   R6   (   R   RA   t   shift(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt	   write_bit  s    c         C@  sW   | d k  s | d k r0 t  d j | ƒ ƒ ‚ n  |  j ƒ  |  j j t d | ƒ ƒ d S(   s,   Write an integer as an unsigned 8-bit value.i    iÿ   s   Octet {0!r} out of range 0..255R   N(   R   R2   RB   R>   R@   R   (   R   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   write_octet  s
    
c         C@  s]   | d k  s | d k r0 t  d j | ƒ ƒ ‚ n  |  j ƒ  |  j j t d t | ƒ ƒ ƒ d S(   s-   Write an integer as an unsigned 16-bit value.i    iÿÿ  s!   Octet {0!r} out of range 0..65535s   >HN(   R   R2   RB   R>   R@   R   t   int(   R   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   write_short#  s
    
c         C@  sW   | d k  s | d k r0 t  d j | ƒ ƒ ‚ n  |  j ƒ  |  j j t d | ƒ ƒ d S(   s.   Write an integer as an unsigned2 32-bit value.i    I       s#   Octet {0!r} out of range 0..2**31-1s   >IN(   R   R2   RB   R>   R@   R   (   R   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt
   write_long+  s
    
c         C@  sW   | d k  s | d k r0 t  d j | ƒ ƒ ‚ n  |  j ƒ  |  j j t d | ƒ ƒ d S(   s-   Write an integer as an unsigned 64-bit value.i    l            s#   Octet {0!r} out of range 0..2**64-1s   >QN(   R   R2   RB   R>   R@   R   (   R   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   write_longlong3  s
    
c         C@  s‚   |  j  ƒ  t | t ƒ r+ | j d ƒ } n  t | ƒ d k r[ t d j t | ƒ ƒ ƒ ‚ n  |  j t | ƒ ƒ |  j j	 | ƒ d S(   s{   Write a string up to 255 bytes long (after any encoding).

        If passed a unicode string, encode with UTF-8.

        s   utf-8iÿ   s    Shortstring overflow ({0} > 255)N(
   RB   R   R	   t   encodet   lenR   R2   RI   R>   R@   (   R   RF   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   write_shortstr;  s    
c         C@  sR   |  j  ƒ  t | t ƒ r+ | j d ƒ } n  |  j t | ƒ ƒ |  j j | ƒ d S(   su   Write a string up to 2**32 bytes long after encoding.

        If passed a unicode string, encode as UTF-8.

        s   utf-8N(   RB   R   R	   RN   RL   RO   R>   R@   (   R   RF   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   write_longstrJ  s
    
c         C@  s€   |  j  ƒ  t ƒ  } x7 t | ƒ D]) \ } } | j | ƒ | j | | ƒ q  W| j ƒ  } |  j t | ƒ ƒ |  j j	 | ƒ d S(   sÃ   Write out a Python dictionary made of up string keys, and values
        that are strings, signed integers, Decimal, datetime.datetime, or
        sub-dictionaries following the same constraints.N(
   RB   R=   R   RP   t
   write_itemRE   RL   RO   R>   R@   (   R   R5   R+   t   kt   v(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   write_tableV  s    
	c         C@  sV  t  | t t f ƒ rS t  | t ƒ r6 | j d ƒ } n  |  j d ƒ |  j | ƒ nÿt  | t ƒ r„ |  j t d d t	 | ƒ ƒ ƒ nÎt  | t
 ƒ r¯ |  j t d d | ƒ ƒ n£t  | t ƒ rÚ |  j t d d | ƒ ƒ nxt  | t ƒ rg|  j d	 ƒ | j ƒ  \ } } } d
 } x | D] } | d | } qW| r@| } n  |  j | ƒ |  j t d | ƒ ƒ në t  | t ƒ r“|  j d ƒ |  j | ƒ n¿ t  | t ƒ r¿|  j d ƒ |  j | ƒ n“ t  | t t f ƒ rñ|  j d ƒ |  j | ƒ na | d  k r|  j d ƒ nE | r.t j t | ƒ | | ƒ n t j t | ƒ | ƒ } t | ƒ ‚ d  S(   Ns   utf-8t   Ss   >cBt   ts   >cdR5   s   >cit   It   Di    i
   s   >it   Tt   Ft   At   V(   R   R
   R   R	   RN   R@   RQ   t   boolR   RJ   t   floatR   R   t   as_tupleRI   R   t   write_timestampt   dictRU   t   listt   tuplet   write_arrayR1   t   ILLEGAL_TABLE_TYPE_WITH_KEYR2   R3   t   ILLEGAL_TABLE_TYPER   (   R   RT   RS   t   signt   digitst   exponentR5   t   err(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyRR   c  sF    "
!c         C@  sZ   t  ƒ  } x | D] } | j | ƒ q W| j ƒ  } |  j t | ƒ ƒ |  j j | ƒ d  S(   N(   R=   RR   RE   RL   RO   R>   R@   (   R   t   aR8   RT   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyRe   ‰  s    	c         C@  s2   |  j  j t d t t j | j ƒ  ƒ ƒ ƒ ƒ d S(   sr   Write out a Python datetime.datetime object as a 64-bit integer
        representing seconds since the Unix epoch.s   >QN(   R>   R@   R   R   t   calendart   timegmt   utctimetuple(   R   RT   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyRa   ‘  s    N(   R:   R;   R<   R1   R   RB   R   RD   RE   R@   RH   RI   RK   RL   RM   RP   RQ   RU   RR   Re   Ra   (    (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR=   æ   s$   														&	t   GenericContentc           B@  sD   e  Z d  Z d g Z d „  Z d „  Z d „  Z d „  Z d „  Z RS(	   se   Abstract base class for AMQP content.

    Subclasses should override the PROPERTIES attribute.

    t   dummyt   shortstrc         K@  sJ   i  } x4 |  j  D]) \ } } | | k r | | | | <q q W| |  _ d S(   s_   Save the properties appropriate to this AMQP content type
        in a 'properties' dictionary.N(   t
   PROPERTIESt
   properties(   R   t   propsR5   t   propnamet   _(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyR   Ÿ  s
    c         C@  s-   y |  j  | j  k SWn t k
 r( t SXd S(   sO   Check if this object has the same properties as another
        content object.N(   Rt   RC   t   NotImplemented(   R   t   other(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   __eq__ª  s    c         C@  sn   | d k r t  d ƒ ‚ n  | |  j k r5 |  j | Sd |  j k r^ | |  j k r^ |  j | St  | ƒ ‚ d S(   s   Look for additional properties in the 'properties'
        dictionary, and if present - the 'delivery_info'
        dictionary.t   __setstate__t   delivery_infoN(   RC   Rt   t   __dict__R|   (   R   R,   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   __getattr__²  s    c   	      C@  sâ   t  | ƒ } g  } x1 | j ƒ  } | j | ƒ | d @d k r Pq q Wd } i  } x€ |  j D]u \ } } | d k rœ | s~ Pn  | d | d } } d } n  | d | >@rÇ t | d | ƒ ƒ  | | <n  | d 8} q\ W| |  _ d S(   sÍ   Given the raw bytes containing the property-flags and property-list
        from a content-frame-header, parse and insert into a dictionary
        stored in this object as an attribute named 'properties'.i   i    i   t   read_N(   R   R    R6   Rs   t   getattrRt   (	   R   t	   raw_bytest   rt   flagst	   flag_bitsRG   R5   t   keyt   proptype(    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   _load_propertiesÃ  s&    	c   	      C@  s  d } d } g  } t  ƒ  } x¡ |  j D]– \ } } |  j j | d ƒ } | d k	 r± | d k rz | j | ƒ d } d } n  | d | >O} | d k r± t | d | ƒ | ƒ q± n  | d 8} q% W| j | ƒ t  ƒ  } x | D] } | j | ƒ qÜ W| j | j	 ƒ  ƒ | j	 ƒ  S(   s¿   serialize the 'properties' attribute (a dictionary) into
        the raw bytes making up a set of property flags and a
        property list, suitable for putting into a content frame header.i   i    i   t   bitt   write_N(
   R=   Rs   Rt   t   getR1   R6   R€   RK   R@   RE   (	   R   RG   R„   Rƒ   R   R…   R†   R-   R   (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   _serialize_propertiesá  s*    			(   Rq   Rr   (	   R:   R;   R<   Rs   R   Rz   R~   R‡   R‹   (    (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyRp   —  s   					(   R<   t
   __future__R    Rm   t   sysR   t   decimalR   t   ioR   t   structR   R   t
   exceptionsR   t   fiveR   R   R	   R
   R   t   version_infot   IS_PY3KR   t   chrRf   Rg   t   objectR   R=   Rp   (    (    (    s4   /tmp/pip-unpacked-wheel-9igm28/amqp/serialization.pyt   <module>   s$   (±±