
    .Phk                        d dl mZ d dlZd dlZd dlZd dlZd dlmZmZm	Z	m
Z
mZ d dlmZmZmZmZmZ d dlmZmZ d dlmZ dZ	 d dlmZ d	Zn# e$ r Y nw xY wd
Z G d de          Z G d de          Z G d d          Z G d de          Z  G d de          Z! G d de          Z" G d d          Z# G d d          Z$dS )    )BytesION)msb_sizestream_copyapply_delta_dataconnect_deltasdelta_types)allocate_memory	LazyMixinmake_shawriteclose)	NULL_BYTE
BYTE_SPACE)force_bytesF)apply_deltaT)	DecompressMemMapReaderFDCompressedSha1WriterDeltaApplyReader
Sha1WriterFlexibleSha1WriterZippedStoreShaWriterr   FDStream
NullStreamc                       e Zd ZdZdZdZddZd Zd Zd Z	e
dd
            Zd Zd Zd Z eedd          fdZddZdS )r   a  Reads data in chunks from a memory map and decompresses it. The client sees
    only the uncompressed data, respective file-like read calls are handling on-demand
    buffered decompression accordingly

    A constraint on the total size of bytes is activated, simulating
    a logical file within a possibly larger physical memory area

    To read efficiently, you clearly don't want to read individual bytes, instead,
    read a few kilobytes at least.

    **Note:** The chunk-size should be carefully selected as it will involve quite a bit
        of string copying due to the way the zlib is implemented. Its very wasteful,
        hence we try to find a good tradeoff between allocation time and number of
        times we actually allocate. An own zlib implementation would be good here
        to better support streamed reading - it would only need to keep the mmap
        and decompress it into chunks, that's all ... )_m_zip_buf_buflen_br_cws_cwe_s_close_cbr_phii   Nc                     || _         t          j                    | _        d| _        d| _        ||| _        d| _        d| _        d| _	        d| _
        d| _        || _        dS )z|Initialize with mmap for stream reading
        :param m: must be content data - use new if you have object data and no sizeNr   F)r   zlibdecompressobjr   r   r   r"   r   r    r!   r$   r%   r#   )selfmclose_on_deletionsizes       L/var/www/html/test/jupyter/venv/lib/python3.11/site-packages/gitdb/stream.py__init__zDecompressMemMapReader.__init__E   sd     &((		DG				'    c                 >    |dk    sJ |                                   d S )Nr"   )_parse_header_infor)   attrs     r-   _set_cache_z"DecompressMemMapReader._set_cache_U   s)    t|||| 	!!!!!r/   c                 .    |                                   d S N)r   r)   s    r-   __del__zDecompressMemMapReader.__del__[   s    

r/   c                 |   d}|| _         |                     |          }|                    t                    }|d|                             t
                    \  }}t          |          }|| _         d| _        |dz  }t          ||d                   | _	        t          |          |z
  | _        d| _        ||fS )zIf this stream contains object data, parse the header info and skip the
        stream to a point where each read will yield object content

        :return: parsed type_string, sizei    Nr      T)r"   readfindr   splitr   intr   r   r   lenr   r%   )r)   maxbhdrhdrendtypr,   s         r-   r1   z)DecompressMemMapReader._parse_header_info^   s     iioo)$$L&&z22	T4yy !CL))	3xx&(	Dyr/   Fc                 \    t          ||d          }|                                \  }}|||fS )a  Create a new DecompressMemMapReader instance for acting as a read-only stream
        This method parses the object header from m and returns the parsed
        type and size, as well as the created stream instance.

        :param m: memory map on which to operate. It must be object data ( header + contents )
        :param close_on_deletion: if True, the memory map will be closed once we are
            being deletedr   )r   r1   )r)   r*   r+   instrC   r,   s         r-   newzDecompressMemMapReader.new{   s7     &a):A>>++--	TD$r/   c                     | j         S )z8:return: random access compatible data we are working on)r   r7   s    r-   datazDecompressMemMapReader.data   s	    wr/   c                     | j         r7t          | j        d          r| j                                         d| _         dS dS )zClose our underlying stream of compressed bytes if this was allowed during initialization
        :return: True if we closed the underlying stream
        :note: can be called safely
        r   FN)r#   hasattrr   r   r7   s    r-   r   zDecompressMemMapReader.close   sF    
 ; 	 tw((  DKKK	  	 r/   c                 "   | j         | j        k    r| j        j        sd| _         t	          | j        d          rT| j        j        t          j        k    r9|                     t          j
                   | j        j        t          j        k    9nq| j        j        se| j        t          | j                  k    rH|                     t          j
                   | j        j        s| j        t          | j                  k    H| j        | _         | j        S )z
        :return: number of compressed bytes read. This includes the bytes it
            took to decompress the header ( if there was one )r   status)r   r"   r   unused_datarJ   rL   r'   Z_OKr;   mmapPAGESIZEr$   r?   r   r7   s    r-   compressed_bytes_readz,DecompressMemMapReader.compressed_bytes_read   s    0 8twty'< DHty(++ -i&$)33IIdm,,, i&$)33
 )/ -DITW4M4MIIdm,,, )/ -DITW4M4M wDH
 yr/   SEEK_SETr   c                     |dk    s|t          t          dd          k    rt          d          t          j                    | _        dx| _        x| _        x| _        | _	        | j
        rd| _
        | `dS dS )zgAllows to reset the stream to restart reading
        :raise ValueError: If offset and whence are not 0r   rR   Can only seek to position 0FN)getattros
ValueErrorr'   r(   r   r   r    r!   r$   r%   r"   r)   offsetwhences      r-   seekzDecompressMemMapReader.seek   s     Q;;&GB
A$>$>>>:;;; &((	7888498ty499 	DI	 	r/   c                 z   |dk     r| j         | j        z
  }nt          || j         | j        z
            }|dk    rdS d}| j        r| j        |k    r<| j                            |          }| xj        |z  c_        | xj        |z  c_        |S | j                                        }|| j        z  }| xj        | j        z  c_        d| _        d | _        | j        j        }|r,| j        t          |          z
  | _
        | j
        |z   | _        n| j
        }| j        | _
        ||z   | _        | j        | j
        z
  dk     r| j
        dz   | _        | j        | j
        | j                 }| j
        t          |          z   | _        | j                            ||          }t          t          dt          j                  dv r*t           j        dk    st          | j        j                  }n3t          | j        j                  t          | j        j                  z   }| xj        t          |          |z
  z  c_        | xj        t          |          z  c_        |r||z   }|r[t          |          t          |          z
  |k     r8| j        | j         k     r(||                     |t          |          z
            z  }|S )Nr:   r   r/      ZLIB_RUNTIME_VERSION)z1.2.7z1.2.5darwin)r"   r   minr   r   r;   r   unconsumed_tailr!   r?   r    r   
decompressrU   r'   ZLIB_VERSIONsysplatformrM   r$   )r)   r,   dattailcwsindatadcompdatunused_datalens           r-   r;   zDecompressMemMapReader.read   s   !887TX%DDtTWtx/00D 1993 9 	!|t##innT**$D 
inn&&$DL(  	 y( 	# 	CII-DI	D(DII)C	DId
DI 9ty 1$$	ADI 49,- IF+	9''55 4/1BCCGYYYbebnrzbzbz !:;;NN !:;;c$)BW>X>XXN 			S[[>11		CMM! 	&X~H  	8XS1T99dh>P>P		$X"6777Hr/   r6   F)r\   )__name__
__module____qualname____doc__	__slots__max_read_sizer.   r4   r8   r1   classmethodrF   rH   r   rQ   rU   rV   r[   r;    r/   r-   r   r   .   s        : : !I M( ( ( ( " " "    : 
 
 
 [
       - - -b #*'"j!"<"<    i i i i i ir/   r   c                       e Zd ZdZdZdZd Zd Zd Ze	seZ
neZ
ddZ eed	d          fd
Zed             Zed             Zed             Zed             ZdS )r   a  A reader which dynamically applies pack deltas to a base object, keeping the
    memory demands to a minimum.

    The size of the final object is only obtainable once all deltas have been
    applied, unless it is retrieved from a pack index.

    The uncompressed Delta has the following layout (MSB being a most significant
    bit encoded dynamic size):

    * MSB Source Size - the size of the base against which the delta was created
    * MSB Target Size - the size of the resulting data after the delta was applied
    * A list of one byte commands (cmd) which are followed by a specific protocol:

     * cmd & 0x80 - copy delta_data[offset:offset+size]

      * Followed by an encoded offset into the delta data
      * Followed by an encoded size of the chunk to copy

     *  cmd & 0x7f - insert

      * insert cmd bytes from the delta buffer into the output stream

     * cmd == 0 - invalid operation ( or error in delta stream )
    )_bstream	_dstreams
_mm_target_sizer   ic                     t          |          dk    s
J d            |d         | _        t          |dd                   | _        d| _        dS )zInitialize this instance with a list of streams, the first stream being
        the delta to apply on top of all following deltas, the last stream being the
        base object onto which to apply the deltasr:   z+Need at least one delta and one base streamr\   Nr   )r?   rw   tuplerx   r   )r)   stream_lists     r-   r.   zDeltaApplyReader.__init__h  sT     ;!###%R####B{3B3/00r/   c                 p   t          | j                  dk    r|                     |          S t          | j                  }|                                dk    rd| _        t          d          | _        d S |                                | _        t          | j                  | _        t          | j        j	                  }t          | j        j        |j        | j        j	        dt          j        z             | j        j        }|                    ||           | j                            d           d S )Nr:   r      )r?   rx   _set_cache_brute_r   rboundrz   r	   ry   rw   r,   r   r;   r   rO   rP   applyr[   )r)   r3   dclbbufr   s        r-   _set_cache_too_slow_without_cz.DeltaApplyReader._set_cache_too_slow_without_cr  s    t~!##))$///
 T^,, ::<<1DJ-a00DOF ZZ\\
)$*55t}122DM&
DM4FdmH[\\\ %		$Qr/   c           	      N   t                      }d}| j        D ]m}|                    d          }t          |          \  }}t          ||          \  }}|                    ||d         |||f           t          ||          }n| j        j        }	|}t          | j                  dk    rt          |	|          x}	}t          |	          }
t          | j        j        |
j        |	dt          j        z             t          |          }d}t          t          |          t          | j                            D ]\  \  }}}}}t          |j        |z
            }|                    |           t          |j        |j        |j        dt          j        z             dt!                      v rt#          |
||           n%t%          |
||t          |          |j                   ||
}}
|
                    d           |                    d           |}|
| _        || _        dS )z*If we are here, we apply the actual deltasr   i   Nr:   r   c_apply_delta)listrx   r;   r   appendmaxrw   r,   r?   r	   r   r   rO   rP   zipreversedglobalsr   r   r[   ry   rz   )r)   r3   buffer_info_listmax_target_sizedstreambufrY   src_sizetarget_size	base_sizer   tbuffinal_target_sizedbufddatas                  r-   r   z"DeltaApplyReader._set_cache_brute_  s%   
  66~ 	@ 	@G,,s##C'}}FH"*3"7"7FK##S\68[$QRRR!/;??OO
 M&	% t~""&))_&E&EEI
 y))DM&
IsT]?RSSS {++ !>A(K[B\B\^fgkgu^v^v>w>w 	, 	,:1T68[7 $GL6$9::EKKek7<t}ATUUU '))++dE40000 xE

DJOOO
 t$DIIaLLLIIaLLL + &


r/   r   c                     | j         | j        z
  }|dk     s||k    r|}| j                            |          }| xj        t	          |          z  c_        |S )Nr:   )rz   r   ry   r;   r?   )r)   countblrH   s       r-   r;   zDeltaApplyReader.read  sX    Z$("199

E ##E**CIIr/   rR   c                     |dk    s|t          t          dd          k    rt          d          d| _        | j                            d           dS )zhAllows to reset the stream to restart reading

        :raise ValueError: If offset and whence are not 0r   rR   rT   N)rU   rV   rW   r   ry   r[   rX   s      r-   r[   zDeltaApplyReader.seek  sU     Q;;&GB
A$>$>>>:;;;Qr/   c                     t          |          dk     rt          d          |d         j        t          v rt          d|d         j        z             | |          S )a  
        Convert the given list of streams into a stream which resolves deltas
        when reading from it.

        :param stream_list: two or more stream objects, first stream is a Delta
            to the object that you want to resolve, followed by N additional delta
            streams. The list's last stream must be a non-delta stream.

        :return: Non-Delta OPackStream object whose stream can be used to obtain
            the decompressed resolved data
        :raise ValueError: if the stream list cannot be handled   zNeed at least two streamsr\   zNCannot resolve deltas if there is no base object stream, last one was type: %s)r?   rW   type_idr   type)clsr}   s     r-   rF   zDeltaApplyReader.new  ss     {a8999 r?"k11`cnoqcrcwwy y y s;r/   c                     | j         j        S r6   )rw   r   r7   s    r-   r   zDeltaApplyReader.type  s    }!!r/   c                     | j         j        S r6   )rw   r   r7   s    r-   r   zDeltaApplyReader.type_id  s    }$$r/   c                     | j         S )z3:return: number of uncompressed bytes in the stream)rz   r7   s    r-   r,   zDeltaApplyReader.size  s     zr/   Nr   )rn   ro   rp   rq   rr   k_max_memory_mover.   r   r   has_perf_modr4   r;   rU   rV   r[   rt   rF   propertyr   r   r,   ru   r/   r-   r   r   B  s        0I *          DH' H' H'V  4'3    #*'"j!"<"<             [ 4 " " X" % % X%   X  r/   r   c                   *    e Zd ZdZdZd Zd ZddZdS )	r   zpSimple stream writer which produces a sha whenever you like as it degests
    everything it is supposed to writesha1c                 ,    t                      | _        d S r6   )r   r   r7   s    r-   r.   zSha1Writer.__init__2  s    JJ			r/   c                 T    | j                             |           t          |          S )z{:raise IOError: If not all bytes could be written
        :param data: byte object
        :return: length of incoming data)r   updater?   r)   rH   s     r-   r   zSha1Writer.write7  s&    
 		4yyr/   Fc                 j    |r| j                                         S | j                                         S )z]:return: sha so far
        :param as_hex: if True, sha will be hex-encoded, binary otherwise)r   	hexdigestdigest)r)   as_hexs     r-   shazSha1Writer.shaD  s4      	)9&&(((y!!!r/   Nrm   )rn   ro   rp   rq   rr   r.   r   r   ru   r/   r-   r   r   ,  sU        * *I  
  " " " " " "r/   r   c                   "    e Zd ZdZdZd Zd ZdS )r   zZWriter producing a sha1 while passing on the written bytes to the given
    write functionwriterc                 H    t                               |            || _        d S r6   )r   r.   r   )r)   r   s     r-   r.   zFlexibleSha1Writer.__init__T  s!    D!!!r/   c                 f    t                               | |           |                     |           d S r6   )r   r   r   r   s     r-   r   zFlexibleSha1Writer.writeX  s0    t$$$Dr/   N)rn   ro   rp   rq   rr   r.   r   ru   r/   r-   r   r   N  sA         I      r/   r   c                   T    e Zd ZdZdZd Zd Zd Zd Z e	e
dd          fd	Zd
 ZdS )r   z=Remembers everything someone writes to it and generates a sha)r   r   c                     t                               |            t                      | _        t	          j        t          j                  | _        d S r6   )r   r.   r   r   r'   compressobjZ_BEST_SPEEDr   r7   s    r-   r.   zZippedStoreShaWriter.__init__b  s:    D!!!99#D$566r/   c                 ,    t          | j        |          S r6   )rU   r   r2   s     r-   __getattr__z ZippedStoreShaWriter.__getattr__g  s    tx&&&r/   c                     t                               | |          }| j                            | j                            |                     |S r6   )r   r   r   r   compress)r)   rH   alens      r-   r   zZippedStoreShaWriter.writej  s@    d++tx((..///r/   c                 h    | j                             | j                                                   d S r6   )r   r   r   flushr7   s    r-   r   zZippedStoreShaWriter.closep  s(    tx~~''(((((r/   rR   r   c                     |dk    s|t          t          dd          k    rt          d          | j                            d           dS )z`Seeking currently only supports to rewind written data
        Multiple writes are not supportedr   rR   rT   N)rU   rV   rW   r   r[   rX   s      r-   r[   zZippedStoreShaWriter.seeks  sL     Q;;&GB
A$>$>>>:;;;ar/   c                 4    | j                                         S )zA:return: string value from the current stream position to the end)r   getvaluer7   s    r-   r   zZippedStoreShaWriter.getvalue{  s    x  """r/   N)rn   ro   rp   rq   rr   r.   r   r   r   rU   rV   r[   r   ru   r/   r-   r   r   ]  s        GGI7 7 7
' ' '  ) ) ) #*'"j!"<"<    # # # # #r/   r   c                   H     e Zd ZdZdZ ed          Z fdZd Zd Z	 xZ
S )r   zDigests data written to it, making the sha available, then compress the
    data and write it to the file descriptor

    **Note:** operates on raw file descriptors
    **Note:** for this to work, you have to use the close-method of this instance)fdr   r   z+Failed to write all bytes to filedescriptorc                     t                                                       || _        t          j        t          j                  | _        d S r6   )superr.   r   r'   r   r   r   )r)   r   	__class__s     r-   r.   zFDCompressedSha1Writer.__init__  s9    #D$566r/   c                     | j                             |           | j                            |          }t	          | j        |          }|t          |          k    r| j        t          |          S )zZ:raise IOError: If not all bytes could be written
        :return: length of incoming data)r   r   r   r   r   r   r?   exc)r)   rH   cdatabytes_writtens       r-   r   zFDCompressedSha1Writer.write  sd     		!!$''dgu--CJJ&&(N4yyr/   c                     | j                                         }t          | j        |          t	          |          k    r| j        t          | j                  S r6   )r   r   r   r   r?   r   r   )r)   	remainders     r-   r   zFDCompressedSha1Writer.close  sE    HNN$$	)$$I66(NTW~~r/   )rn   ro   rp   rq   rr   IOErrorr   r.   r   r   __classcell__)r   s   @r-   r   r     s{        U U
 &I '?
@
@C7 7 7 7 7
 
 
      r/   r   c                   <    e Zd ZdZdZd Zd ZddZd Zd Z	d	 Z
d
S )r   zA simple wrapper providing the most basic functions on a file descriptor
    with the fileobject interface. Cannot use os.fdopen as the resulting stream
    takes ownership_fd_posc                 "    || _         d| _        d S Nr   r   )r)   r   s     r-   r.   zFDStream.__init__  s    			r/   c                 t    | xj         t          |          z  c_         t          j        | j        |           d S r6   )r   r?   rV   r   r   r   s     r-   r   zFDStream.write  s2    		SYY		
4     r/   r   c                     |dk    r$t           j                            | j                  }t          j        | j        |          }| xj        t          |          z  c_        |S r   )rV   pathgetsize	_filepathr;   r   r   r?   )r)   r   bytess      r-   r;   zFDStream.read  sP    A::GOODN33E %((		SZZ		r/   c                     | j         S r6   )r   r7   s    r-   filenozFDStream.fileno  s	    xr/   c                     | j         S r6   )r   r7   s    r-   tellzFDStream.tell  s
    yr/   c                 .    t          | j                   d S r6   )r   r   r7   s    r-   r   zFDStream.close  s    dhr/   Nr   )rn   ro   rp   rq   rr   r.   r   r;   r   r   r   ru   r/   r-   r   r     s           I  ! ! !           r/   r   c                   :    e Zd ZdZ e            ZddZd Zd ZdS )r   zVA stream that does nothing but providing a stream interface.
    Use it like /dev/nullr   c                     dS )N ru   )r)   r,   s     r-   r;   zNullStream.read  s    rr/   c                     d S r6   ru   r7   s    r-   r   zNullStream.close  s    r/   c                      t          |          S r6   )r?   r   s     r-   r   zNullStream.write  s    4yyr/   Nr   )	rn   ro   rp   rq   r|   rr   r;   r   r   ru   r/   r-   r   r     s[         I         r/   r   )%ior   rO   rV   re   r'   	gitdb.funr   r   r   r   r   
gitdb.utilr	   r
   r   r   r   gitdb.constr   r   gitdb.utils.encodingr   r   gitdb_speedups._perfr   r   ImportError__all__r   r   r   r   r   r   r   r   ru   r/   r-   <module>r      s          				 



                            . - - - - - - - , , , , , ,	AAAAAALL 	 	 	D	%Q Q Q Q QY Q Q Qh` ` ` ` `y ` ` `T" " " " " " " "D        #  #  #  #  #:  #  #  #F# # # # #Z # # #P       D         s   A AA