o b/@sdZddlZddlZddlmZddlmZddlmZddl m Z ddl m Z ddl mZGd d d eZd d Zd dZdZdZdZdZdZdZdZdZdZddZdaeddZGdddejej Z!e!Z"e"#e"$dddZ%d d!Z&dS)"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 eZdZdS) BananaErrorN)__name__ __module__ __qualname__r r 7/usr/lib/python3/dist-packages/twisted/spread/banana.pyrsrcCsN|dkr |ddS|dksJd|r%|t|d@f|d?}|sdSdS)Nrz!can only encode positive integers)bytes)integerstreamr r r int2b128s rcCs6d}d}t|D]}t|}|||7}|dK}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} rr)rord)steicharnr r r b1282int)s    rcCs|adS)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 setPrefixLimitKs r'@i c@s(eZdZdZddgZdZeZddZddZ d d Z d d Z d dZ ddZ dZddZddZiddddddddddd d!d"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1d2d3d4d5d6d7d8d9d:d;dd?d@dAdBdCdDdEdFZiZeD]\ZZeee<q|dMdGdHZdIdJZdKdLZdS)NBananaz 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} pbnoneNcCs<||_d|d d|_d|_d|_d|dd|_dS)zt Set the prefix limit for decoding done by this protocol instance. @see: L{setPrefixLimit} rriiN) prefixLimit_smallestLongInt _smallestInt _largestInt_largestLongInt)selfr&r r r r'rs zBanana.setPrefixLimitcCsdS)zPSurrogate for connectionMade Called after protocol negotiation. Nr r2r r r connectionReady~szBanana.connectionReadycCs||_|dSN)currentDialectr4)r2dialectr r r _selectDialects zBanana._selectDialectcCs|jr ||dS|jr0|D]}||jvr#||||dSqtd|j dS||jvr<||dStd|j dS)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.) r6expressionReceivedisClient knownDialects sendEncodedr8rmsg transportloseConnection)r2obj serverVerr r r callExpressionReceiveds&    zBanana.callExpressionReceivedcCs*|td|_|js||jdSdSr5)r'r%r6r:r<r;r3r r r connectionMades zBanana.connectionMadecCs.|j}|r|dd|dS||dS)Nr) listStackappendrB)r2itemlr r r gotItemszBanana.gotItemc Cs|j|}|j}|j}|re|j|ks Jdt|jt|||_d}t|D] }|tkr1n|d}q)||jkrCtd|jfdS|d|}|||d}||dd} t ||jkrjtd|jf|t krt |}|t krztd| |gf| }n|tkrt |}|t krtdt | |kr| |d}|| d|ndS|tkr| }t |}||n{|tkr| }t |}||nl|tkr| }t |}|| n\|tkr| }t | }||nL|tkr | }t |}|j|} |jdkr|| n1td | |tkr.t | d kr,| d d}|td | dd dn dStd ||rct |d d|d dkrc|d} || |rct |d d|d dksG|sd|_dS)NzThis ain't right: {} {}rrz1Security 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*zInvalid item for pb protocol !dzInvalid Type Byte rDrJ)bufferrErIformatreprr HIGH_BIT_SETr-rlenLISTr SIZE_LIMITrFSTRINGINTLONGINTLONGNEGNEGVOCABincomingVocabularyr6NotImplementedErrorFLOATstructunpackpop) r2chunkrMrErIposchnumtypebyterestrGr r r dataReceiveds                  $ $ MzBanana.dataReceivedcCst)z=Called when an expression (list, string, or int) is received.)r[)r2lstr r r r9szBanana.expressionReceivedsNonersclassr,s dereferences references dictionarysfunctionsinstancerslistrKsmodule s persistent stuple s unpersistable scopy scachescachedsremoteslocal)slcachesversionsloginspasswords challenges logged_ins not_logged_ins cachemessagesmessagesanswerserrorsdecrefsdecachesuncachecCs$g|_t|j|_d|_||_dS)Nr)rEcopyoutgoingVocabularyoutgoingSymbolsoutgoingSymbolCountr:)r2r:r r r __init__4s zBanana.__init__cCs,t}|||j|}|j|dS)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_encodewritegetvaluer>)r2r@ encodeStreamvaluer r r r<:s zBanana.sendEncodedcCst|ttfr.t|tkrtdt|ftt|||t|D]}|||q#dSt|t r||j ks=||j krDtd|f||j krUt| ||t dS|dkret| ||tdS||jkrut|||tdSt|||tdSt|tr|t|td|dSt|tr|jdkr||jvr|j|}t|||tdSt|tkrtdt|ftt|||t||dStdtt||)Nz#list/tuple is too long to send (%d)zint is too large to send (%d)rrLr*z$byte string is too long to send (%d)z#Banana cannot send {} objects: {!r}) isinstancelisttuplerQrSrrrRrintr.r1r/rWrXr0rUrVfloatr\r]packrr6rrYrTrNrtype)r2r@relemsymbolIDr r r rJsT                     zBanana._encode)r)r r r __doc__r;r-rS sizeLimitr'r4r8rBrCrIrMrfr9rrZitemskvrr<rr r r r r)as  S     %   r)r+cCst}|t_t||S)zEncode a list s-expression.)r_ir>r<r)rgrr r r encodes rcCs8g}|jt_zt|Wdt_t`|dSdt_t`w)z) Decode a banana-encoded string. rJr)rFrr9rfrM)rrHr r r decodes r)'rrr]iortwisted.internetrtwisted.persistedrtwisted.pythonrtwisted.python.compatrtwisted.python.reflectr ExceptionrrrrRrUrTrXr\rVrWrYrPr'r%rSProtocol Ephemeralr)rrCr8rrr r r r sB