
    ch<                        S r SSKrSSKJrJrJrJr  SSKJrJ	r	J
r
JrJr  SSKJrJrJrJrJrJrJrJrJrJrJr   SSKJr  SSKJrJrJrJ r J!r!J"r"J#r#  SSK$J%r%J&r&J'r'J(r(J)r)  SS	K*J+r+  SS
K,J-r-  SSK.J/r/  SSK0r0SSK1r1SSK2r2SSK3r3Sr4S r5SS jr6 " S S5      r7 " S S\	5      r8 " S S\	5      r9 " S S\	5      r:g! \ a     Nf = f)z3Contains PackIndexFile and PackFile implementations    N)	BadObjectAmbiguousObjectNameUnsupportedOperation
ParseError)mman	LazyMixinunpack_from
bin_to_hexbyte_ord)create_pack_object_headerpack_object_header_infois_equal_canonical_shatype_id_to_type_mapwrite_objectstream_copy
chunk_sizedelta_types	OFS_DELTA	REF_DELTAmsb_sizePackIndexFile_sha_to_index)OInfoOStream	OPackInfoOPackStreamODeltaStreamODeltaPackInfoODeltaPackStream)DecompressMemMapReaderDeltaApplyReader
Sha1Writer
NullStreamFlexibleSha1Writer)pack)crc32)	NULL_BYTE)PackIndexFilePackFile
PackEntityc                    U R                  U5      R                  5       n[        U5      u  pEnSnSnU[        :X  aV  Un	[	        X9   5      n
U	S-  n	U
S-  nU
S-  (       a.  [	        X9   5      n
U	S-  n	US-  nUS-  U
S-  -   nU
S-  (       a  M.  UnU	nOU[
        :X  a
  US-   nX6U nOUnX-   nU(       a/  [        X7S SU5      nUc  U[        XX]5      4$ U[        XXXU5      4$ Uc  U[        XU5      4$ U[        XXX5      4$ )a  
:return: Tuple(abs_data_offset, PackInfo|PackStream)
    an object of the correct type according to the type_id  of the object.
    If as_stream is True, the object will contain a stream, allowing  the
    data to be read decompressed.
:param data: random accessible data containing all required information
:parma offset: offset in to the data at which the object information is located
:param as_stream: if True, a stream object will be returned that can read
    the data, otherwise you receive an info object onlyN               F)
use_regionbufferr   r   r   r   r    r   r   r   r   )cursoroffset	as_streamdatatype_iduncomp_sizedata_rela_offsettotal_rela_offset
delta_infoicdelta_offsetabs_data_offsetstreams                 ]C:\Users\julio\OneDrive\Documentos\Trabajo\Ideas Frescas\venv\Lib\site-packages\gitdb/pack.pypack_object_atrB   L   sS    V$++-D-DT-J*G*J )TW	Q4x$h!AFAAL(A-!d(;L	 $hh "
	I	,r1+<=
 -0O'-?(@%U"K$UUU"$4Vk_e$fff"If{$KKK"N6K$\\\    c                 t   SnSnUSLnSnU(       a  Un U " [         5      nU[        U5      -  nUR                  U5      n	U[        U	5      -  nU" U	5        U(       a  [        X5      n[        U5      [         :w  a  OMi  UR	                  5       n	U[        U	5      -  nU" U	5        U(       a  [        X5      nXEU4$ )a~  Copy a stream as read from read function, zip it, and write the result.
Count the number of written bytes and return it
:param base_crc: if not None, the crc will be the base for all compressed data
    we consecutively write and generate a crc32 from. If None, no crc will be generated
:return: tuple(no bytes read, no bytes written, crc32) crc might be 0 if base_crc
    was falser   N)r   lencompressr&   flush)
readwritezstreambase_crcbrbwwant_crccrcchunk
compresseds
             rA   write_stream_to_packrR      s     
B	
Bt#H
C Z 
c%j%%e,

c*oj
(C u:#  J#j/B	*J$ C=rC   c                   .    \ rS rSrSrSrS rS rS rSr	g)	IndexWriter   zUtility to cache index information, allowing to write all information later
in one go to the given stream
**Note:** currently only writes v2 indices_objsc                 "    [        5       U l        g N)listrV   selfs    rA   __init__IndexWriter.__init__   s    V
rC   c                 >    U R                   R                  XU45        g)z&Append one piece of object informationN)rV   append)r[   binsharO   r4   s       rA   r_   IndexWriter.append   s    

6/0rC   c                    U R                   R                  S S9  [        U5      nUR                  nU" [        R
                  5        U" [        S[        R                  5      5        [        S5      nU R                    H  nU[        US   S   5      ==   S-  ss'   M!     [        S5       H(  nXW   nU" [        SU5      5        XWS-   ==   U-  ss'   M*     U" [        SUS   5      5        U" SR                  S	 U R                    5       5      5        U R                    H  nU" [        SUS   S
-  5      5        M     [        5       nU R                    HE  nUS   n	U	S:  a"  UR                  U	5        S[        U5      -   S-
  n	U" [        SU	S
-  5      5        MG     U H  n	U" [        SU	5      5        M     [        U5      S:X  d   eU" U5        UR                  SS9n
U" U
5        U
$ )zWrite the index file using the given write method
:param pack_sha: binary sha over the whole pack that we index
:return: sha1 binary sha over all index file contentsc                     U S   $ )Nr    )os    rA   <lambda>#IndexWriter.write.<locals>.<lambda>   s    adrC   )key>L(   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r,      rC   c              3   *   #    U  H	  oS    v   M     g7f)r   Nrd   ).0ts     rA   	<genexpr>$IndexWriter.write.<locals>.<genexpr>   s     4AQ4s          i        >Qr0   Fas_hex)rV   sortr$   rI   r(   index_v2_signaturer%   index_version_defaultrY   r   rangejoinr_   rE   sha)r[   pack_sharI   
sha_writer	sha_writetmplistrm   r<   vofsr{   s              rA   rI   IndexWriter.write   s   
 	

N+'.
$$	-223$t]@@AB z"AHQqT!W%&!+&  sA
Ad4m$ENaN 
 	$tWS\*+ 	#((4445 Ad41
!234  &AA$CZs# 3w</!3d4z!123  Cd4o& 
 8}"#"(nnEn*c

rC   )rV   N)
__name__
__module____qualname____firstlineno____doc__	__slots__r\   r_   rI   __static_attributes__rd   rC   rA   rT   rT      s    2 I16rC   rT   c                      ^  \ rS rSrSrSrSrSrU 4S jrS r	S r
S	 rS
 rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS rS\" 5       ;   a	  S rSrU =r$ SrU =r$ )r(      ziA pack index provides offsets into the corresponding pack, allowing to find
locations for offsets faster.i  s   tOcrq   c                 .   > [         TU ]  5         Xl        g rX   )superr\   
_indexpath)r[   	indexpath	__class__s     rA   r\   PackIndexFile.__init__  s    #rC   c                 R    [         R                  " U R                  5        S U l        g rX   )r   force_map_handle_removal_winr   _cursorrZ   s    rA   closePackIndexFile.close  s    ))$//:rC   c                    US:X  a#  U R                   R                  5       SS U l        g US:X  a#  U R                   R                  5       SS  U l        g US:X  a  [        R                  " U R
                  5      R                  5       U l         [        R                  " 5       S:  ax  U R                   R                  5       [        R                  " 5       :  aF  [        SU R
                  U R                   R                  5       [        R                  " 5       4-  5      eg g U R                   R                  5       nUS S U R                  :H  =(       a    S=(       d    S	U l        U R                  S:X  a)  [        S
US5      S   nX0R                  :X  d
   SU-  5       eS H'  n[        X[        U SX@R                  4-  5      5        M)     U R                  5         g )N_packfile_checksumr   r   zsThe index file at %s is too large to fit into a mapped window (%i > %i). This is a limitation of the implementation   rq   r,   ri   zUnsupported index version: %i)entryr4   r{   rO   z_%s_v%i)r   mapr   r   make_cursorr   r1   window_size	file_sizeAssertionErrorrw   _versionr	   setattrgetattr_initialize)r[   attrmmap
version_idfnames        rA   _set_cache_PackIndexFile._set_cache_  s   ''&*ll&6&6&8S&AD#))&*ll&6&6&8&>D#Y  ++DOO<GGIDL!A%$,,*@*@*BTEUEUEW*W$  &[OOT\\%;%;%=t?O?O?Q^S &S T T +X% <<##%D!"1X)@)@@FQL1DM}}!(tQ7:
!]]2`4SV`4``2
 ;WT9}}?U3U%VW ; rC   c                 ^    [        SU R                  R                  5       SUS-  -   5      S-   $ )z!:return: tuple(offset, binsha, 0)z>L20s      r   r	   r   r   r[   r<   s     rA   	_entry_v1PackIndexFile._entry_v13  s+    7DLL$4$4$6q2vFNNrC   c                 ^    [        SU R                  R                  5       SUS-  -   5      S   $ )zsee ``_offset_v2``ri   r   r   r   r   r   s     rA   
_offset_v1PackIndexFile._offset_v17  s+    4!1!1!3TAF]CAFFrC   c                 V    SUS-  -   S-   nU R                   R                  5       X"S-    $ )zsee ``_sha_v2``r   r   r   r0   r   r   r[   r<   bases      rA   _sha_v1PackIndexFile._sha_v1;  s0    q2v"||!$by11rC   c                     g)unsupportedr   rd   r   s     rA   _crc_v1PackIndexFile._crc_v1@  s    rC   c                 f    U R                  U5      U R                  U5      U R                  U5      4$ )z#:return: tuple(offset, binsha, crc))
_offset_v2_sha_v2_crc_v2r   s     rA   	_entry_v2PackIndexFile._entry_v2G  s(    "DLLOT\\!_EErC   c                     [        SU R                  R                  5       U R                  US-  -   5      S   nUS-  (       a;  [        SU R                  R                  5       U R                  US-  S-  -   5      S   nU$ )z~:return: 32 or 64 byte offset into pack files. 64 byte offsets will only
be returned if the pack is larger than 4 GiB, or 2^32ri   r   r   rr   rs   l       )r	   r   r   _pack_offset_pack_64_offset)r[   r<   r4   s      rA   r   PackIndexFile._offset_v2K  s~     T4<<#3#3#5t7H7H1q57PQRST
 J t||'7'7'94;O;OSY\gSgklRl;lmnopF rC   c                 d    U R                   US-  -   nU R                  R                  5       X"S-    $ )z;:return: sha at the given index of this file index instancer0   )_sha_list_offsetr   r   r   s      rA   r   PackIndexFile._sha_v2Y  s2    $$q2v-||!$by11rC   c                 r    [        SU R                  R                  5       U R                  US-  -   5      S   $ )z.:return: 4 bytes crc for the object at index iri   r   r   )r	   r   r   _crc_list_offsetr   s     rA   r   PackIndexFile._crc_v2^  s4    4!1!1!3T5J5JQQRU5RSTUVVrC   c                 P   U R                  U R                  S:H  S-  5      U l        U R                  S:X  ap  U R                  U R	                  5       S-  -   U l        U R
                  U R	                  5       S-  -   U l        U R                  U R	                  5       S-  -   U l        gg)zinitialize base datarq   r   r0   r   N)_read_fanoutr   _fanout_tabler   sizer   r   r   rZ   s    rA   r   PackIndexFile._initializef  s    !..0Ba/GH==A$($9$9DIIK"<L$LD! $ 5 5		a GD#'#4#4tyy{Q#FD  rC   c           
          U R                   R                  5       n[        5       nUR                  n[	        S5       H  nU" [        SX!US-  -   5      S   5        M      U$ )z%Generate a fanout table from our data   ri   r   r   )r   r   rY   r_   ry   r	   )r[   byte_offsetdoutr_   r<   s         rA   r   PackIndexFile._read_fanoutp  sV    LLfsA;tQa!e(;<Q?@  
rC   c                     U R                   $ rX   r   rZ   s    rA   versionPackIndexFile.version}  s    }}rC   c                      U R                   S   $ )z4:return: amount of objects referred to by this indexrj   )r   rZ   s    rA   r   PackIndexFile.size  s    !!#&&rC   c                     U R                   $ )z":return: path to the packindexfile)r   rZ   s    rA   pathPackIndexFile.path  s    rC   c                 <    U R                   R                  5       SS $ )z@:return: 20 byte sha representing the sha1 hash of the pack filer   r   r   rZ   s    rA   packfile_checksumPackIndexFile.packfile_checksum  s    ||!#c**rC   c                 <    U R                   R                  5       SS $ )zB:return: 20 byte sha representing the sha1 hash of this index filer   Nr   rZ   s    rA   indexfile_checksum PackIndexFile.indexfile_checksum  s    ||!#$''rC   c                 t  ^  T R                   S:X  a|  [        R                  " S5      nUR                  T R                  R	                  5       T R
                  T R                   5        [        R                  S:X  a  UR                  5         U$ [        U 4S j[        T R                  5       5       5       5      $ )z:return: sequence of all offsets in the order in which they were written

**Note:** return value can be random accessed, but may be immmutablerq   Ilittlec              3   F   >#    U  H  nTR                  U5      v   M     g 7frX   )r4   )rl   indexr[   s     rA   rn   (PackIndexFile.offsets.<locals>.<genexpr>  s     L9KU++9Ks   !)r   array	frombytesr   r   r   r   sys	byteorderbyteswaptuplery   r   )r[   as   ` rA   offsetsPackIndexFile.offsets  s     ==AC AKK((*4+<+<T=Q=QRS }}(

HLtyy{9KLLLrC   c                     [        US   5      nU R                  nSnUS:w  a  U R                  US-
     nU R                  U   nXE:  a*  XE-   S-  nU" U5      nX:  a  UnOX:X  a  U$ US-   nXE:  a  M*  g)z
:return: index usable with the ``offset`` or ``entry`` method, or None
    if the sha was not found in this pack index
:param sha: 20 byte sha to lookupr   r,   rq   N)r   r{   r   )r[   r{   
first_byteget_shalohimidmid_shas           rA   sha_to_indexPackIndexFile.sha_to_index  s    
 c!f%
((?##JN3B
+ g7q.CclG}
1W g rC   c                 X   [        U5      S:  a  [        S5      e[        U[        5      (       d   S5       e[	        US   5      nU R
                  nSnUS:w  a  U R                  US-
     nU R                  U   nU[        S[        U5      -
  -  -   nXV:  a+  XV-   S-  nU" U5      n	Xy:  a  UnOXy:X  a  UnOUS-   nXV:  a  M+  XPR                  5       :  aV  U" U5      n
[        X!U
5      (       a=  SnUS-   U R                  5       :  a  U" US-   5      nU(       a  X:X  a  [        U5      eU$ g)a6  
:return: index as in `sha_to_index` or None if the sha was not found in this
    index file
:param partial_bin_sha: an at least two bytes of a partial binary sha as bytes
:param canonical_length: length of the original hexadecimal representation of the
    given partial binary sha
:raise AmbiguousObjectName:rq   z'Require at least 2 bytes of partial shazpartial_bin_sha must be bytesr   r,   r0   N)rE   
ValueError
isinstancebytesr   r{   r   r'   r   r   r   )r[   partial_bin_shacanonical_lengthr   r   r   r   
filled_shar   r  cur_shanext_shas               rA   partial_sha_to_index"PackIndexFile.partial_sha_to_index  sC    !#FGG/511R3RR1oa01
((?##JN3B
+ %yB_9M4M'NN
 g7q.CclG#&1W g 		bkG%&6QQ6DIIK'&rAvH 3-o>>	 rC   r   c                     [        X5      $ rX   r   r[   r{   s     rA   r  r    s    -d88rC   )r   r   r   r   r   r   r   r   ) r   r   r   r   r   r   rw   rx   r\   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  globalsr   __classcell__)r   s   @rA   r(   r(      s    %  #$#POG2
F2
WG'+(M"41f $wy0	9 	9 1rC   r(   c                       \ rS rSrSrSrSrSrSrSr	S r
S	 rS
 rSS jrS rS rS rS rS rS rS rS rSS jrSrg)r)   i  a  A pack is a file written according to the Version 2 for git packs

As we currently use memory maps, it could be assumed that the maximum size of
packs therefore is 32 bit on 32 bit systems. On 64 bit systems, this should be
fine though.

**Note:** at some point, this might be implemented using streams as well, or
streams are an alternate path in the case memory maps cannot be created
for some reason - one clearly doesn't want to read 10GB at once in that
case)	_packpathr   _sizer   iKCAPrq      r0   c                     Xl         g rX   r  )r[   packpaths     rA   r\   PackFile.__init__  s    !rC   c                 R    [         R                  " U R                  5        S U l        g rX   )r   r   r  r   rZ   s    rA   r   PackFile.close  s    ))$..9rC   c                    [         R                  " U R                  5      R                  5       U l        [        SU R                  R                  5       S5      u  o l        U l        X R                  :w  a  [        SU-  5      eg )N>LLLr   zInvalid pack signature: %i)r   r   r  r1   r   r	   r   r   r  pack_signaturer   )r[   r   r7   s      rA   r   PackFile._set_cache_  sl    ''7BBD .9AQAQASUV-W*
 )))9GCDD *rC   c              #   "  #    U R                   nUR                  5       U R                  -
  nU=(       d    U R                  n[	        5       nXT:  a  [        X5S5      u  px[        UR                  UR                  UR                  [        5        UR                  R                  UR                  :X  d   eXWUR                  -
  UR                  R                  5       -   -  nU(       a  UR                  R                  S5        Uv   XT:  a  M  gg7f)z7Handle the actual iteration of objects within this packTr   N)r   r   footer_sizefirst_object_offsetr#   rB   r   rH   rI   r   r   r@   _brpack_offsetcompressed_bytes_readseek)	r[   start_offsetr5   r=   content_size
cur_offsetnulldata_offsetostreams	            rA   _iter_objectsPackFile._iter_objects   s     LL{{}t'7'77!=T%=%=
|'#1!#F K djj',,
K>>%%555)<)<<@d@d@fffJ
 ##A&M 's   D	DDc                     U R                   $ )z2:return: The amount of objects stored in this pack)r  rZ   s    rA   r   PackFile.size:      zzrC   c                     U R                   $ )z!:return: the version of this packr   rZ   s    rA   r   PackFile.version>  s    }}rC   c                 R    U R                   R                  5       R                  5       $ )z
:return: read-only data of this pack. It provides random access and usually
    is a memory map.
:note: This method is unsafe as it returns a window into a file which might be larger than than the actual window size)r   r1   r   rZ   s    rA   r6   PackFile.dataB  s      ||&&(,,..rC   c                     U R                   R                  U R                   R                  5       S-
  5      R                  5       SS $ )zE:return: 20 byte sha1 hash on all object sha's contained in this filer0   N)r   r1   r   r2   rZ   s    rA   checksumPackFile.checksumJ  s7    ||&&t||'='='?"'DELLNqQQrC   c                     U R                   $ )z:return: path to the packfiler  rZ   s    rA   r   PackFile.pathN  s    ~~rC   c                     [        5       nU R                  n [        X1S5      S   nUR                  U5        UR                  [
        :X  a  UR                  UR                  -
  nO U$ MS  )a  
:return: list of pack streams which are required to build the object
    at the given offset. The first entry of the list is the object at offset,
    the last one is either a full object, or a REF_Delta stream. The latter
    type needs its reference object to be locked up in an ODB to form a valid
    delta chain.
    If the object at offset is no delta, the size of the list is 1.
:param offset: specifies the first byte of the object within this packTr,   )rY   r   rB   r_   r7   r   r%  r;   )r[   r4   r   r=   r-  s        rA   collect_streamsPackFile.collect_streamsU  sg     fLL$Q5a8GJJw)+ ,,w/A/AA
  
 rC   c                 \    [        U R                  U=(       d    U R                  S5      S   $ )zRetrieve information about the object at the given file-absolute offset

:param offset: byte offset
:return: OPackInfo instance, the actual type differs depending on the type_id attributeFr,   rB   r   r#  r[   r4   s     rA   infoPackFile.infor  s)    
 dllF,Nd6N6NPUVWXYYrC   c                 \    [        U R                  U=(       d    U R                  S5      S   $ )zRetrieve an object at the given file-relative offset as stream along with its information

:param offset: byte offset
:return: OPackStream instance, the actual type differs depending on the type_id attributeTr,   r@  rA  s     rA   r@   PackFile.streamy  s)    
 dllF,Nd6N6NPTUVWXXrC   c                 "    U R                  USS9$ )at  
:return: iterator yielding OPackStream compatible instances, allowing
    to access the data in the pack directly.
:param start_offset: offset to the first object to iterate. If 0, iteration
    starts at the very first object in the pack.

**Note:** Iterating a pack directly is costly as the datastream has to be decompressed
to determine the bounds between the objectsTr5   r.  )r[   r(  s     rA   stream_iterPackFile.stream_iter  s     !!,$!??rC   )r   r  r  r   N)Tr   )r   r   r   r   r   r   r  pack_version_defaultr#  r"  r\   r   r   r.  r   r   r6   r8  r   r=  rB  r@   rI  r   rd   rC   rA   r)   r)     sl    	 >IN  K"
E4/R:ZY	@rC   r)   c                       \ rS rSrSrSr\r\r	S r
S rS rS rS rSS	 jrS
 rS rS rS rS rS rSS jrS rS rS rS r\SS\R:                  4S j5       r\S\R:                  4S j5       rSr g)r*   i  zmCombines the PackIndexFile and the PackFile into one, allowing the
actual objects to be resolved and iterated)_index_pack_offset_mapc                     [         R                  R                  U5      u  p#U R                  SU-  5      U l        U R                  SU-  5      U l        g)zGInitialize ourselves with the path to the respective pack or index filez%s.idxz%s.packN)osr   splitextIndexFileClsrM  PackFileClsrN  )r[   pack_or_index_pathbasenameexts       rA   r\   PackEntity.__init__  sG    (();<''8(;<%%i(&:;
rC   c                 l    U R                   R                  5         U R                  R                  5         g rX   )rM  r   rN  rZ   s    rA   r   PackEntity.close  s"    

rC   c                    [        U R                  R                  5       5      n[        U R                  R                  5       5      U R                  R                  -
  nU(       d   S5       eS n[        U5      S:X  a  US   U0nO>[        U5      n[        U5      n[        U5        [        XV5      n[        U5      nX4US   '   X@l        g )NzCannot handle empty indicesr,   r   )sortedrM  r   rE   rN  r6   r"  iternextzipdictrO  )r[   r   offsets_sortedlast_offset
offset_mapiter_offsetsiter_offsets_plus_oneconsecutives           rA   r   PackEntity._set_cache_  s    
   3 3 56$**//+,tzz/E/EE<<<~
~!#(+[9J/L$($8!&'lBKk*J .9~b)*%rC   c                 X    U R                   R                  U5      nUc  [        U5      eU$ )z*:return: index for the given sha, or raise)rM  r  r   )r[   r{   r   s      rA   _sha_to_indexPackEntity._sha_to_index  s*    ((-=C. rC   c              #      #    U R                   R                  nU R                  n[        U R                   R	                  5       5       H  nU" U" U5      X5      v   M     g7f)zPIterate over all objects in our index and yield their OInfo or OStream instencesN)rM  r{   _objectry   r   )r[   r5   _sharm  r   s        rA   r.  PackEntity._iter_objects  sH     {{,,4;;++-.E$u+y88 /s   AA!c                 |   US:  a  U R                  U5      nUc  U R                  R                  U5      nU R                  R                  U5      n[	        U R
                  R                  R                  U5      R                  5       5      u  pVnU(       a  U[        ;  aF  U R
                  R                  U5      n[        XR                  UR                  UR                  5      $ U R                  U5      n	[        R                   " U	5      n
[#        XR                  SU
5      $ U[        ;  a  [%        U[&        U   U5      $ U R                  U5      n	U	S   R)                  S5      n[+        U5      u  pL[+        X5      u  pMU	S   R,                  [        ;   a  [/        US5      e[%        XS   R                  U5      $ )z:return: OInfo or OStream object providing information about the given sha
:param index: if not -1, its assumed to be the sha's index in the IndexFiler   Ni   r\  zCould not resolve delta object)rj  rM  r{   r4   r   rN  r   r1   r2   r   r@   r   typer   collect_streams_at_offsetr!   newr   r   r   rH   r   r7   r   )r[   r{   r5   r   r4   r7   r8   r9   
packstreamstreamsdstreambufsrc_sizetarget_sizes                 rA   rm  PackEntity._object  sy    19&&s+E;++//%(C##E*1HI[I[IfIfgmInIuIuIw1x..k)!ZZ..v6
sOOZ__jFWFWXX 44V<G&**73G\\4AAk)S"5g">LL
 44V<G!*//#&C'}F"*3"7F r{""k1%EFFbk..<<rC   c                 &    U R                  US5      $ )zRetrieve information about the object identified by the given sha

:param sha: 20 byte sha1
:raise BadObject:
:return: OInfo instance, with 20 byte shaFrm  r  s     rA   rB  PackEntity.info  s     ||C''rC   c                 &    U R                  US5      $ )zRetrieve an object stream along with its information as identified by the given sha

:param sha: 20 byte sha1
:raise BadObject:
:return: OStream instance, with 20 byte shaTr|  r  s     rA   r@   PackEntity.stream  s     ||C&&rC   c                 (    U R                  SSU5      $ )zMAs ``info``, but uses a PackIndexFile compatible index to refer to the objectNFr|  r[   r   s     rA   info_at_indexPackEntity.info_at_index	  s    ||D%//rC   c                 (    U R                  SSU5      $ )zOAs ``stream``, but uses a PackIndexFile compatible index to refer to the
objectNTr|  r  s     rA   stream_at_indexPackEntity.stream_at_index  s     ||D$..rC   c                     U R                   $ )z*:return: the underlying pack file instance)rN  rZ   s    rA   r%   PackEntity.pack  r2  rC   c                     U R                   $ )z0:return: the underlying pack index file instance)rM  rZ   s    rA   r   PackEntity.index  s    {{rC   c                    U(       a  U R                   R                  5       S:  a  [        S5      eU R                  U5      nU R                   R	                  U5      nU R
                  U   nU R                   R                  U5      n[        R                  nU R                  R                  5       nUn	Sn
X:  a/  [        U	[        -   U5      nX-
  nU" XX-    U
5      n
X-  n	X:  a  M/  U
S-  U:H  $ [        5       nU R                  USS9n[        UR                   UR"                  UR$                  UR&                  5        UR)                  SS9U:X  d   eUR)                  SS9U:H  $ )	a  
Verify that the stream at the given sha is valid.

:param use_crc: if True, the index' crc is run over the compressed stream of
    the object, which is much faster than checking the sha1. It is also
    more prone to unnoticed corruption or manipulation.
:param sha: 20 byte sha1 of the object whose stream to verify
    whether the compressed stream of the object is valid. If it is
    a delta, this only verifies that the delta's data is valid, not the
    data of the actual undeltified object, as it depends on more than
    just this stream.
    If False, the object will be decompressed and the sha generated. It must
    match the given sha

:return: True if the stream is valid
:raise UnsupportedOperation: If the index is version 1 only
:raise BadObject: sha was not foundrq   z=Version 1 indices do not contain crc's, verify by sha insteadr   rp   TrG  Frt   )rM  r   r   rj  r4   rO  rO   zlibr&   rN  r6   minr   r"   rm  r   rq  r   rH   rI   r{   )r[   r{   use_crcr   r4   next_offset	crc_value
crc_update	pack_datacur_posthis_crc_valuerboundr   	shawriterr@   s                  rA   is_valid_streamPackEntity.is_valid_stream  sN   $ {{""$q(*+jkk &&s+E[[''.F**62K.I J

)IGN'Wz1;?'!+Ign,M~!^	 ' #Z/I=="I\\#\6Ffkk6;;	P===.#555===.#55rC   c                      U R                  SS9$ )zY
:return: Iterator over all objects in this pack. The iterator yields
    OInfo instancesFrG  rH  rZ   s    rA   	info_iterPackEntity.info_iterU  s     !!E!22rC   c                      U R                  SS9$ )z[
:return: iterator over all objects in this pack. The iterator yields
    OStream instancesTrG  rH  rZ   s    rA   rI  PackEntity.stream_iter[  s     !!D!11rC   c                    U R                   R                  U5      nUS   R                  [        :X  Ga?  US   nUR                  [        ;   Ga%  UR                  [        :X  a  [        UR                  [        5      (       a4  U R                  R                  UR                  R                  5       5      nO%U R                  R                  UR                  5      nUc   U$ U R                   R                  U R                  R                  U5      5      nUR                  U5        O6U R                   R                  UR                  5      nUR                  U5        UR                  [        ;   a  GM%  U$ )z
As the version in the PackFile, but can resolve REF deltas within this pack
For more info, see ``collect_streams``

:param offset: offset into the pack file at which the object can be foundr\  )rN  r=  r7   r   r   r  r;   
memoryviewrM  r  tobytesr@   r4   r_   )r[   r4   ru  r@   sindexs        rA   rr  $PackEntity.collect_streams_at_offseta  s    **,,V4 2;)+R[F..K/>>Y.!&"3"3Z@@!%!9!9&:K:K:S:S:U!V!%!9!9&:K:K!L~  "ZZ..t{{/A/A&/IJFNN6*
 "ZZ..v/@/@AFNN6*! ..K/* rC   c                 t    U R                  U R                  R                  U R                  U5      5      5      $ )a  
As ``PackFile.collect_streams``, but takes a sha instead of an offset.
Additionally, ref_delta streams will be resolved within this pack.
If this is not possible, the stream will be left alone, hence it is adivsed
to check for unresolved ref-deltas and resolve them before attempting to
construct a delta stream.

:param sha: 20 byte sha1 specifying the object whose related streams you want to collect
:return: list of streams, first being the actual object delta, the last being
    a possibly unresolved base object.
:raise BadObject:)rr  rM  r4   rj  r  s     rA   r=  PackEntity.collect_streams  s0     --dkk.@.@ASASTWAX.YZZrC   Nc                    UnU(       d1  [        U[        [        45      (       d  [        U5      n[        U5      n[	        U5      nUR
                  nSn	Sn
USLnU" [        S[        R                  [        R                  U5      5        U	S-  n	U(       a
  [        5       n
SnU H  nUS-  nSn[        UR                  UR                  5      nU(       a  [        U5      nOSnU" U5        [        R                   " U5      nUR"                  n[%        UR&                  UUUS9u  nnnUUR                  :X  d   eU(       a  U
R)                  UR*                  X5        U	[        U5      U-   -  n	X:X  d  M    O   X:w  a  [-        SXL4-  5      eUR/                  SS	9n[        U5      S
:X  d   eU" U5        U	[        U5      -  n	SnU(       a  U
R                  UU5      nUU4$ )a.  
Create a new pack by putting all objects obtained by the object_iterator
into a pack which is written using the pack_write method.
The respective index is produced as well if index_write is not Non.

:param object_iter: iterator yielding odb output objects
:param pack_write: function to receive strings to write into the pack stream
:param indx_write: if not None, the function writes the index file corresponding
    to the pack.
:param object_count: if you can provide the amount of objects in your iteration,
    this would be the place to put it. Otherwise we have to pre-iterate and store
    all items into a list to get the number, which uses more memory than necessary.
:param zlib_compression: the zlib compression level to use
:return: tuple(pack_sha, index_binsha) binary sha over all the contents of the pack
    and over all contents of the index. If index_write was None, index_binsha will be None

**Note:** The destination of the write functions is up to the user. It could
be a socket, or a file for instance

**Note:** writes only undeltified objectsr   Nr  r  r,   )rK   zKExpected to write %i objects into pack, but received only %i from iteratorsFrt   r0   )r  r   rY   rE   r$   rI   r%   r)   r  rK  rT   r   r7   r   r&   r  compressobjr@   rR   rH   r_   r`   r  r{   )clsobject_iter
pack_writeindex_writeobject_countzlib_compressionobjspack_writerpwriter   r   wants_indexactual_countobjrO   hdrrJ   r-  rL   rM   r|   	index_shas                         rA   
write_packPackEntity.write_pack  s   . kE4=99K(t9L )4""!- 	tFH33X5R5RT`abr	ME CALC ,CKKBCCj3K &&'78GjjG.w||VWWZ[KBC>">SZZ2 3s8b= C+1 8 ']am`||~ ~
 ??%?08}"""8s8}	Hk:I ""rC   c                 ,  ^^ [         R                  " SSU5      u  mn[         R                  " SSU5      u  mnU4S jnU4S jnU R                  XXU5      u  p[        R                  " T5        [        R                  " T5        Sn[        R
                  R                  X+[        U	5      S4-  5      n[        R
                  R                  X+[        U	5      S4-  5      n[        R                  " X\5        [        R                  " Xm5        U " U5      $ )a|  Create a new on-disk entity comprised of a properly named pack file and a properly named
and corresponding index file. The pack contains all OStream objects contained in object iter.
:param base_dir: directory which is to contain the files
:return: PackEntity instance initialized with the new pack

**Note:** for more information on the other parameters see the write_pack method r%   r   c                 2   > [         R                  " TU 5      $ rX   rQ  rI   )r   pack_fds    rA   rf   #PackEntity.create.<locals>.<lambda>  s    rxx3rC   c                 2   > [         R                  " TU 5      $ rX   r  )r   index_fds    rA   rf   r    s    1 5rC   z
pack-%s.%sidx)	tempfilemkstempr  rQ  r   r   rz   r
   rename)r  r  base_dirr  r  	pack_path
index_pathr  r  pack_binshaindex_binshafmtnew_pack_pathnew_index_pathr  r  s                 @@rA   createPackEntity.create  s     &--b&(C'//GXF*3
5$'NN;Kgw$x!

Xj6Mv5V/VWhz+7NPU6V0VW
		)+
		*-=!!rC   )rM  rO  rN  )r\  )F)!r   r   r   r   r   r   r(   rS  r)   rT  r\   r   r   rj  r.  rm  rB  r@   r  r  r%   r   r  r  rI  rr  r=  classmethodr  Z_BEST_SPEEDr  r  r   rd   rC   rA   r*   r*     s    2I
 !LK<&29'=X('0/5n32!F[ =A $t7H7HY# Y#v 8<tO`O` " "rC   r*   rX   );r   r  	gitdb.excr   r   r   r   
gitdb.utilr   r   r	   r
   r   	gitdb.funr   r   r   r   r   r   r   r   r   r   r   gitdb_speedups._perfr   ImportError
gitdb.baser   r   r   r   r   r   r   gitdb.streamr    r!   r"   r#   r$   structr%   binasciir&   gitdb.constr'   r  r   rQ  r   __all__rB   rR   rT   r(   r)   r*   rd   rC   rA   <module>r     s   
 :      	?
      !   	 

5
1]l%VD DN~9I ~9HQ@y Q@lw" w"O  		s   B: :CC