B
    \Q                 @   s   d Z ddlmZ ddlZddlZddlmZ ddlT dZdZ	d	Z
d
ZdZdZG dd deZG dd deZdd ZG dd deZdddZejfddZdS )z
Implements the minimal functionality required
to extract a "Workbook" or "Book" stream (as one big string)
from an OLE2 Compound Document file.
    )print_functionN)unpack   )*s   ࡱc               @   s   e Zd ZdS )CompDocErrorN)__name__
__module____qualname__ r   r   +lib/python3.7/site-packages/xlrd/compdoc.pyr      s   r   c               @   s&   e Zd ZdejfddZdddZdS )	DirNoder   c             C   s   || _ || _td|dd \}| _| _| _| _| _td|dd \| _| _	|dkrbt
d| _nt|d|d	  d
| _g | _d| _td|dd | _|r| | d S )Nz<HBBiii@   P   z<iit   |   r       	utf_16_ler   z<IIIId   )DIDlogfiler   etypeZcolourleft_DID	right_DIDroot_DID	first_SIDtot_sizeZUNICODE_LITERALnameZunicodechildrenparenttsinfodump)selfr   ZdentDEBUGr   Zcbufsizer   r   r   __init__"   s    (zDirNode.__init__r   c             C   sR   t | jd| j| j| j| j| j| j| j| j	| j
| j |dkrNtd| j| jd d S )NzbDID=%d name=%r etype=%d DIDs(left=%d right=%d root=%d parent=%d kids=%r) first_SID=%d tot_size=%d
r   ztimestamp info)file)fprintfr   r   r"   r   r   r   r   r$   r#   r    r!   printr%   )r'   r(   r   r   r   r&   5   s    zDirNode.dumpN)r   )r   r   r   sysstdoutr)   r&   r   r   r   r   r       s   r   c             C   sn   |dk rd S t | || | j | | j| || | _t | || | j | | jdkrjt | || | j d S )Nr   r   )_build_family_treer   r#   appendr$   r   r   r   )dirlistZ
parent_DIDZ	child_DIDr   r   r   r/   @   s     
r/   c               @   sL   e Zd ZdZejdfddZdddZdd	d
Zdd Z	dd Z
dd ZdS )CompDocz
    Compound document handler.

    :param mem:
      The raw contents of the file, as a string, or as an :class:`mmap.mmap`
      object. The only operation it needs to support is slicing.
    r   c       +      C   s  || _ || _|dd tkr$td|dd dkrHtd|dd  td|d	d \}}|rvtd
||f |d || _td|dd \}}|dkrtd| |d d}||krtd| |d d}d|>  | _}d|> | _| jdks| jdkrtd| j| jf |d td|dd \}	| _	}
| _
}}}}t|d }t||\}}|rv|d7 }tdt||f |d || _|| _tddg|  }| _|rtd|||| j|d td||f |d td|	| j	| j
f |d td||f |d td||f |d |d  }d!| }d}ttd"|dd }|| d | }td|d# | d$ |d  }d}|dkr|ttdfkrn|}x|tttfkr|dkrtd%||f |d ||krd&||f }|dkrt||d P t|n|dk r
td'| || r(td(||| f d||< |d7 }|r^||kr^td)||||||d d||  }|t|||||   | }qW |r||krtd*||||||d |rtd+t||d t|d,| g | _d}d}xtt|D ]}|| } | ttfkrq| |kr`|sNtd-|d td.| |f |d d}t||< d}qn| d/k rvtd0|  ||  rtd1| ||  f d$|| < |d7 }|r||krtd2||||||| |d	 d||   }| jt|||||   qW |r0td3t| j|d t| jd,| t|d |r|rtd+t||d t|d,| x$t|t| jD ]}!t| j|!< qlW td3t| j|d t| jd,| | j| jd| j| j| j	d4d5d6}"g }#d7}$xBtdt|"d8D ].}%|$d7 }$|#t|$|"|%|%d8  d| qW |#| _t |#d|#d j! |rFx|#D ]}&|&"| q2W | jd }'|'j#d9ks`t$|'j%dk sx|'j&dkrd:| _'n$| j| jd| j||'j%|'j&d;d d6| _'g | _(|dkr|'j&dkrtd<|d |'j&dkr|}|}(x|dkrd|(dkrd|| rtd=||| f d9||< |(d8 }(d||  })tt|||)|)|  }*| j(|* | j| }qW |rtd>||(f |d |(dkr|tkst$|rtd?|d t| j(d,| |rtd@|d t|d| d S )ANr      zNot an OLE2 compound document      s   z)Expected "little-endian" marker, found %rz<HH   z/
CompDoc format: version=0x%04x revision=0x%04x)r*   "      zMWARNING: sector size (2**%d) is preposterous; assuming 512 and continuing ...	   zYWARNING: short stream sector size (2**%d) is preposterous; assuming 64 and continuing ...   r   i   r   z"@@@@ sec_size=%d short_sec_size=%dz	<iiiiiiii,   L   zAWARNING *** file size (%d) not 512 + multiple of sector size (%d)Bz	sec sizesz mem data: %d bytes == %d sectorsz=SAT_tot_secs=%d, dir_first_sec_sid=%d, min_size_std_stream=%dz'SSAT_first_sec_sid=%d, SSAT_tot_secs=%dz)MSATX_first_sec_sid=%d, MSATX_tot_secs=%d   z<%diz<109im   r   zMSATX: sid=%d (0x%08X)z7MSAT extension: accessing sector %d but only %d in filez%MSAT extension: invalid sector id: %dzMSAT corruption: seen[%d] == %dz	[1]===>>>z	[2]===>>>zMSAT: len =
   z8WARNING *** File is truncated, or OLE2 MSAT is corrupt!!z6INFO: Trying to access sector %d but only %d availabler   zMSAT: invalid sector id: %dz)MSAT extension corruption: seen[%d] == %dz	[3]===>>>z
SAT: len =Z	directory   )r"   seen_idr         r   SSCSzHWARNING *** OLE2 inconsistency: SSCS size is 0 but SSAT size is non-zerozSSAT corruption: seen[%d] == %dz&SSAT last sid %d; remaining sectors %dSSATseen))r   r(   	SIGNATUREr   r   r,   memsec_sizeshort_sec_sizeZdir_first_sec_sidmin_size_std_streamlendivmodmem_data_secsmem_data_lenarrayrG   listmaxEOCSIDFREESIDMSATSIDextendpop	dump_listSATxrangeEVILSID_get_streamr0   r   r1   r/   r   r&   r   AssertionErrorr    r!   rE   rF   )+r'   rI   r   r(   ZrevisionversionZsszZssszrJ   ZSAT_tot_secsZ_unusedZSSAT_first_sec_sidZSSAT_tot_secsZMSATX_first_sec_sidZMSATX_tot_secsrP   rO   Z	left_overrG   ZnentZfmtZtrunc_warnedZMSATZSAT_sectors_reqdZexpected_MSATX_sectorsZactual_MSATX_sectorsZsidmsgoffsetZactual_SAT_sectorsZ
dump_againZmsidxZmsidZsatxZdbytesr1   ZdidposdZsscs_dirZnsecs	start_posZnewsr   r   r   r)   T   s8   
&








$

&


 zCompDoc.__init__Nr   c	             C   s  g }	|}
|d krx|
dkr|d k	rN| j |
 rDtd||
| j |
 f || j |
< ||
|  }|	||||   y||
 }
W q tk
r   td||
f Y qX qW |
tkstn|}x|
dkrj|d k	r| j |
 rtd||
| j |
 f || j |
< ||
|  }|}||kr|}||8 }|	||||   y||
 }
W q tk
rf   td||
f Y qX qW |
tkszt|dkrt| jd||||  d|	S )Nr   z%s corruption: seen[%d] == %dz:OLE2 stream %r: sector allocation table invalid entry (%d)z=WARNING *** OLE2 stream %r: expected size %d, actual size %d
    )	rG   r   r0   
IndexErrorrT   r^   r+   r   join)r'   rI   basesatrJ   	start_sidsizer"   rB   Zsectorssrd   ZtodoZgrabr   r   r   r]     sR    






zCompDoc._get_streamc             C   s   |d }|dd  }| j }xx|| jD ]j}|| j | kr&|| j}|dkrZ|| S |dkrz|sntd| ||S || d tdq&W d S )Nr   r   r   z"Requested component is a 'storage'z'Requested stream is not a 'user stream')r1   r#   r"   lowerr   r   _dir_searchr&   )r'   pathZstorage_DIDheadtailZdlZchildZetr   r   r   rn   M  s    
zCompDoc._dir_searchc          
   C   s~   |  |d}|dkrdS |j| jkrR| j| jd| j| j|j|j||j	d dS | j| j
d| j| j|j|j|d ddS dS )a  
        Interrogate the compound document's directory; return the stream as a
        string if found, otherwise return ``None``.

        :param qname:
          Name of the desired stream e.g. ``'Workbook'``.
          Should be in Unicode or convertible thereto.
        /Ni   r:   )r"   rB   r   z (from SSCS))rn   splitr!   rL   r]   rI   rZ   rJ   r    r   rE   rF   rK   )r'   qnamerc   r   r   r   get_named_stream`  s    	zCompDoc.get_named_streamc             C   s   |  |d}|dkrdS |j| jkr>td||j| jf |j| jkr| | jd| j| j	|j
|j||jd }| jrtd| jd t| jd	| j |S | | jd
| j| j|j
|j|d dd
|jfS dS )aq  
        Interrogate the compound document's directory.

        If the named stream is not found, ``(None, 0, 0)`` will be returned.

        If the named stream is found and is contiguous within the original
        byte sequence (``mem``) used when the document was opened,
        then ``(mem, offset_to_start_of_stream, length_of_stream)`` is returned.

        Otherwise a new string is built from the fragments and
        ``(new_string, 0, length_of_stream)`` is returned.

        :param qname:
          Name of the desired stream e.g. ``'Workbook'``.
          Should be in Unicode or convertible thereto.
        rr   N)Nr   r   z7%r stream length (%d bytes) > file data size (%d bytes)i   r:   z
seen)r*   r8   r   z (from SSCS))rn   rs   r!   rP   r   rL   _locate_streamrI   rZ   rJ   r    r   r(   r,   r   rY   rG   r]   rE   rF   rK   )r'   rt   rc   resultr   r   r   locate_named_streamu  s&    zCompDoc.locate_named_streamc	                sb  |}	|	dk rt d| d}
d}d}g }d}|| d | }x|	dkr| j|	 rtd| | jd t| jd	| j t d
||	| j|	 f || j|	< |d7 }||krt d||| f |	|
d kr||7 }n*|
dkr|||f ||	|  }|| }|	}
||	 }	q>W |	tkst||ks&t|s6 ||fS |||f d fdd|D d|fS )Nr   z%_locate_stream: start_sid (%d) is -veiiiHr   z_locate_stream(%s): seen)r*   r8   z%s corruption: seen[%d] == %dz,%s: size exceeds expected %d bytes; corrupt?re   c             3   s   | ]\}} || V  qd S )Nr   ).0rd   end_pos)rI   r   r   	<genexpr>  s    z)CompDoc._locate_stream.<locals>.<genexpr>)	r   rG   r,   r   rY   r0   rT   r^   rg   )r'   rI   rh   ri   rJ   rj   Zexpected_stream_sizert   rB   rl   prd   rz   ZslicesZ	tot_foundZfound_limitr   )rI   r   rv     sD    
 


zCompDoc._locate_stream)Nr   N)r   )r   r   r   __doc__r-   r.   r)   r]   rn   ru   rx   rv   r   r   r   r   r2   J   s    I
1
(r2   c             C   sT   t d|d| f d|d x*| |||  D ]}t t|d|d q,W t |d d S )Nz%5d%sz = )endr*   )r*   )r,   str)aliststridefdposequalvaluer   r   r   x_dump_line  s    r   c                s   d fdd	}d }d }xvt dt D ]b}|d krF|| |}q, ||   ||  kr,|| kr|| dd || |}q,W |d k	r|d k	r||kr||dd d S )Nr   c                sT   t d| d| f dd x* | |   D ]}t t|dd q,W t d d S )Nz%5d%sz =r~   )r   r*   )r*   )r,   r   )r   r   r   )r   r   r   r   r   
_dump_line  s    zdump_list.<locals>._dump_liner   )r   )r   )r[   rM   )r   r   r   r   rb   Zoldposr   )r   r   r   r   rY     s     rY   )r   )r}   Z
__future__r   rQ   r-   Zstructr   ZtimemachinerH   rT   rU   ZSATSIDrV   r\   	Exceptionr   objectr   r/   r2   r   r.   rY   r   r   r   r   <module>   s(    
   
