U
     T‚g’/  ã                   @   sú   d 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
 ddlmZ ddlmZ G d	d
„ d
eƒZdd„ Zdd„ ZdZdZdZdZdZdZdZdZdZdd„ Zdaedƒ dZG dd„ dejej ƒZ!e!ƒ Z"e" #¡  e" $d¡ dd„ Z%d d!„ Z&dS )"zé
Banana -- s-exp based protocol.

Future Plans: This module is almost entirely stable.  The same caveat applies
to it as applies to L{twisted.spread.jelly}, however.  Read its future plans
for more details.

@author: Glyph Lefkowitz
é    N)ÚBytesIO)Úprotocol)Ústyles)Úlog)Ú	iterbytes)ÚfullyQualifiedNamec                   @   s   e Zd ZdS )ÚBananaErrorN)Ú__name__Ú
__module__Ú__qualname__© r   r   ú9/tmp/pip-unpacked-wheel-1_7di8ic/twisted/spread/banana.pyr      s   r   c                 C   sH   | dkr|dƒ d S | dks$t dƒ‚| rD|t| d@ fƒƒ | d? } q$d S )Nr   ó    z!can only encode positive integersé   é   )ÚAssertionErrorÚbytes)ÚintegerÚstreamr   r   r   Úint2b128   s    r   c                 C   s6   d}d}t | ƒD ] }t|ƒ}||| 7 }|dK }q|S )zí
    Convert an integer represented as a base 128 string into an L{int}.

    @param st: The integer encoded in a byte string.
    @type st: L{bytes}

    @return: The integer value extracted from the byte string.
    @rtype: L{int}
    é   r   r   )r   Úord)ÚstÚeÚiÚcharÚnr   r   r   Úb1282int)   s    

r   ó   €ó   �ó   ‚ó   ƒó   „ó   …ó   †ó   ‡c                 C   s   | a dS )ak  
    Set the limit on the prefix length for all Banana connections
    established after this call.

    The prefix length limit determines how many bytes of prefix a banana
    decoder will allow before rejecting a potential object as too large.

    @type limit: L{int}
    @param limit: The number of bytes of prefix for banana to allow when
    decoding.
    N)Ú_PREFIX_LIMIT)Úlimitr   r   r   ÚsetPrefixLimitK   s    r(   é@   i  
 c                    @   sà   e Zd ZdZddgZdZeZdd„ Zdd„ Z	d	d
„ Z
dd„ Zdd„ Zdd„ ZdZdd„ Zdd„ Zddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5œZi Ze ¡ D ]\ZZeee< q°d<d6d7„Zd8d9„ Zd:d;„ ZdS )=ÚBananazé
    L{Banana} implements the I{Banana} s-expression protocol, client and
    server.

    @ivar knownDialects: These are the profiles supported by this Banana
        implementation.
    @type knownDialects: L{list} of L{bytes}
    ó   pbó   noneNc                 C   s<   || _ d|d   d | _d| _d| _d|d  d | _dS )zt
        Set the prefix limit for decoding done by this protocol instance.

        @see: L{setPrefixLimit}
        é   r   r   i   €iÿÿÿN)ÚprefixLimitÚ_smallestLongIntÚ_smallestIntÚ_largestIntÚ_largestLongInt)Úselfr'   r   r   r   r(   r   s
    zBanana.setPrefixLimitc                 C   s   dS )zPSurrogate for connectionMade
        Called after protocol negotiation.
        Nr   ©r3   r   r   r   ÚconnectionReady~   s    zBanana.connectionReadyc                 C   s   || _ |  ¡  d S ©N)ÚcurrentDialectr5   )r3   Údialectr   r   r   Ú_selectDialectƒ   s    zBanana._selectDialectc                 C   sˆ   | j r|  |¡ nr| jrZ|D ]&}|| jkr|  |¡ |  |¡  q„qt d¡ | j 	¡  n*|| jkrp|  |¡ nt d¡ | j 	¡  d S )NzSThe client doesn't speak any of the protocols offered by the server: disconnecting.zYThe client selected a protocol the server didn't suggest and doesn't know: disconnecting.)
r7   ÚexpressionReceivedÚisClientÚknownDialectsÚsendEncodedr9   r   ÚmsgÚ	transportZloseConnection)r3   ÚobjZ	serverVerr   r   r   ÚcallExpressionReceived‡   s$    


ÿ
ÿzBanana.callExpressionReceivedc                 C   s&   |   t¡ d | _| js"|  | j¡ d S r6   )r(   r&   r7   r;   r=   r<   r4   r   r   r   ÚconnectionMade¥   s    
zBanana.connectionMadec                 C   s,   | j }|r|d d  |¡ n
|  |¡ d S )Néÿÿÿÿr   )Ú	listStackÚappendrA   )r3   ÚitemÚlr   r   r   ÚgotItem«   s    zBanana.gotItemó    c                 C   sÊ  | j | }| j}| j}|�rÀ| j |ks@td t| j ƒt|ƒ¡ƒ‚|| _ d}t|ƒD ]}|tkrb qŠ|d }qR|| jkr†t	d| jf ƒ‚d S |d |… }|||d … }||d d … }	t
|ƒ| jkrÔt	d| jf ƒ‚|tk�rt|ƒ}|tkröt	dƒ‚| |g f¡ |	}�nz|tk�rdt|ƒ}|tk�r0t	dƒ‚t
|	ƒ|k�r\|	|d … }||	d |… ƒ nd S �n"|tk�r†|	}t|ƒ}||ƒ �n |tk�r¦|	}t|ƒ}||ƒ nà|tk�rÈ|	}t|ƒ}|| ƒ n¾|tk�rê|	}t|ƒ }||ƒ nœ|tk�r0|	}t|ƒ}| j| }
| jdk�r ||
ƒ ntd	|
›�ƒ‚nV|tk�rxt
|	ƒd
k�rr|	d
d … }|t d|	d d
… ¡d ƒ nd S ntd|›�ƒ‚|rt
|d d ƒ|d d kr| ¡ d }
||
ƒ �q†qd| _ d S )NzThis ain't right: {} {}r   r   z1Security precaution: more than %d bytes of prefixz9Security precaution: longer than %d bytes worth of prefixz#Security precaution: List too long.z%Security precaution: String too long.r+   zInvalid item for pb protocol é   ú!dzInvalid Type Byte rC   rI   )ÚbufferrD   rH   r   ÚformatÚreprr   ÚHIGH_BIT_SETr.   r   ÚlenÚLISTr   Ú
SIZE_LIMITrE   ÚSTRINGÚINTÚLONGINTÚLONGNEGÚNEGÚVOCABÚincomingVocabularyr7   ÚNotImplementedErrorÚFLOATÚstructÚunpackÚpop)r3   ÚchunkrL   rD   rH   ÚposÚchÚnumZtypebyteÚrestrF   r   r   r   ÚdataReceived´   sš    
þ

ÿÿÿÿ













 zBanana.dataReceivedc                 C   s
   t ƒ ‚dS )z=Called when an expression (list, string, or int) is received.N)rZ   )r3   Úlstr   r   r   r:     s    zBanana.expressionReceivedr   r-   é   é   é   é   r   rJ   é	   é
   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   é   )s   Nones   classs   dereferences	   references
   dictionarys   functions   instances   lists   modules
   persistents   tuples   unpersistables   copys   caches   cacheds   remotes   locals   lcaches   versions   logins   passwords	   challenges	   logged_ins   not_logged_ins   cachemessages   messages   answers   errors   decrefs   decaches   uncachec                 C   s$   g | _ t | j¡| _d| _|| _d S )Nr   )rD   ÚcopyÚoutgoingVocabularyÚoutgoingSymbolsZoutgoingSymbolCountr;   )r3   r;   r   r   r   Ú__init__4  s    zBanana.__init__c                 C   s,   t ƒ }|  ||j¡ | ¡ }| j |¡ dS )a  
        Send the encoded representation of the given object:

        @param obj: An object to encode and send.

        @raise BananaError: If the given object is not an instance of one of
            the types supported by Banana.

        @return: L{None}
        N)r   Ú_encodeÚwriteÚgetvaluer?   )r3   r@   ÚencodeStreamÚvaluer   r   r   r=   :  s    zBanana.sendEncodedc                 C   s¼  t |ttfƒr\t|ƒtkr,tdt|ƒf ƒ‚tt|ƒ|ƒ |tƒ |D ]}|  ||¡ qF�n\t |t	ƒrø|| j
k sz|| jkrˆtd|f ƒ‚|| jk r¨t| |ƒ |tƒ nN|dk rÆt| |ƒ |tƒ n0|| jkrät||ƒ |tƒ nt||ƒ |tƒ nÀt |tƒ�r|tƒ |t d|¡ƒ nšt |tƒ�r | jdk�r`|| jk�r`| j| }t||ƒ |tƒ n>t|ƒtk�r€tdt|ƒf ƒ‚tt|ƒ|ƒ |tƒ ||ƒ ntd tt|ƒƒ|¡ƒ‚d S )Nz#list/tuple is too long to send (%d)zint is too large to send (%d)r   rK   r+   z$byte string is too long to send (%d)z#Banana cannot send {} objects: {!r})Ú
isinstanceÚlistÚtuplerP   rR   r   r   rQ   r…   Úintr/   r2   r0   rV   rW   r1   rT   rU   Úfloatr[   r\   Úpackr   r7   rƒ   rX   rS   rM   r   Útype)r3   r@   r†   ÚelemZsymbolIDr   r   r   r…   J  sT    











ÿ

 ÿÿzBanana._encode)r   )r	   r
   r   Ú__doc__r<   r.   rR   Z	sizeLimitr(   r5   r9   rA   rB   rH   rL   rd   r:   r‚   rY   ÚitemsÚkÚvr„   r=   r…   r   r   r   r   r*   a   sf   SÞ%

r*   r,   c                 C   s   t ƒ }|t_t | ¡ | ¡ S )zEncode a list s-expression.)r   Ú_ir?   r=   r‡   )re   rˆ   r   r   r   Úencode€  s    
r—   c                 C   s0   g }|j t_zt | ¡ W 5 dt_t`X |d S )z)
    Decode a banana-encoded string.
    rI   r   )rE   r–   r:   rL   rd   )r   rG   r   r   r   Údecodeˆ  s    r˜   )'r’   r�   r\   Úior   Ztwisted.internetr   Ztwisted.persistedr   Ztwisted.pythonr   Ztwisted.python.compatr   Ztwisted.python.reflectr   Ú	Exceptionr   r   r   rQ   rT   rS   rW   r[   rU   rV   rX   rO   r(   r&   rR   ÚProtocolZ	Ephemeralr*   r–   rB   r9   r—   r˜   r   r   r   r   Ú<module>   s@   
  
