Ë
    ojc\  ã                   óÖ   — d Z ddlmZ ddlmZmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZmZ dZ G d	„ d
e«      Z G d„ de«      Z G d„ de«      Z G d„ d«      Z G d„ dee
«      Zg d¢Zy)ap  
Memcache client protocol. Memcached is a caching server, storing data in the
form of pairs key/value, and memcache is the protocol to talk with it.

To connect to a server, create a factory for L{MemCacheProtocol}::

    from twisted.internet import reactor, protocol
    from twisted.protocols.memcache import MemCacheProtocol, DEFAULT_PORT
    d = protocol.ClientCreator(reactor, MemCacheProtocol
        ).connectTCP("localhost", DEFAULT_PORT)
    def doSomething(proto):
        # Here you call the memcache operations
        return proto.set("mykey", "a lot of data")
    d.addCallback(doSomething)
    reactor.run()

All the operations of the memcache protocol are present, but
L{MemCacheProtocol.set} and L{MemCacheProtocol.get} are the more important.

See U{http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt} for
more information about the protocol.
é    )Údeque)ÚDeferredÚTimeoutErrorÚfail)ÚLineReceiver)ÚTimeoutMixin)Úlog)ÚnativeStringÚnetworkStringiË+  c                   ó   — e Zd ZdZy)ÚNoSuchCommandzA
    Exception raised when a non existent command is called.
    N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© ó    ú</usr/lib/python3/dist-packages/twisted/protocols/memcache.pyr   r   (   ó   „ òr   r   c                   ó   — e Zd ZdZy)ÚClientErrorz1
    Error caused by an invalid client call.
    Nr   r   r   r   r   r   .   r   r   r   c                   ó   — e Zd ZdZy)ÚServerErrorz*
    Problem happening on the server.
    Nr   r   r   r   r   r   4   r   r   r   c                   ó"   — e Zd ZdZd„ Zd„ Zd„ Zy)ÚCommanda8  
    Wrap a client action into an object, that holds the values used in the
    protocol.

    @ivar _deferred: the L{Deferred} object that will be fired when the result
        arrives.
    @type _deferred: L{Deferred}

    @ivar command: name of the command sent to the server.
    @type command: L{bytes}
    c                 óz   — || _         t        «       | _        |j                  «       D ]  \  }}t	        | ||«       Œ y)zß
        Create a command.

        @param command: the name of the command.
        @type command: L{bytes}

        @param kwargs: this values will be stored as attributes of the object
            for future use
        N)Úcommandr   Ú	_deferredÚitemsÚsetattr)Úselfr   ÚkwargsÚkÚvs        r   Ú__init__zCommand.__init__G   s9   € ð ˆŒÜ!›ˆŒØ—L‘L“Nò 	 ‰DˆAˆqÜ�D˜!˜QÕñ	 r   c                 ó:   — | j                   j                  |«       y)zB
        Shortcut method to fire the underlying deferred.
        N)r   Úcallback)r"   Úvalues     r   ÚsuccesszCommand.successV   s   € ð 	�‰×Ñ Õ&r   c                 ó:   — | j                   j                  |«       y)z5
        Make the underlying deferred fails.
        N)r   Úerrback)r"   Úerrors     r   r   zCommand.fail\   s   € ð 	�‰×Ñ˜uÕ%r   N)r   r   r   r   r&   r*   r   r   r   r   r   r   :   s   „ ñ
ò ò'ó&r   r   c                   ó
  — e Zd ZdZd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„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd+d„Zd+d„Zd„ Zd,d„Zd,d„Zd,d„Zd,d„Z d„ Z!d „ Z"d!„ Z#d-d"„Z$d-d#„Z%d$„ Z&d.d&„Z'd'„ Z(d(„ Z)d)„ Z*y%)/ÚMemCacheProtocola1  
    MemCache protocol: connect to a memcached server to store/retrieve values.

    @ivar persistentTimeOut: the timeout period used to wait for a response.
    @type persistentTimeOut: L{int}

    @ivar _current: current list of requests waiting for an answer from the
        server.
    @type _current: L{deque} of L{Command}

    @ivar _lenExpected: amount of data expected in raw mode, when reading for
        a value.
    @type _lenExpected: L{int}

    @ivar _getBuffer: current buffer of data, used to store temporary data
        when reading in raw mode.
    @type _getBuffer: L{list}

    @ivar _bufferLength: the total amount of bytes in C{_getBuffer}.
    @type _bufferLength: L{int}

    @ivar _disconnected: indicate if the connectionLost has been called or not.
    @type _disconnected: L{bool}
    éú   Fc                 óh   — t        «       | _        d| _        d| _        d| _        |x| _        | _        y)zÓ
        Create the protocol.

        @param timeOut: the timeout to wait before detecting that the
            connection is dead and close it. It's expressed in seconds.
        @type timeOut: L{int}
        N)r   Ú_currentÚ_lenExpectedÚ
_getBufferÚ_bufferLengthÚpersistentTimeOutÚtimeOut)r"   r7   s     r   r&   zMemCacheProtocol.__init__€   s3   € ô ›ˆŒØ ˆÔØˆŒØ!ˆÔØ07Ð7ˆÔ ¥r   c                 óŽ   — | j                   r9| j                   j                  «       }|j                  |«       | j                   rŒ8yy)zW
        Cancel all the outstanding commands, making them fail with C{reason}.
        N)r2   Úpopleftr   )r"   ÚreasonÚcmds      r   Ú_cancelCommandsz MemCacheProtocol._cancelCommandsŽ   s2   € ð �mŠmØ—-‘-×'Ñ'Ó)ˆCØ�H‰H�VÔð �m�mr   c                 ól   — | j                  t        d«      «       | j                  j                  «        y)z:
        Close the connection in case of timeout.
        zConnection timeoutN)r<   r   Ú	transportÚloseConnection©r"   s    r   ÚtimeoutConnectionz"MemCacheProtocol.timeoutConnection–   s(   € ð 	×Ñœ\Ð*>Ó?Ô@Ø�‰×%Ñ%Õ'r   c                 ó`   — d| _         | j                  |«       t        j                  | |«       y)z9
        Cause any outstanding commands to fail.
        TN)Ú_disconnectedr<   r   ÚconnectionLost)r"   r:   s     r   rD   zMemCacheProtocol.connectionLost�   s*   € ð "ˆÔØ×Ñ˜VÔ$Ü×#Ñ# D¨&Õ1r   c                 ó~   — | j                   s| j                  | j                  «       t        j                  | |«       y)zA
        Override sendLine to add a timeout to response.
        N)r2   Ú
setTimeoutr6   r   ÚsendLine)r"   Úlines     r   rG   zMemCacheProtocol.sendLine¥   s-   € ð �}Š}Ø�O‰O˜D×2Ñ2Ô3Ü×Ñ˜d DÕ)r   c                 óN  — | j                  «        | j                  j                  |«       | xj                  t	        |«      z  c_        | j                  | j
                  dz   k\  rÀdj                  | j                  «      }|d| j
                   }|| j
                  dz   d }|}d| _        d| _        d| _        | j                  d   }|j                  r9|j                  |j                     \  }}|||f|j                  |j                  <   n||_        | j                  |«       yy)z)
        Collect data for a get.
        é   r   Nr   )ÚresetTimeoutr4   Úappendr5   Úlenr3   Újoinr2   ÚmultipleÚvaluesÚ
currentKeyr)   ÚsetLineMode)r"   ÚdataÚbufÚremÚvalr;   ÚflagsÚcass           r   ÚrawDataReceivedz MemCacheProtocol.rawDataReceived­   s  € ð 	×ÑÔØ�‰×Ñ˜tÔ$Ø×Òœc $›iÑ'ÕØ×Ñ ×!2Ñ!2°QÑ!6Ò6Ø—8‘8˜DŸO™OÓ,ˆDØÐ*˜×*Ñ*Ð+ˆCØ�t×(Ñ(¨1Ñ,Ð.Ð/ˆCØˆCØ $ˆDÔØ"ˆDŒOØ!%ˆDÔØ—-‘- Ñ"ˆCØ�|Š|Ø ŸZ™Z¨¯©Ñ7‘
��sØ.3°S¸#Ð->�—
‘
˜3Ÿ>™>Ò*à�”	Ø×Ñ˜SÕ!ð 7r   c                 óV   — | j                   j                  «       j                  d«       y)z?
        Manage a success response to a set operation.
        TN©r2   r9   r*   r@   s    r   Ú
cmd_STOREDzMemCacheProtocol.cmd_STOREDÄ   ó   € ð 	�‰×ÑÓ×'Ñ'¨Õ-r   c                 óV   — | j                   j                  «       j                  d«       y)zŠ
        Manage a specific 'not stored' response to a set operation: this is not
        an error, but some condition wasn't met.
        FNr[   r@   s    r   Úcmd_NOT_STOREDzMemCacheProtocol.cmd_NOT_STOREDÊ   s   € ð
 	�‰×ÑÓ×'Ñ'¨Õ.r   c           	      óÖ  — | j                   j                  «       }|j                  dk(  ry|j                  rE|j                  j                  «       D ��ci c]  \  }}||ddd…   “Œ }}}|j                  |«       y|j                  |j                  |j                  f«       y|j                  dk(  r[|j                  r|j                  |j                  «       y|j                  |j                  |j                  |j                  f«       y|j                  dk(  r|j                  |j                  «       yt        dj                  t        |j                  «      «      «      ‚c c}}w )zB
        This the end token to a get or a stat operation.
        ó   getNrJ   ó   getsó   statsz%Unexpected END response to {} command)r2   r9   r   rO   rP   r    r*   rW   r)   rX   ÚRuntimeErrorÚformatr
   )r"   r;   ÚkeyrV   rP   s        r   Úcmd_ENDzMemCacheProtocol.cmd_ENDÑ   s	  € ð �m‰m×#Ñ#Ó%ˆØ�;‰;˜&Ò Ø�|Š|Ø8;¿
¹
×8HÑ8HÓ8J×K©H¨C°˜#˜s¡3 Q 3™x™-ÐK�ÑKØ—‘˜FÕ#à—‘˜SŸY™Y¨¯	©	Ð2Õ3Ø�[‰[˜GÒ#Ø�|Š|Ø—‘˜CŸJ™JÕ'à—‘˜SŸY™Y¨¯©°·±Ð;Õ<Ø�[‰[˜HÒ$Ø�K‰K˜Ÿ
™
Õ#äØ7×>Ñ>Ü  §¡Ó-óóð ùó Ls   ÁE%c                 óV   — | j                   j                  «       j                  d«       y)z=
        Manage error response for incr/decr/delete.
        FNr[   r@   s    r   Úcmd_NOT_FOUNDzMemCacheProtocol.cmd_NOT_FOUNDê   ó   € ð 	�‰×ÑÓ×'Ñ'¨Õ.r   c                 óä  — | j                   d   }|j                  dk(  r|j                  «       \  }}}d}n|j                  «       \  }}}}t        |«      | _        g | _        d| _        |j                  r;||j                  vrt        d«      ‚||_
        t        |«      |g|j                  |<   n1|j                  |k7  rt        d«      ‚t        |«      |_        ||_        | j                  «        y)z:
        Prepare the reading a value after a get.
        r   ra   r   zUnexpected commands answer.N)r2   r   ÚsplitÚintr3   r4   r5   rO   Úkeysrd   rQ   rP   rf   rW   rX   Ú
setRawMode)r"   rH   r;   rf   rW   ÚlengthrX   s          r   Ú	cmd_VALUEzMemCacheProtocol.cmd_VALUEð   sÓ   € ð �m‰m˜AÑˆØ�;‰;˜&Ò Ø!%§¡£ÑˆC�˜Ø‰Cà&*§j¡j£lÑ#ˆC�˜ Ü ›KˆÔØˆŒØˆÔØ�<Š<Ø˜#Ÿ(™(Ñ"Ü"Ð#@ÓAÐAØ ˆCŒNÜ" 5›z¨3Ð/ˆC�J‰J�sŠOà�w‰w˜#Š~Ü"Ð#@ÓAÐAÜ˜E›
ˆCŒIØˆCŒGØ�‰Õr   c                 ój   — | j                   d   }|j                  dd«      \  }}||j                  |<   y)z-
        Reception of one stat line.
        r   ó    é   N)r2   rl   rP   )r"   rH   r;   rf   rV   s        r   Úcmd_STATzMemCacheProtocol.cmd_STAT	  s3   € ð �m‰m˜AÑˆØ—:‘:˜d AÓ&‰ˆˆSØˆ�
‰
�3Šr   c                 óV   — | j                   j                  «       j                  |«       y)z%
        Read version token.
        Nr[   )r"   ÚversionDatas     r   Úcmd_VERSIONzMemCacheProtocol.cmd_VERSION  s   € ð 	�‰×ÑÓ×'Ñ'¨Õ4r   c                 ó”   — t        j                  d«       | j                  j                  «       }|j	                  t        «       «       y)z7
        A non-existent command has been sent.
        zNon-existent command sent.N)r	   Úerrr2   r9   r   r   )r"   r;   s     r   Ú	cmd_ERRORzMemCacheProtocol.cmd_ERROR  s1   € ô 	�‰Ð,Ô-Ø�m‰m×#Ñ#Ó%ˆØ�‰”“Õ!r   c                 ó²   — t        |«      }t        j                  d|z   «       | j                  j	                  «       }|j                  t        |«      «       y)z0
        An invalid input as been sent.
        zInvalid input: N)Úreprr	   rz   r2   r9   r   r   ©r"   ÚerrTextr;   s      r   Úcmd_CLIENT_ERRORz!MemCacheProtocol.cmd_CLIENT_ERROR  sB   € ô �w“-ˆÜ�‰Ð! GÑ+Ô,Ø�m‰m×#Ñ#Ó%ˆØ�‰”˜WÓ%Õ&r   c                 ó²   — t        |«      }t        j                  d|z   «       | j                  j	                  «       }|j                  t        |«      «       y)z4
        An error has happened server-side.
        zServer error: N)r}   r	   rz   r2   r9   r   r   r~   s      r   Úcmd_SERVER_ERRORz!MemCacheProtocol.cmd_SERVER_ERROR(  sB   € ô �w“-ˆÜ�‰Ð  7Ñ*Ô+Ø�m‰m×#Ñ#Ó%ˆØ�‰”˜WÓ%Õ&r   c                 óV   — | j                   j                  «       j                  d«       y)z>
        A delete command has completed successfully.
        TNr[   r@   s    r   Úcmd_DELETEDzMemCacheProtocol.cmd_DELETED1  r]   r   c                 óV   — | j                   j                  «       j                  d«       y)z6
        The last command has been completed.
        TNr[   r@   s    r   Úcmd_OKzMemCacheProtocol.cmd_OK7  r]   r   c                 óV   — | j                   j                  «       j                  d«       y)z5
        A C{checkAndSet} update has failed.
        FNr[   r@   s    r   Ú
cmd_EXISTSzMemCacheProtocol.cmd_EXISTS=  rj   r   c                 óì  — | j                  «        |j                  dd«      d   }t        | dt        |«      z   d«      }|�+|j                  dd«      dd }|r ||d   «       ns |«        nk|j	                  dd«      }t        | dt        |«      z   d«      }|� |«        n6| j
                  j                  «       }t        |«      }|j                  |«       | j
                  s| j                  d«       yy)z8
        Receive line commands from the server.
        rs   rt   r   Úcmd_Nó   _)
rK   rl   Úgetattrr
   Úreplacer2   r9   rm   r*   rF   )r"   rH   Útokenr;   ÚargsrV   s         r   ÚlineReceivedzMemCacheProtocol.lineReceivedC  sá   € ð 	×ÑÔØ—
‘
˜4 Ó# AÑ&ˆä�d˜F¤\°%Ó%8Ñ8¸$Ó?ˆØˆ?Ø—:‘:˜d AÓ& q rÐ*ˆDÙÙ�D˜‘G•á•ð —<‘<  dÓ+ˆDÜ˜$ ¬°dÓ);Ñ ;¸TÓBˆCØˆÙ•ð —m‘m×+Ñ+Ó-�Ü˜$“i�Ø—‘˜CÔ Ø�}Š}à�O‰O˜DÕ!ð r   c                 ó(   — | j                  d||«      S )a¾  
        Increment the value of C{key} by given value (default to 1).
        C{key} must be consistent with an int. Return the new value.

        @param key: the key to modify.
        @type key: L{bytes}

        @param val: the value to increment.
        @type val: L{int}

        @return: a deferred with will be called back with the new value
            associated with the key (after the increment).
        @rtype: L{Deferred}
        s   incr©Ú	_incrdecr©r"   rf   rV   s      r   Ú	incrementzMemCacheProtocol.increment`  s   € ð �~‰~˜g s¨CÓ0Ð0r   c                 ó(   — | j                  d||«      S )aà  
        Decrement the value of C{key} by given value (default to 1).
        C{key} must be consistent with an int. Return the new value, coerced to
        0 if negative.

        @param key: the key to modify.
        @type key: L{bytes}

        @param val: the value to decrement.
        @type val: L{int}

        @return: a deferred with will be called back with the new value
            associated with the key (after the decrement).
        @rtype: L{Deferred}
        s   decrr’   r”   s      r   Ú	decrementzMemCacheProtocol.decrementq  s   € ð  �~‰~˜g s¨CÓ0Ð0r   c                 óÈ  — | j                   rt        t        d«      «      S t        |t        «      s!t        t        dt        |«      › d�«      «      S t        |«      | j                  kD  rt        t        d«      «      S dj                  ||dt        |«      fz  g«      }| j                  |«       t        ||¬«      }| j                  j                  |«       |j                  S )z1
        Internal wrapper for incr/decr.
        únot connectedúInvalid type for key: ú, expecting bytesúKey too longrs   s   %d©rf   )rC   r   rd   Ú
isinstanceÚbytesr   ÚtyperM   ÚMAX_KEY_LENGTHrN   rm   rG   r   r2   rL   r   )r"   r;   rf   rV   ÚfullcmdÚcmdObjs         r   r“   zMemCacheProtocol._incrdecrƒ  sÅ   € ð ×ÒÜœ _Ó5Ó6Ð6Ü˜#œuÔ%ÜÜÐ4´T¸#³Y°KÐ?PÐQÓRóð ô ˆs‹8�d×)Ñ)Ò)Üœ NÓ3Ó4Ð4Ø—)‘)˜S # u´°C³¨{Ñ':Ð;Ó<ˆØ�‰�gÔÜ˜ #Ô&ˆØ�‰×Ñ˜VÔ$Ø×ÑÐr   c                 ó.   — | j                  d||||d«      S )a�  
        Replace the given C{key}. It must already exist in the server.

        @param key: the key to replace.
        @type key: L{bytes}

        @param val: the new value associated with the key.
        @type val: L{bytes}

        @param flags: the flags to store with the key.
        @type flags: L{int}

        @param expireTime: if different from 0, the relative time in seconds
            when the key will be deleted from the store.
        @type expireTime: L{int}

        @return: a deferred that will fire with C{True} if the operation has
            succeeded, and C{False} with the key didn't previously exist.
        @rtype: L{Deferred}
        s   replacer   ©Ú_set©r"   rf   rV   rW   Ú
expireTimes        r   r�   zMemCacheProtocol.replace•  s   € ð* �y‰y˜ S¨#¨u°jÀ#ÓFÐFr   c                 ó.   — | j                  d||||d«      S )a„  
        Add the given C{key}. It must not exist in the server.

        @param key: the key to add.
        @type key: L{bytes}

        @param val: the value associated with the key.
        @type val: L{bytes}

        @param flags: the flags to store with the key.
        @type flags: L{int}

        @param expireTime: if different from 0, the relative time in seconds
            when the key will be deleted from the store.
        @type expireTime: L{int}

        @return: a deferred that will fire with C{True} if the operation has
            succeeded, and C{False} with the key already exists.
        @rtype: L{Deferred}
        s   addr   r¥   r§   s        r   ÚaddzMemCacheProtocol.add¬  ó   € ð* �y‰y˜  c¨5°*¸cÓBÐBr   c                 ó.   — | j                  d||||d«      S )a9  
        Set the given C{key}.

        @param key: the key to set.
        @type key: L{bytes}

        @param val: the value associated with the key.
        @type val: L{bytes}

        @param flags: the flags to store with the key.
        @type flags: L{int}

        @param expireTime: if different from 0, the relative time in seconds
            when the key will be deleted from the store.
        @type expireTime: L{int}

        @return: a deferred that will fire with C{True} if the operation has
            succeeded.
        @rtype: L{Deferred}
        s   setr   r¥   r§   s        r   ÚsetzMemCacheProtocol.setÃ  r«   r   c                 ó.   — | j                  d|||||«      S )am  
        Change the content of C{key} only if the C{cas} value matches the
        current one associated with the key. Use this to store a value which
        hasn't been modified since last time you fetched it.

        @param key: The key to set.
        @type key: L{bytes}

        @param val: The value associated with the key.
        @type val: L{bytes}

        @param cas: Unique 64-bit value returned by previous call of C{get}.
        @type cas: L{bytes}

        @param flags: The flags to store with the key.
        @type flags: L{int}

        @param expireTime: If different from 0, the relative time in seconds
            when the key will be deleted from the store.
        @type expireTime: L{int}

        @return: A deferred that will fire with C{True} if the operation has
            succeeded, C{False} otherwise.
        @rtype: L{Deferred}
        s   casr¥   )r"   rf   rV   rX   rW   r¨   s         r   ÚcheckAndSetzMemCacheProtocol.checkAndSetÚ  s   € ð4 �y‰y˜  c¨5°*¸cÓBÐBr   c           
      ó~  — | j                   rt        t        d«      «      S t        |t        «      s!t        t        dt        |«      › d�«      «      S t        |«      | j                  kD  rt        t        d«      «      S t        |t        «      s!t        t        dt        |«      › d�«      «      S |rd|z   }t        |«      }dj                  ||t        d|||fz  «      g«      |z   }| j                  |«       | j                  |«       t        ||||¬«      }	| j                  j                  |	«       |	j                  S )	z6
        Internal wrapper for setting values.
        r™   rš   r›   rœ   zInvalid type for value: rs   z%d %d %d)rf   rW   rp   )rC   r   rd   rž   rŸ   r   r    rM   r¡   rN   r   rG   r   r2   rL   r   )
r"   r;   rf   rV   rW   r¨   rX   rp   r¢   r£   s
             r   r¦   zMemCacheProtocol._setö  s2  € ð ×ÒÜœ _Ó5Ó6Ð6Ü˜#œuÔ%ÜÜÐ4´T¸#³Y°KÐ?PÐQÓRóð ô ˆs‹8�d×)Ñ)Ò)Üœ NÓ3Ó4Ð4Ü˜#œuÔ%ÜÜÐ6´t¸C³y°kÐARÐSÓTóð ñ Ø˜‘*ˆCÜ�S“ˆà�I‰IØ�cœ=¨°u¸jÈ&Ð6QÑ)QÓRÐSóð ñð 	ð 	�‰�gÔØ�‰�cÔÜ˜ #¨U¸6ÔBˆØ�‰×Ñ˜VÔ$Ø×ÑÐr   c                 ó.   — | j                  d||ddd«      S )aœ  
        Append given data to the value of an existing key.

        @param key: The key to modify.
        @type key: L{bytes}

        @param val: The value to append to the current value associated with
            the key.
        @type val: L{bytes}

        @return: A deferred that will fire with C{True} if the operation has
            succeeded, C{False} otherwise.
        @rtype: L{Deferred}
        s   appendr   r   r¥   r”   s      r   rL   zMemCacheProtocol.append  s   € ð  �y‰y˜ C¨¨a°°CÓ8Ð8r   c                 ó.   — | j                  d||ddd«      S )až  
        Prepend given data to the value of an existing key.

        @param key: The key to modify.
        @type key: L{bytes}

        @param val: The value to prepend to the current value associated with
            the key.
        @type val: L{bytes}

        @return: A deferred that will fire with C{True} if the operation has
            succeeded, C{False} otherwise.
        @rtype: L{Deferred}
        s   prependr   r   r¥   r”   s      r   ÚprependzMemCacheProtocol.prepend'  s   € ð  �y‰y˜ S¨#¨q°!°SÓ9Ð9r   c                 ó*   — | j                  |g|d«      S )a¾  
        Get the given C{key}. It doesn't support multiple keys. If
        C{withIdentifier} is set to C{True}, the command issued is a C{gets},
        that will return the current identifier associated with the value. This
        identifier has to be used when issuing C{checkAndSet} update later,
        using the corresponding method.

        @param key: The key to retrieve.
        @type key: L{bytes}

        @param withIdentifier: If set to C{True}, retrieve the current
            identifier along with the value and the flags.
        @type withIdentifier: L{bool}

        @return: A deferred that will fire with the tuple (flags, value) if
            C{withIdentifier} is C{False}, or (flags, cas identifier, value)
            if C{True}.  If the server indicates there is no value
            associated with C{key}, the returned value will be L{None} and
            the returned flags will be C{0}.
        @rtype: L{Deferred}
        F©Ú_get)r"   rf   ÚwithIdentifiers      r   ÚgetzMemCacheProtocol.get9  s   € ð, �y‰y˜#˜ °Ó6Ð6r   c                 ó(   — | j                  ||d«      S )a  
        Get the given list of C{keys}.  If C{withIdentifier} is set to C{True},
        the command issued is a C{gets}, that will return the identifiers
        associated with each values. This identifier has to be used when
        issuing C{checkAndSet} update later, using the corresponding method.

        @param keys: The keys to retrieve.
        @type keys: L{list} of L{bytes}

        @param withIdentifier: If set to C{True}, retrieve the identifiers
            along with the values and the flags.
        @type withIdentifier: L{bool}

        @return: A deferred that will fire with a dictionary with the elements
            of C{keys} as keys and the tuples (flags, value) as values if
            C{withIdentifier} is C{False}, or (flags, cas identifier, value) if
            C{True}.  If the server indicates there is no value associated with
            C{key}, the returned values will be L{None} and the returned flags
            will be C{0}.
        @rtype: L{Deferred}

        @since: 9.0
        Trµ   )r"   rn   r·   s      r   ÚgetMultiplezMemCacheProtocol.getMultipleQ  s   € ð0 �y‰y˜˜~¨tÓ4Ð4r   c           	      óF  — t        |«      }| j                  rt        t        d«      «      S |D ]c  }t	        |t
        «      s#t        t        dt        |«      › d�«      «      c S t        |«      | j                  kD  sŒOt        t        d«      «      c S  |rd}nd}dj                  |g|z   «      }| j                  |«       |r |D �ci c]  }|d“Œ }}t        |||d	¬
«      }nt        ||d   dddd¬«      }| j                  j                  |«       |j                  S c c}w )z>
        Helper method for C{get} and C{getMultiple}.
        r™   rš   r›   rœ   rb   ra   rs   )r   r   NT)rn   rP   rO   r   Nr   F)rf   r)   rW   rX   rO   )ÚlistrC   r   rd   rž   rŸ   r   r    rM   r¡   rN   rG   r   r2   rL   r   )	r"   rn   r·   rO   rf   r;   r¢   rP   r£   s	            r   r¶   zMemCacheProtocol._getk  s!  € ô �D‹zˆØ×ÒÜœ _Ó5Ó6Ð6Øò 	9ˆCÜ˜c¤5Ô)ÜÜÐ"8¼¸c»¸ÐCTÐ UÓVóò ô �3‹x˜$×-Ñ-Ó-ÜœK¨Ó7Ó8Ò8ð	9ñ Ø‰CàˆCØ—)‘)˜S˜E D™LÓ)ˆØ�‰�gÔÙØ59Ö:¨c�c˜>Ñ)Ð:ˆFÐ:Ü˜S t°FÀTÔJ‰FäØ˜˜a™¨°A¸3ÈôˆFð 	�‰×Ñ˜VÔ$Ø×ÑÐùò ;s   Ã
DNc                 óà   — |rd|z   }nd}| j                   rt        t        d«      «      S | j                  |«       t	        di ¬«      }| j
                  j                  |«       |j                  S )aí  
        Get some stats from the server. It will be available as a dict.

        @param arg: An optional additional string which will be sent along
            with the I{stats} command.  The interpretation of this value by
            the server is left undefined by the memcache protocol
            specification.
        @type arg: L{None} or L{bytes}

        @return: a deferred that will fire with a L{dict} of the available
            statistics.
        @rtype: L{Deferred}
        s   stats rc   r™   )rP   ©rC   r   rd   rG   r   r2   rL   r   )r"   Úargr;   r£   s       r   ÚstatszMemCacheProtocol.stats‰  sd   € ñ Ø˜c‘/‰CàˆCØ×ÒÜœ _Ó5Ó6Ð6Ø�‰�cÔÜ˜¨"Ô-ˆØ�‰×Ñ˜VÔ$Ø×ÑÐr   c                 óÈ   — | j                   rt        t        d«      «      S | j                  d«       t	        d«      }| j
                  j                  |«       |j                  S )zª
        Get the version of the server.

        @return: a deferred that will fire with the string value of the
            version.
        @rtype: L{Deferred}
        r™   s   versionr¾   ©r"   r£   s     r   ÚversionzMemCacheProtocol.version¢  sQ   € ð ×ÒÜœ _Ó5Ó6Ð6Ø�‰�jÔ!Ü˜Ó$ˆØ�‰×Ñ˜VÔ$Ø×ÑÐr   c                 ó4  — | j                   rt        t        d«      «      S t        |t        «      s!t        t        dt        |«      › d�«      «      S | j                  d|z   «       t        d|¬«      }| j                  j                  |«       |j                  S )a  
        Delete an existing C{key}.

        @param key: the key to delete.
        @type key: L{bytes}

        @return: a deferred that will be called back with C{True} if the key
            was successfully deleted, or C{False} if not.
        @rtype: L{Deferred}
        r™   rš   r›   s   delete s   deleter�   )rC   r   rd   rž   rŸ   r   r    rG   r   r2   rL   r   )r"   rf   r£   s      r   ÚdeletezMemCacheProtocol.delete±  sˆ   € ð ×ÒÜœ _Ó5Ó6Ð6Ü˜#œuÔ%ÜÜÐ4´T¸#³Y°KÐ?PÐQÓRóð ð 	�‰�j 3Ñ&Ô'Ü˜¨Ô,ˆØ�‰×Ñ˜VÔ$Ø×ÑÐr   c                 óÈ   — | j                   rt        t        d«      «      S | j                  d«       t	        d«      }| j
                  j                  |«       |j                  S )z·
        Flush all cached values.

        @return: a deferred that will be called back with C{True} when the
            operation has succeeded.
        @rtype: L{Deferred}
        r™   s	   flush_allr¾   rÂ   s     r   ÚflushAllzMemCacheProtocol.flushAllÇ  sQ   € ð ×ÒÜœ _Ó5Ó6Ð6Ø�‰�lÔ#Ü˜Ó&ˆØ�‰×Ñ˜VÔ$Ø×ÑÐr   )é<   )rt   )r   r   )F)N)+r   r   r   r   r¡   rC   r&   r<   rA   rD   rG   rY   r\   r_   rg   ri   rq   ru   rx   r{   r€   r‚   r„   r†   rˆ   r�   r•   r—   r“   r�   rª   r­   r¯   r¦   rL   r³   r¸   rº   r¶   rÀ   rÃ   rÅ   rÇ   r   r   r   r/   r/   c   sÐ   „ ñð2 €NØ€Mó8òò(ò2ò*ò"ò..ò/òò2/òò2ò5ò"ò'ò'ò.ò.ò/ò"ó:1ó"1ò$ ó$Gó.Có.Có.Cò8 ò>9ò$:ó$7ó05ò4 ó< ò2 ò ó, r   r/   )r/   ÚDEFAULT_PORTr   r   r   N)r   Úcollectionsr   Útwisted.internet.deferr   r   r   Útwisted.protocols.basicr   Útwisted.protocols.policiesr   Útwisted.pythonr	   Útwisted.python.compatr
   r   rÉ   Ú	Exceptionr   r   r   r   r/   Ú__all__r   r   r   ú<module>rÒ      sm   ðñ
õ0 ç ?Ñ ?Ý 0Ý 3Ý ß =à€ô�Iô ô�)ô ô�)ô ÷&&ñ &&ôRq	 �| \ô q	 òh�r   