U
    W['                     @   s   d Z ddlZddlZddlZzddlZW n ek
rD   ddlZY nX ddlmZ ze	 W n e
k
rr   eZ	Y nX G dd dZG dd deZd
dd	Zd	ddg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  nrt| j	djD ]}t 
| qBt| j	dj}|D ]4}|dd }t j|rt 
| qjt || qjdS )zb
        @type name: str
        @param name: Base path to use for the directory storage.
        z*.newz*.rplN)ospathabspathZdnamer   
_dnamePathisdirZcreateDirectoryglobchildremoveexistsrename)selfnamefZreplacementsold r   :/usr/lib/python3/dist-packages/twisted/persisted/dirdbm.py__init__2   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.
           
   _   /   -)base64Zencodestringreplacer   kr   r   r   _encodeO   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   Zdecodestringr   r   r   r   r   _decodeW   s    zDirDBM._decodec              	   C   s$   t |jd}| }W 5 Q R X |S )z
        Read in the contents of a file.

        Override in subclasses to e.g. provide transparently encrypted dirdbm.
        rb)_openr   read)r   r   r   sr   r   r   	_readFile^   s    zDirDBM._readFilec              	   C   s.   t |jd}|| |  W 5 Q R X 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   
_writeFilei   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__t   s    zDirDBM.__len__c                 C   s   t |tkstdt |tks(td| |}| j|}| rR|d}n
|d}z| || W n   |	   Y nX | r|	  |
| 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   ZsiblingExtensionr)   r   ZmoveTo)r   r   vr   newr   r   r   __setitem__{   s"    

 zDirDBM.__setitem__c                 C   sT   t |tkstd| j| |}z| |W S  tk
rN   t|Y nX dS )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
        r.   N)	r/   r0   r1   r   r   r   r$   EnvironmentErrorKeyError)r   r   r   r   r   r   __getitem__   s    zDirDBM.__getitem__c                 C   sZ   t |tkstd| |}z| j|  W n" tk
rT   t| 	|Y nX dS )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
        r.   N)
r/   r0   r1   r   r   r   r   r5   r6   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   ZasBytesModer+   r,   r   r   r   keys   s    zDirDBM.keysc                 C   s(   g }|   }|D ]}|| |  q|S )z?
        @return: a L{list} of file-contents (values).
        r;   append)r   Zvalsr;   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.
        r<   )r   itemsr;   r>   r   r   r   r@      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.
        r.   )r/   r0   r1   r   r   r   isfiler   r>   r   r   r   has_key   s    
zDirDBM.has_keyc                 C   s   || k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   r>   valuer   r   r   
setdefault   s    zDirDBM.setdefaultNc                 C   s   || kr| | S |S d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)}
        Nr   )r   r>   defaultr   r   r   get   s    
z
DirDBM.getc                 C   s
   |  |S )z)
        @see: L{DirDBM.has_key}
        )rC   rB   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)r@   )r   dictr>   valr   r   r   update  s    zDirDBM.updatec                 C   sH   t |}|| jkst| |j}|  |  D ]}| | ||< q2|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   AssertionError	__class__r   clearr;   )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)r;   r   r   r   r   rN   5  s    zDirDBM.clearc                 C   s   dS )zL
        Close this dbm: no-op, for dbm-style interface compliance.
        Nr   r,   r   r   r   close=  s    zDirDBM.closec                 C   sB   t |tkstd| j| |}| r6| S t|dS )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
        r.   N)	r/   r0   r1   r   r   r   rA   getModificationTimer6   )r   r>   r   r   r   r   rR   C  s    zDirDBM.getModificationTime)N)__name__
__module____qualname____doc__r   r   r   r$   r)   r-   r4   r7   r8   r;   r?   r@   rC   rE   rG   rH   rK   rP   rN   rQ   rR   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   r4   )r   r   r2   r   r   r   r4   \  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
        )rX   loadsr   r7   r   r   r   r   r7   j  s    zShelf.__getitem__N)rS   rT   rU   rV   r4   r7   r   r   r   r   rW   T  s   rW   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   openy  s    	r^   )NN)rV   r   r   r
   ZcPicklerX   ImportErrorZtwisted.python.filepathr   r!   	NameErrorr^   r   rW   __all__r   r   r   r   <module>   s$   
  ,%
