o
    b*                     @   s   d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	 dd Z
dd	 Zd
d Zdd ZG dd dZG dd dejZG dd deZG dd deZG dd dejZdd Zdd ZdS )zE
Dict client protocol implementation.

@author: Pavel Pergamenshchik
    )BytesIO)deferprotocol)basic)logc                 C   s   | dkrdS | dd dkrd}nd}d}t | }|dkr"|d 	 |d}|dkr<|dkr;|d || fS n2|dkrN|d}|dkrMd| fS n |dkr`|dkr\|| fS d| fS |d	krn|dkrn|| fS ||7 }q#)
zQChew one dqstring or atom from beginning of line and return (param, remaningline)    )Nr   r         "      \N    )r   read)linemoderesioa r   8/usr/lib/python3/dist-packages/twisted/protocols/dict.py
parseParam   s<   



r   c                 C   s   t dd | S )zMunch a string into an 'atom'c                 S   s   | t ttdg d vS )N!   "   '   \   )mapchrrange)xr   r   r   <lambda>6   s    zmakeAtom.<locals>.<lambda>)filterr   r   r   r   makeAtom3   s   r"   c                 C   sL   t dg d }g }| D ]}t||v r|d || qd|} | S )Nr   r   r   r   )r   ordappendjoin)s	mustquoteresultcr   r   r   makeWord9   s   

r*   c                 C   sD   t | dkr| dkrd S t | dkr | dd dkr | dd  } | S )Nr      .r   r
   s   ..)lenr!   r   r   r   	parseTextD   s
   r-   c                   @   s   e Zd ZdZdd ZdS )
DefinitionzA word definitionc                 C   s   || _ || _|| _|| _d S N)namedbdbdesctext)selfr0   r1   r2   r3   r   r   r   __init__P      
zDefinition.__init__N)__name__
__module____qualname____doc__r5   r   r   r   r   r.   M   s    r.   c                   @   s  e Zd ZdZdZdZdZdZdZdZ	dd Z
dd Zdd	 Zd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zd d! Zd"d# Zd$d% Zd&d' Zd(d) Zd*d+ Zd,d- Zd.d/ Zd0d1 Z d2d3 Z!d4d5 Z"d6d7 Z#d8d9 Z$d:d; Z%d<d= Z&d>d? Z'dS )@
DictClientzdict (RFC2229) clientNi   c                 C   s   d | _ d | _d S r/   )datar(   r4   r   r   r   r5   a      
zDictClient.__init__c                 C   s   d| _ d| _d S )Nconncommand)stater   r=   r   r   r   connectionMadee   r>   zDictClient.connectionMadec                 C   s,   t || jd krtdtj| | dS )z3Throw up if the line is longer than 1022 charactersr
   z(DictClient tried to send a too long lineN)r,   
MAX_LENGTH
ValueErrorr   LineReceiversendLiner4   r   r   r   r   rF   i   s   zDictClient.sendLinec                 C   s   z| d}W n
 ty   Y d S w | jdkrd}n't|dk r3td|  | d | j  d S t	|d d }|dd  }t
| d| d| j | j}|| d S )	Nzutf-8r3      z-DictClient got invalid line from server -- %szInvalid line from server   	dictCode__)decodeUnicodeErrorr   r,   r   msgprotocolError	transportLoseConnectionintgetattrrA   dictCode_default)r4   r   codemethodr   r   r   lineReceivedo   s    


zDictClient.lineReceivedc                 C   s&   t d|  | d | j  dS )zUnknown messagez3DictClient got unexpected message from server -- %szUnexpected server messageN)r   rN   rO   rP   loseConnectionrG   r   r   r   rT      s   
zDictClient.dictCode_defaultc                 C      dS )z*We are about to get kicked off, do nothingNr   rG   r   r   r   dictCode_221_ready      zDictClient.dictCode_221_readyc                 C   s   d| _ |   dS )zGreeting messagereadyN)rA   dictConnectedrG   r   r   r   dictCode_220_conn   s   zDictClient.dictCode_220_connc                 C      |  d | j  d S )NzAccess deniedrO   rP   rX   r=   r   r   r   dictCode_530_conn      
zDictClient.dictCode_530_connc                 C   r_   )NzServer temporarily unavailabler`   r=   r   r   r   dictCode_420_conn   rb   zDictClient.dictCode_420_connc                 C   r_   )Nz(Server shutting down at operator requestr`   r=   r   r   r   dictCode_421_conn   rb   zDictClient.dictCode_421_connc                 C   sR   | j dks	J dd| _d| _d| _ dt|dt|d}| | dS )zSend a dict DEFINE commandr\   z4DictClient.sendDefine called when not in ready stateNdefinezDEFINE {} {}UTF-8)rA   r(   r<   formatr"   encoder*   rF   )r4   databasewordr@   r   r   r   
sendDefine   s   zDictClient.sendDefinec                 C   sR   | j dks	J dd| _d| _d| _ dt|t|t|}| |d dS )zSend a dict MATCH commandr\   z3DictClient.sendMatch called when not in ready stateNmatchzMATCH {} {} {}rf   )rA   r(   r<   rg   r"   rF   rh   )r4   ri   strategyrj   r@   r   r   r   	sendMatch   s   zDictClient.sendMatchc                 C      d| _ | d  dS zInvalid databaser\   Nr   defineFailedrG   r   r   r   dictCode_550_define      zDictClient.dictCode_550_definec                 C   ro   rp   r   matchFailedrG   r   r   r   dictCode_550_match   rt   zDictClient.dictCode_550_matchc                 C   ro   )zInvalid strategyr\   Nru   rG   r   r   r   dictCode_551_match   rt   zDictClient.dictCode_551_matchc                 C   ro   zNo matchr\   Nrq   rG   r   r   r   dictCode_552_define   rt   zDictClient.dictCode_552_definec                 C   ro   ry   ru   rG   r   r   r   dictCode_552_match   rt   zDictClient.dictCode_552_matchc                 C   s
   g | _ dS )zn definitions retrievedN)r(   rG   r   r   r   dictCode_150_define   s   
zDictClient.dictCode_150_definec                 C   sn   d| _ t|\}}t|\}}t|\}}|r|r|s'| d | j  dS | jt|||g  g | _dS )zDefinition text followsr3   zInvalid server responseN)	r   r   rO   rP   rX   r(   r$   r.   r<   )r4   r   rj   r1   r2   r   r   r   dictCode_151_define   s   

zDictClient.dictCode_151_definec                 C   s   d| _ g | _g | _dS )zn matches found, text followsr3   N)r   r(   r<   rG   r   r   r   dictCode_152_match   s   
zDictClient.dictCode_152_matchc                 C   s>   t |}|dkrd| _| j| jd _d| _dS | j| dS )z"A line of definition text receivedNr@   )r-   r   r<   r(   r3   r$   )r4   r   r   r   r   r   dictCode_text_define   s   
zDictClient.dictCode_text_definec                 C   sF   dd }t |}|dkrd| _t|| j| _d| _dS | j| dS )zOne line of match text receivedc                 S   s    t | \}}t |\}}||fS r/   )r   )r&   p1tp2r   r   r   l   s   z)DictClient.dictCode_text_match.<locals>.lNr@   )r-   r   r   r<   r(   r$   )r4   r   r   r   r   r   r   dictCode_text_match   s   
zDictClient.dictCode_text_matchc                 C       | j }d| _ d| _| | dS okNr\   )r(   rA   
defineDoner4   r   r   r   r   r   dictCode_250_define     zDictClient.dictCode_250_definec                 C   r   r   )r(   rA   	matchDoner   r   r   r   dictCode_250_match  r   zDictClient.dictCode_250_matchc                 C   rY   )z5override to catch unexpected dict protocol conditionsNr   r4   reasonr   r   r   rO     r[   zDictClient.protocolErrorc                 C   rY   )zCoverride to be notified when the server is ready to accept commandsNr   r=   r   r   r   r]     r[   zDictClient.dictConnectedc                 C   rY   )z8override to catch reasonable failure responses to DEFINENr   r   r   r   r   rr     r[   zDictClient.defineFailedc                 C   rY   )z#override to catch successful DEFINENr   r4   r(   r   r   r   r     r[   zDictClient.defineDonec                 C   rY   )z7override to catch reasonable failure responses to MATCHNr   r   r   r   r   rv   #  r[   zDictClient.matchFailedc                 C   rY   )z"override to catch successful MATCHNr   r   r   r   r   r   '  r[   zDictClient.matchDone)(r7   r8   r9   r:   r<   rC   rA   r   r(   factoryr5   rB   rF   rW   rT   rZ   r^   ra   rc   rd   rk   rn   rs   rw   rx   rz   r{   r|   r}   r~   r   r   r   r   rO   r]   rr   r   rv   r   r   r   r   r   r;   W   sL    
r;   c                   @   s   e Zd ZdS )InvalidResponseN)r7   r8   r9   r   r   r   r   r   ,  s    r   c                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )
DictLookupzNUtility class for a single dict transaction. To be used with DictLookupFactoryc                 C   s,   | j js| j jt| | j   d S d S r/   )r   donederrbackr   
clientDoner   r   r   r   rO   3  s   zDictLookup.protocolErrorc                 C   s@   | j jdkr| j| j j  d S | j jdkr| j| j j  d S d S )Nre   rl   )r   	queryTyperk   paramrn   r=   r   r   r   r]   8  s
   zDictLookup.dictConnectedc                 C   &   | j jg  | j   | j  d S r/   r   r   callbackr   rP   rX   r   r   r   r   rr   >     
zDictLookup.defineFailedc                 C   &   | j j| | j   | j  d S r/   r   r   r   r   r   r   C  r   zDictLookup.defineDonec                 C   r   r/   r   r   r   r   r   rv   H  r   zDictLookup.matchFailedc                 C   r   r/   r   r   r   r   r   r   M  r   zDictLookup.matchDoneN)
r7   r8   r9   r:   rO   r]   rr   r   rv   r   r   r   r   r   r   0  s    r   c                   @   s@   e Zd ZdZeZdZdd Zdd Zdd Z	d	d
 Z
dd ZdS )DictLookupFactoryz-Utility factory for a single dict transactionNc                 C   s   || _ || _|| _d| _d S )Nr   )r   r   r   r   )r4   r   r   r   r   r   r   r5   Y  r6   zDictLookupFactory.__init__c                 C   s   d| _ | `dS )zCalled by client when done.r   N)r   r   r=   r   r   r   r   _  s   zDictLookupFactory.clientDonec                 C   s   | j | d S r/   )r   r   r4   	connectorerrorr   r   r   clientConnectionFailedd  s   z(DictLookupFactory.clientConnectionFailedc                 C   s   | j s| j| d S d S r/   )r   r   r   r   r   r   r   clientConnectionLostg  s   z&DictLookupFactory.clientConnectionLostc                 C   s   |   }| |_|S r/   )r   r   )r4   addrpr   r   r   buildProtocolk  s   zDictLookupFactory.buildProtocol)r7   r8   r9   r:   r   r   r   r5   r   r   r   r   r   r   r   r   r   S  s    r   c                 C   s6   t  }td||f|}ddlm} || || |S )z"Look up a word using a dict serverre   r   reactorr   Deferredr   twisted.internetr   
connectTCP)hostportri   rj   r   r   r   r   r   r   re   q  s
   re   c                 C   s8   t  }td|||f|}ddlm} || || |S )z Match a word using a dict serverrl   r   r   r   )r   r   ri   rm   rj   r   r   r   r   r   r   rl   |  s
   rl   N)r:   r   r   r   r   r   twisted.protocolsr   twisted.pythonr   r   r"   r*   r-   r.   rE   r;   	Exceptionr   r   ClientFactoryr   re   rl   r   r   r   r   <module>   s"   !	
 V#