
    Ϫf/                     `   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
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a ed       dZ G d dej>                  ej@                        Z! e!       Z"e"jG                          e"jI                  d       d Z%d Z&y)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                       e Zd Zy)BananaErrorN)__name__
__module____qualname__     7/usr/lib/python3/dist-packages/twisted/spread/banana.pyr
   r
      s    r   r
   c                 x    | dk(  r	 |d       y | dkD  sJ d       | r |t        | dz  f             | dz	  } | ry y )Nr       z!can only encode positive integers      )bytes)integerstreams     r   int2b128r      sJ    !|uQ;;;;;
ugn&'(Q, r   c                 ^    d}d}t        |       D ]  }t        |      }|||z  z  }|dz  } |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ns        r   b1282intr!   )   sG     	
A	A" I	QU
	a Hr                           c                     | a y)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)limits    r   setPrefixLimitr-   K   s	     Mr   @   i  
 c                   2   e Zd ZdZddgZdZeZd Zd Z	d Z
d Zd	 Zd
 ZdZd Z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'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;d<d=d>Zi Zej'                         D ]
  \  ZZeee<    dBd?Zd@ ZdA Zy)C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                 p    || _         d|dz  z   dz   | _        d| _        d| _        d|dz  z  dz
  | _        y)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,   s     r   r-   zBanana.setPrefixLimitr   sK     !"#	"2 3a 7$$ UQY/!3r   c                      y)zPSurrogate for connectionMade
        Called after protocol negotiation.
        Nr   r:   s    r   connectionReadyzBanana.connectionReady~   s    r   c                 2    || _         | j                          y N)currentDialectr=   )r:   dialects     r   _selectDialectzBanana._selectDialect   s    %r   c                    | j                   r| j                  |       y | j                  ri|D ]4  }|| j                  v s| j	                  |       | j                  |        y  t        j                  d       | j                  j                          y || j                  v r| j                  |       y t        j                  d       | j                  j                          y )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.)
r@   expressionReceivedisClientknownDialectssendEncodedrB   r   msg	transportloseConnection)r:   obj	serverVers      r   callExpressionReceivedzBanana.callExpressionReceived   s    ##C( }}!$ 4I D$6$66((3++I6	4 GG@ NN113$,,,'', GGC NN113r   c                     | j                  t               d | _        | j                  s| j	                  | j
                         y y r?   )r-   r+   r@   rE   rG   rF   r<   s    r   connectionMadezBanana.connectionMade   s8    M*"}}T//0 r   c                 r    | j                   }|r|d   d   j                  |       y | j                  |       y )Nr   )	listStackappendrM   )r:   itemls      r   gotItemzBanana.gotItem   s0    NNbE!HOOD!''-r   r   c                    | j                   |z   }| j                  }| j                  }|r| j                   |k7  s3J dj                  t	        | j                         t	        |                   || _         d}t        |      D ]  }|t        k\  r n0|dz   } || j                  kD  rt        d| j                  fz        y |d | }|||dz    }||dz   d  }	t        |      | j                  kD  rt        d| j                  fz        |t        k(  r6t        |      }|t        kD  rt        d      |j                  |g f       |	}n`|t        k(  r@t        |      }|t        kD  rt        d      t        |	      |k\  r|	|d  } ||	d |        ny |t        k(  r|	}t        |      } ||       n|t         k(  r|	}t        |      } ||       n|t"        k(  r|	}t        |      } ||        n|t$        k(  r|	}t        |       } ||       n|t&        k(  rB|	}t        |      }| j(                  |   }
| j*                  dk(  r	 ||
       n\t-        d	|
      |t.        k(  r7t        |	      d
k\  r(|	d
d  } |t1        j2                  d|	d d
       d          ny t-        d|      |rRt        |d   d         |d   d   k(  r8|j5                         d   }
 ||
       |rt        |d   d         |d   d   k(  r8|rd| _         y )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.r1   zInvalid item for pb protocol    !dzInvalid Type Byte rQ   r   )bufferrR   rV   formatreprr   HIGH_BIT_SETr5   r
   lenLISTr!   
SIZE_LIMITrS   STRINGINTLONGINTLONGNEGNEGVOCABincomingVocabularyr@   NotImplementedErrorFLOATstructunpackpop)r:   chunkrZ   rR   rV   poschnumtypebyterestrT   s              r   dataReceivedzBanana.dataReceived   s5   u$NN	,,;;&( *C*J*JT[[!V+ ( !DKC' 
%Ag

 )))%K++-.  #,CcC!G,H#')$D3x$***!O'')*  4sm#%&KLL  #r+V#sm#%&MNNt9#!#$ZFD#J'SsmW$smW$smS}nU"sm..s3&&%/DM-0MdX.VWWU"t9>!!"XFFMM$Ra9!<=),>xl*KLLYr]1%5!6)B-:J!J }}q) Yr]1%5!6)B-:J!JU Z r   c                     t               )z=Called when an expression (list, string, or int) is received.)rh   )r:   lsts     r   rD   zBanana.expressionReceived  s    !##r   s   Noner   s   classr4   s   dereference   s	   reference   s
   dictionary   s   function   s   instancer   s   listrX   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                 v    g | _         t        j                  | j                        | _        d| _        || _        y )Nr   )rR   copyoutgoingVocabularyoutgoingSymbolsoutgoingSymbolCountrE   )r:   rE   s     r   __init__zBanana.__init__4  s/    #yy)@)@A#$  r   c                     t               }| j                  ||j                         |j                         }| j                  j                  |       y)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getvaluerI   )r:   rK   encodeStreamvalues       r   rG   zBanana.sendEncoded:  s?     yS,,,-%%'U#r   c           	         t        |t        t        f      ret        |      t        kD  rt        dt        |      fz        t        t        |      |        |t               |D ]  }| j                  ||        y t        |t              r|| j                  k  s|| j                  kD  rt        d|fz        || j                  k  rt        | |        |t               y |dk  rt        | |        |t               y || j                  k  rt        ||        |t                y t        ||        |t"               y t        |t$              r) |t&                |t)        j*                  d|             y t        |t,              r| j.                  dk(  r6|| j0                  v r(| j0                  |   }t        ||        |t2               y t        |      t        kD  rt        dt        |      fz        t        t        |      |        |t4                ||       y t        dj7                  t9        t;        |            |            )Nz#list/tuple is too long to send (%d)zint is too large to send (%d)r   rY   r1   z$byte string is too long to send (%d)z#Banana cannot send {} objects: {!r})
isinstancelisttupler^   r`   r
   r   r_   r   intr6   r9   r7   rd   re   r8   rb   rc   floatri   rj   packr   r@   r   rf   ra   r[   r   type)r:   rK   r   elemsymbolIDs        r   r   zBanana._encodeJ  s   cD%=)3x*$!"G3s8+"UVVSXu%$K *T5)*S!T***cD4H4H.H!"ASF"JKKT&&&#u%gq#u%c
(((e$c
e$gU#%L&++dC()U#""e+t7K7K0K//45)es8j(%>#c(L  S5)fc
5<<&tCy13 r   )r   )r   r   r   __doc__rF   r5   r`   	sizeLimitr-   r=   rB   rM   rO   rV   rZ   rs   rD   r   rg   itemskvr   rG   r   r   r   r   r0   r0   a   s    G$MKI
4
4<1. FQf$## 	!# 		#
 	a# 	q# 	Q# 	Q# 	# 	1# 	r# 	"# 	"# 	#  	"!#" 	2##$ 	2%#& 	"'#( E#J "((* "1 !1"!$ -r   r0   r2   c                 v    t               }|t        _        t        j                  |        |j	                         S )zEncode a list s-expression.)r   _irI   rG   r   )ru   r   s     r   encoder     s+    9LBLNN3  ""r   c                     g }|j                   t        _        	 t        j                  |        dt        _        t        `|d   S # dt        _        t        `w xY w)z)
    Decode a banana-encoded string.
    r   r   )rS   r   rD   rs   rZ   )r   rU   s     r   decoder     sM     	AHHB"
	!Q4K 	!s   A A)'r   r   rj   ior   twisted.internetr   twisted.persistedr   twisted.pythonr   twisted.python.compatr   twisted.python.reflectr   	Exceptionr
   r   r!   r_   rb   ra   re   ri   rc   rd   rf   r]   r-   r+   r`   Protocol	Ephemeralr0   r   rO   rB   r   r   r   r   r   <module>r      s   
    % $  + 5	) 	( 	

   r 
VX 0 0 Vt X       ' #r   