o
    NZh                     @   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r*tj}tj}	nt	j
tj}t	j
tj}	t	j
||}
t|
| t|
d|||	 t	j
|
V  W d   dS 1 s`w   Y  dS )zRead 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 X/var/www/html/lang_env/lib/python3.10/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                       sn   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i | |dkrtdt|tr8t|fd|i|p i }t|dkr4t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   sJ    | j d t| j | jd}|V  W d    d S 1 sw   Y  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 urd S i | _ g }|  E}|D ]:  js& js&q| j d	d
 | t jD   fdd
D } jrFdnd|d< | j || j |d < qW d    n1 sbw   Y  | j dd
 | |D  d S )Npathnamesizectimer8   uidgidmtime)namerE   createdr8   rG   rH   rI   c                 S      i | ]	}||d ddqS r   	directory)rJ   rE   typer   .0dirnamer   r   r   
<dictcomp>       z2LibArchiveFileSystem._get_dirs.<locals>.<dictcomp>c                    s   i | ]
}|t  | qS r   )getattr)rQ   keyentryfieldsr   r   rS      s    rN   r   rO   rJ   c                 S   rL   rM   r   rP   r   r   r   rS      rT   )	r6   r>   isdirisfileupdateZ_all_dirnamessetrJ   append)r7   Z
list_namesr=   fr   rW   r   	_get_dirs   s@   


zLibArchiveFileSystem._get_dirsrbTc                 K   s   |  |}|dkrtt }|  (}|D ]}	|	j|krq|	jdkr$ n|	|	jD ]}
|
} ntqW d    n1 s=w   Y  t| ||dS )Nra   r   )fsrC   data)	r@   NotImplementedErrorbytesr>   rD   rE   Z
get_blocksr0   r   )r7   rC   r8   r&   Z
autocommitZcache_optionsr9   rc   r=   rX   blockr   r   r   _open   s$   
	


zLibArchiveFileSystem._open)ra   NTN)__name__
__module____qualname____doc__Zroot_markerr+   Zcachabler   r/   r   r>   classmethodr@   r`   rg   __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     $

&