U
    xÊ¹j¾  ã                   @   sÐ   d dl mZ d dlmZmZmZmZmZmZm	Z	 d dl
Z
d dlmZ d dlmZ d dlmZ d dlmZ d dlmZ eeeeeeƒZe dejegeej¡Zeed	ƒZed
d
ejfdd„ƒZG dd„ deƒZdS )é    )Úcontextmanager)Ú	CFUNCTYPEÚPOINTERÚc_intÚ
c_longlongÚc_void_pÚcastÚcreate_string_bufferN)Ú
open_files)ÚAbstractArchiveFileSystem)Ú
MemoryFile)ÚDEFAULT_BLOCK_SIZEÚread_set_seek_callbackÚ
NO_OPEN_CBÚallc              	   #   s¶   t |ƒ‰ tˆ tƒ‰‡ ‡‡fdd„}‡fdd„}t |¡}t|ƒ}trRtj}tj}	nt	j
 tj¡}t	j
 tj¡}	t	j
 ||¡�0}
t|
|ƒ t |
d|||	¡ t	j
 |
¡V  W 5 Q R X dS )z†Read an archive from a seekable file-like object.

    The `file` object must support the standard `readinto` and 'seek' methods.
    c                    s$   ˆ  ˆ ¡}t|ttƒƒ}ˆ|d< |S )Nr   )Úreadintor   r   r   )Ú	archive_pÚcontextZptrptrÚlength©ÚbufZbuf_pÚfile© ú`/var/www/html/bwave/python/venv/lib/python3.8/site-packages/fsspec/implementations/libarchive.pyÚ	read_func*   s    
z custom_reader.<locals>.read_funcc                    s   ˆ   ||¡ ˆ  ¡ S )N)ÚseekÚtell)r   r   ÚoffsetÚwhence)r   r   r   Ú	seek_func3   s    z custom_reader.<locals>.seek_funcN)r	   r   r   ÚffiZREAD_CALLBACKÚSEEK_CALLBACKÚnew_apir   ZNO_CLOSE_CBÚ
libarchiveÚreadZOPEN_CALLBACKZVOID_CBZCLOSE_CALLBACKZnew_archive_readr   Z	read_openZArchiveRead)r   Úformat_nameZfilter_nameÚ
block_sizer   r   Zread_cbZseek_cbZopen_cbZclose_cbr   r   r   r   Úcustom_reader!   s    
	

r'   c                       sf   e Zd ZdZdZdZdZddddef‡ fdd„	Ze	d	d
„ ƒZ
e‡ fdd„ƒZdd„ Zddd„Z‡  ZS )ÚLibArchiveFileSystemay  Compressed archives as a file-system (read-only)

    Supports the following formats:
    tar, pax , cpio, ISO9660, zip, mtree, shar, ar, raw, xar, lha/lzh, rar
    Microsoft CAB, 7-Zip, WARC

    See the libarchive documentation for further restrictions.
    https://www.libarchive.org/

    Keeps file object open while instance lives. It only works in seekable
    file-like objects. In case the filesystem does not support this kind of
    file object, it is recommended to cache locally.

    This class is pickleable, but not necessarily thread-safe (depends on the
    platform). See libarchive documentation for details.
    Ú r#   FÚrNc                    sŒ   t ƒ j| f|Ž |dkr tdƒ‚t|tƒrlt|fd|i|p<i —Ž}t|ƒdkrdtd|› d|› d�ƒ‚|d }|| _| ¡ | _	|| _
d	| _d	S )
aB  
        Parameters
        ----------
        fo: str or file-like
            Contains ZIP, and must exist. If a str, will fetch file using
            :meth:`~fsspec.open_files`, which must return one file exactly.
        mode: str
            Currently, only 'r' accepted
        target_protocol: str (optional)
            If ``fo`` is a string, this value can be used to override the
            FS protocol inferred from a URL
        target_options: dict (optional)
            Kwargs passed when instantiating the target FS, if ``fo`` is
            a string.
        r*   z%Only read from archive files acceptedÚprotocolé   zPath "z(" did not resolve to exactly one file: "ú"r   N)ÚsuperÚ__init__Ú
ValueErrorÚ
isinstanceÚstrr
   ÚlenZofÚ	__enter__Úfor&   Ú	dir_cache)Úselfr5   ÚmodeZtarget_protocolZtarget_optionsr&   ÚkwargsÚfiles©Ú	__class__r   r   r/   ^   s    
ÿ
zLibArchiveFileSystem.__init__c              	   c   s2   | j  d¡ t| j | jd��}|V  W 5 Q R X d S )Nr   )r&   )r5   r   r'   r&   )r7   Úarcr   r   r   Ú_open_archive…   s    z"LibArchiveFileSystem._open_archivec                    s   t ƒ  |¡ d¡S )Nú/)r.   Ú_strip_protocolÚlstrip)ÚclsÚpathr;   r   r   r@   ‹   s    z$LibArchiveFileSystem._strip_protocolc              	      sÚ   ddddddddœ‰| j d k	r"d S i | _ g }|  ¡ �€}|D ]t‰ ˆ jsLˆ jsLq:| j  d	d
„ |  tˆ jƒ¡D ƒ¡ ‡ ‡fdd
„ˆD ƒ}ˆ jrŒdnd|d< | ˆ j¡ || j |d < q:W 5 Q R X | j  dd
„ |  |¡D ƒ¡ d S )NÚpathnameÚsizeÚctimer8   ÚuidÚgidÚmtime)ÚnamerE   Úcreatedr8   rG   rH   rI   c                 S   s   i | ]}||d ddœ“qS ©r   Ú	directory)rJ   rE   Útyper   ©Ú.0Údirnamer   r   r   Ú
<dictcomp>¦   s   ÿ z2LibArchiveFileSystem._get_dirs.<locals>.<dictcomp>c                    s   i | ]}|t ˆ ˆ| ƒ“qS r   )Úgetattr)rP   Úkey©ÚentryÚfieldsr   r   rR   «   s      rM   r   rN   rJ   c                 S   s   i | ]}||d ddœ“qS rL   r   rO   r   r   r   rR   ³   s   ÿ )	r6   r>   ÚisdirÚisfileÚupdateZ_all_dirnamesÚsetrJ   Úappend)r7   Z
list_namesr=   Úfr   rU   r   Ú	_get_dirs�   s<    ù


þÿþÿzLibArchiveFileSystem._get_dirsÚrbTc              	   K   s€   |   |¡}|dkrt‚tƒ }|  ¡ �H}|D ]<}	|	j|kr:q*|	jdkrH qh|	 |	j¡D ]}
|
} q*qTt‚q*W 5 Q R X t| ||d�S )Nr_   r   )ÚfsrC   Údata)	r@   ÚNotImplementedErrorÚbytesr>   rD   rE   Z
get_blocksr0   r   )r7   rC   r8   r&   Z
autocommitZcache_optionsr9   ra   r=   rV   Úblockr   r   r   Ú_open¹   s    	



zLibArchiveFileSystem._open)r_   NTN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zroot_markerr+   Zcachabler   r/   r   r>   Úclassmethodr@   r^   re   Ú__classcell__r   r   r;   r   r(   H   s(   ú'
,    úr(   )Ú
contextlibr   Úctypesr   r   r   r   r   r   r	   r#   Zlibarchive.ffir    Zfsspecr
   Zfsspec.archiver   Zfsspec.implementations.memoryr   Zfsspec.utilsr   r!   Zc_archive_pZ	check_intr   Úhasattrr"   Z	page_sizer'   r(   r   r   r   r   Ú<module>   s$   $
   ÿ
&