o
    ¯bi'  ã                   @   s„   d Z ddlZddlZddlZddlZddlmZ ze W n ey'   e	ZY nw G dd„ dƒZ
G dd„ de
ƒZddd	„Z	g d
¢ZdS )a„  
DBM-style interface to a directory.

Each key is stored as a single file.  This is not expected to be very fast or
efficient, but it's good for easy debugging.

DirDBMs are *not* thread-safe, they should only be accessed by one thread at
a time.

No files should be placed in the working directory of a DirDBM save those
created by the DirDBM itself!

Maintainer: Itamar Shtull-Trauring
é    N)ÚFilePathc                   @   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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d „Zd!d"„ Zd#d$„ Zd%d&„ Zd'd(„ Zd)d*„ Zd+d,„ ZdS ).ÚDirDBMz®
    A directory with a DBM interface.

    This class presents a hash-like interface to a directory of small,
    flat files. It can only use strings as keys or values.
    c                 C   s¦   t j |¡| _t|ƒ| _| j ¡ s| j ¡  dS t | j 	d¡j¡D ]}t  
|¡ q"t | j 	d¡j¡}|D ]}|dd… }t j |¡rJt  
|¡ q6t  ||¡ q6dS )zb
        @type name: str
        @param name: Base path to use for the directory storage.
        z*.newz*.rplNéüÿÿÿ)ÚosÚpathÚabspathÚdnamer   Ú
_dnamePathÚisdirÚcreateDirectoryÚglobÚchildÚremoveÚexistsÚrename)ÚselfÚnameÚfÚreplacementsÚold© r   ú:/usr/lib/python3/dist-packages/twisted/persisted/dirdbm.pyÚ__init__,   s   


ûzDirDBM.__init__c                 C   s   t  |¡ dd¡ dd¡S )z?
        Encode a key so it can be used as a filename.
        ó   
ó   _ó   /ó   -)Úbase64ÚencodebytesÚreplace©r   Úkr   r   r   Ú_encodeH   s   zDirDBM._encodec                 C   s   t  | dd¡ dd¡¡S )z3
        Decode a filename to get the key.
        r   r   r   r   )r   Údecodebytesr   r    r   r   r   Ú_decodeO   ó   zDirDBM._decodec                 C   s:   t |jdƒ�}| ¡ }W d  ƒ |S 1 sw   Y  |S )z�
        Read in the contents of a file.

        Override in subclasses to e.g. provide transparently encrypted dirdbm.
        ÚrbN)Ú_openr   Úread)r   r   r   Úsr   r   r   Ú	_readFileU   s   

ÿþzDirDBM._readFilec                 C   sD   t |jdƒ�}| |¡ | ¡  W d  ƒ dS 1 sw   Y  dS )zw
        Write data to a file.

        Override in subclasses to e.g. provide transparently encrypted dirdbm.
        ÚwbN)r'   r   ÚwriteÚflush)r   r   Údatar   r   r   r   Ú
_writeFile_   s   

"þzDirDBM._writeFilec                 C   s   t | j ¡ ƒS )zF
        @return: The number of key/value pairs in this Shelf
        )Úlenr	   Úlistdir©r   r   r   r   Ú__len__i   s   zDirDBM.__len__c                 C   s¤   t |ƒtks
tdƒ‚t |ƒtkstdƒ‚|  |¡}| j |¡}| ¡ r)| d¡}n| d¡}z|  ||¡ W n t	yB   | 
¡  ‚ w | ¡ rK| 
¡  | |¡ dS )zÔ
        C{dirdbm[k] = v}
        Create or modify a textfile in this directory

        @type k: bytes
        @param k: key to set

        @type v: bytes
        @param v: value to associate with C{k}
        úDirDBM key must be byteszDirDBM value must be bytesz.rplz.newN)ÚtypeÚbytesÚ	TypeErrorr"   r	   r   r   ÚsiblingExtensionr/   ÚBaseExceptionr   ÚmoveTo)r   r!   Úvr   Únewr   r   r   Ú__setitem__o   s$   

þzDirDBM.__setitem__c                 C   sJ   t |ƒtks
tdƒ‚| j |  |¡¡}z|  |¡W S  ty$   t|ƒ‚w )a  
        C{dirdbm[k]}
        Get the contents of a file in this directory as a string.

        @type k: bytes
        @param k: key to lookup

        @return: The value associated with C{k}
        @raise KeyError: Raised when there is no such key
        r4   )	r5   r6   r7   r	   r   r"   r*   ÚOSErrorÚKeyError)r   r!   r   r   r   r   Ú__getitem__‘   s   ÿzDirDBM.__getitem__c                 C   sR   t |ƒtks
tdƒ‚|  |¡}z| j |¡ ¡  W dS  ty(   t|  	|¡ƒ‚w )zÀ
        C{del dirdbm[foo]}
        Delete a file in this directory.

        @type k: bytes
        @param k: key to delete

        @raise KeyError: Raised when there is no such key
        r4   N)
r5   r6   r7   r"   r	   r   r   r>   r?   r$   r    r   r   r   Ú__delitem__¤   s   

ÿzDirDBM.__delitem__c                 C   s   t t| j| j ¡  ¡ ƒƒS )z9
        @return: a L{list} of filenames (keys).
        )ÚlistÚmapr$   r	   ÚasBytesModer1   r2   r   r   r   Úkeys¶   r%   zDirDBM.keysc                 C   s(   g }|   ¡ }|D ]	}| | | ¡ q|S )z?
        @return: a L{list} of file-contents (values).
        ©rE   Úappend)r   ÚvalsrE   Úkeyr   r   r   Úvalues¼   s
   zDirDBM.valuesc                 C   s,   g }|   ¡ }|D ]}| || | f¡ q|S )zL
        @return: a L{list} of 2-tuples containing key/value pairs.
        rF   )r   ÚitemsrE   rI   r   r   r   rK   Æ   s
   zDirDBM.itemsc                 C   s.   t |ƒtks
tdƒ‚|  |¡}| j |¡ ¡ S )z¬
        @type key: bytes
        @param key: The key to test

        @return: A true value if this dirdbm has the specified key, a false
        value otherwise.
        r4   )r5   r6   r7   r"   r	   r   Úisfile©r   rI   r   r   r   Úhas_keyÐ   s   
zDirDBM.has_keyc                 C   s   || vr
|| |< |S | | S )z¶
        @type key: bytes
        @param key: The key to lookup

        @param value: The value to associate with key if key is not already
        associated with a value.
        r   )r   rI   Úvaluer   r   r   Ú
setdefaultÝ   s   zDirDBM.setdefaultNc                 C   s   || v r| | S |S )zü
        @type key: bytes
        @param key: The key to lookup

        @param default: The value to return if the given key does not exist

        @return: The value associated with C{key} or C{default} if not
        L{DirDBM.has_key(key)}
        r   )r   rI   Údefaultr   r   r   Úgetê   s   
z
DirDBM.getc                 C   s
   |   |¡S )z)
        @see: L{DirDBM.has_key}
        )rN   rM   r   r   r   Ú__contains__ù   s   
zDirDBM.__contains__c                 C   s   |  ¡ D ]\}}|| |< qdS )zþ
        Add all the key/value pairs in L{dict} to this dirdbm.  Any conflicting
        keys will be overwritten with the values from L{dict}.

        @type dict: mapping
        @param dict: A mapping of key/value pairs to add to this dirdbm.
        N)rK   )r   ÚdictrI   Úvalr   r   r   Úupdateÿ   s   
ÿzDirDBM.updatec                 C   sH   t |ƒ}|| jksJ ‚|  |j¡}| ¡  |  ¡ D ]}| | ||< q|S )a<  
        Copy the contents of this dirdbm to the dirdbm at C{path}.

        @type path: L{str}
        @param path: The path of the dirdbm to copy to.  If a dirdbm
        exists at the destination path, it is cleared first.

        @rtype: C{DirDBM}
        @return: The dirdbm this dirdbm was copied to.
        )r   r	   Ú	__class__r   ÚclearrE   )r   r   Údr!   r   r   r   ÚcopyTo
  s   zDirDBM.copyToc                 C   s   |   ¡ D ]}| |= qdS )z<
        Delete all key/value pairs in this dirdbm.
        N)rE   r    r   r   r   rX     s   ÿzDirDBM.clearc                 C   s   dS )zL
        Close this dbm: no-op, for dbm-style interface compliance.
        Nr   r2   r   r   r   Úclose%  s    zDirDBM.closec                 C   s>   t |ƒtks
tdƒ‚| j |  |¡¡}| ¡ r| ¡ S t|ƒ‚)zÁ
        Returns modification time of an entry.

        @return: Last modification date (seconds since epoch) of entry C{key}
        @raise KeyError: Raised when there is no such key
        r4   )	r5   r6   r7   r	   r   r"   rL   ÚgetModificationTimer?   )r   rI   r   r   r   r   r\   *  s   zDirDBM.getModificationTime)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r"   r$   r*   r/   r3   r=   r@   rA   rE   rJ   rK   rN   rP   rR   rS   rV   rZ   rX   r[   r\   r   r   r   r   r   $   s.    

"


r   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚShelfzÃ
    A directory with a DBM shelf interface.

    This class presents a hash-like interface to a directory of small,
    flat files. Keys must be strings, but values can be any given object.
    c                 C   s   t  |¡}t | ||¡ dS )zÉ
        C{shelf[foo] = bar}
        Create or modify a textfile in this directory.

        @type k: str
        @param k: The key to set

        @param v: The value to associate with C{key}
        N)ÚpickleÚdumpsr   r=   )r   r!   r;   r   r   r   r=   B  s   

zShelf.__setitem__c                 C   s   t  t | |¡¡S )a  
        C{dirdbm[foo]}
        Get and unpickle the contents of a file in this directory.

        @type k: bytes
        @param k: The key to lookup

        @return: The value associated with the given key
        @raise KeyError: Raised if the given key does not exist
        )rb   Úloadsr   r@   r    r   r   r   r@   O  s   zShelf.__getitem__N)r]   r^   r_   r`   r=   r@   r   r   r   r   ra   :  s    ra   c                 C   s   t | ƒS )z£
    This is for 'anydbm' compatibility.

    @param file: The parameter to pass to the DirDBM constructor.

    @param flag: ignored
    @param mode: ignored
    )r   )ÚfileÚflagÚmoder   r   r   Úopen]  s   	rh   )rh   r   ra   )NN)r`   r   r   r   rb   Útwisted.python.filepathr   r'   Ú	NameErrorrh   r   ra   Ú__all__r   r   r   r   Ú<module>   s"   ÿ  
#