o
    ¯b–/  ã                   @   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   ú7/usr/lib/python3/dist-packages/twisted/spread/banana.pyr      s    r   c                 C   sN   | dkr
|dƒ d S | dksJ dƒ‚| r%|t | d@ fƒƒ | d? } | sd S d S )Nr   ó    z!can only encode positive integersé   é   )Ú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i 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/“d0d1“d2d3“d4d5“d6d7“d8d9d:d;d<d=d>d?d@dAdBdCdDdEdFœ¥Zi Ze ¡ D ]\ZZeee< q|dMdGdH„ZdIdJ„ ZdKdL„ ZdS )NÚ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   ©r2   r   r   r   ÚconnectionReady~   s    zBanana.connectionReadyc                 C   s   || _ |  ¡  d S ©N)ÚcurrentDialectr4   )r2   Údialectr   r   r   Ú_selectDialectƒ   s   zBanana._selectDialectc                 C   s�   | j r
|  |¡ d S | jr0|D ]}|| jv r#|  |¡ |  |¡  d S qt d¡ | j 	¡  d S || jv r<|  |¡ d S 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.)
r6   ÚexpressionReceivedÚisClientÚknownDialectsÚsendEncodedr8   r   ÚmsgÚ	transportÚloseConnection)r2   ÚobjÚ	serverVerr   r   r   ÚcallExpressionReceived‡   s&   


ýÿ
ÿzBanana.callExpressionReceivedc                 C   s*   |   t¡ d | _| js|  | j¡ d S d S r5   )r'   r%   r6   r:   r<   r;   r3   r   r   r   ÚconnectionMade¥   s
   
ÿzBanana.connectionMadec                 C   s.   | j }|r|d d  |¡ d S |  |¡ d S )Néÿÿÿÿr   )Ú	listStackÚappendrB   )r2   ÚitemÚlr   r   r   ÚgotItem«   s   zBanana.gotItemó    c                 C   sÔ  | j | }| j}| j}|�re| j |ks J d t| j ƒt|ƒ¡ƒ‚|| _ d}t|ƒD ]}|tkr1 n|d }q)|| jkrCtd| jf ƒ‚d S |d |… }|||d … }||d d … }	t	|ƒ| jkrjtd| jf ƒ‚|t
kr„t|ƒ}|tkrztdƒ‚| |g f¡ |	}n±|tkr«t|ƒ}|tkr”tdƒ‚t	|	ƒ|kr©|	|d … }||	d |… ƒ nŒd S |tkrº|	}t|ƒ}||ƒ n{|tkrÉ|	}t|ƒ}||ƒ nl|tkrÙ|	}t|ƒ}|| ƒ n\|tkré|	}t|ƒ }||ƒ nL|tk�r|	}t|ƒ}| j| }
| jdk�r||
ƒ n1td	|
›�ƒ‚|tk�r.t	|	ƒd
k�r,|	d
d … }|t d|	d d
… ¡d ƒ n	d S td|›�ƒ‚|�rct	|d d ƒ|d d k�rc| ¡ d }
||
ƒ |�rct	|d d ƒ|d d k�sG|s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 rD   rJ   )ÚbufferrE   rI   ÚformatÚreprr   ÚHIGH_BIT_SETr-   r   ÚlenÚLISTr   Ú
SIZE_LIMITrF   ÚSTRINGÚINTÚLONGINTÚLONGNEGÚNEGÚVOCABÚincomingVocabularyr6   ÚNotImplementedErrorÚFLOATÚstructÚunpackÚpop)r2   ÚchunkrM   rE   rI   ÚposÚchÚnumÚtypebyteÚrestrG   r   r   r   ÚdataReceived´   sž   
þ

ÿÿÿÿ







$$þ¶
MzBanana.dataReceivedc                 C   s   t ƒ ‚)z=Called when an expression (list, string, or int) is received.)r[   )r2   Úlstr   r   r   r9     s   zBanana.expressionReceiveds   Noner   s   classr,   s   dereferenceé   s	   referenceé   s
   dictionaryé   s   functioné   s   instancer   s   listrK   s   moduleé	   s
   persistenté
   s   tupleé   s   unpersistableé   s   copyé   s   cacheé   s   cachedé   s   remoteé   s   localé   é   é   é   é   é   é   é   é   é   é   é   é   é   é   )s   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   )rE   ÚcopyÚoutgoingVocabularyÚoutgoingSymbolsÚoutgoingSymbolCountr:   )r2   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>   )r2   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 ]}|  ||¡ q#d S t |t	ƒr€|| j
k s=|| jkrDtd|f ƒ‚|| jk rUt| |ƒ |tƒ d S |dk ret| |ƒ |tƒ d S || jkrut||ƒ |tƒ d S t||ƒ |tƒ d S t |tƒr“|tƒ |t d|¡ƒ d S t |tƒrÒ| jdkr²|| jv r²| j| }t||ƒ |tƒ d S t|ƒtkrÁtdt|ƒf ƒ‚tt|ƒ|ƒ |tƒ ||ƒ d S td tt|ƒƒ|¡ƒ‚)Nz#list/tuple is too long to send (%d)zint is too large to send (%d)r   rL   r*   z$byte string is too long to send (%d)z#Banana cannot send {} objects: {!r})Ú
isinstanceÚlistÚtuplerQ   rS   r   r   rR   rˆ   Úintr.   r1   r/   rW   rX   r0   rU   rV   Úfloatr\   r]   Úpackr   r6   r…   rY   rT   rN   r   Útype)r2   r@   r‰   ÚelemÚsymbolIDr   r   r   rˆ   J  sT   ÿ








ÿÿÿzBanana._encode)r   )r	   r
   r   Ú__doc__r;   r-   rS   Ú	sizeLimitr'   r4   r8   rB   rC   rI   rM   rf   r9   r„   rZ   ÚitemsÚkÚvr‡   r<   rˆ   r   r   r   r   r)   a   sŒ    Sþýüûúùø	÷
öõôóñðïîíÞ%

r)   r+   c                 C   s   t ƒ }|t_t | ¡ | ¡ S )zEncode a list s-expression.)r   Ú_ir>   r<   rŠ   )rg   r‹   r   r   r   Úencode€  s   
rœ   c                 C   s8   g }|j t_zt | ¡ W dt_t`|d S dt_t`w )z)
    Decode a banana-encoded string.
    rJ   r   )rF   r›   r9   rf   rM   )r   rH   r   r   r   Údecodeˆ  s   þr�   )'r–   rƒ   r]   Úior   Útwisted.internetr   Útwisted.persistedr   Útwisted.pythonr   Útwisted.python.compatr   Útwisted.python.reflectr   Ú	Exceptionr   r   r   rR   rU   rT   rX   r\   rV   rW   rY   rP   r'   r%   rS   ÚProtocolÚ	Ephemeralr)   r›   rC   r8   rœ   r�   r   r   r   r   Ú<module>   sB   
  
