
mR\Q                 @   s   d  Z  d d l m Z d d l Z d d l m Z d d l Td d l Z d Z d Z	 d Z
 d	 Z d
 Z d Z Gd d   d e  Z Gd d   d e  Z d d   Z Gd d   d e  Z d d d  Z e j 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   0/var/www/dbchiro/venv/build/xlrd/xlrd/compdoc.pyr
      s   r
   c               @   s4   e  Z d  Z d e j d d  Z d d d  Z d S)DirNoder   c             C   s   | |  _  | |  _ t d | d d   \ } |  _ |  _ |  _ |  _ |  _ t d | d d   \ |  _ |  _	 | d k r t
 d  |  _ n  t | d | d	  d
  |  _ g  |  _ d |  _ t d | d d   |  _ | r |  j |  n  d  S)Nz<HBBiii@   P   z<iit   |   r    r   	utf_16_ler   z<IIIId   )DIDlogfiler   etypeZcolourleft_DID	right_DIDroot_DID	first_SIDtot_sizeZUNICODE_LITERALnameunicodechildrenparenttsinfodump)selfr   ZdentDEBUGr   Zcbufsizer   r   r   __init__    s    		:% 		zDirNode.__init__r   c             C   sx   t  |  j d |  j |  j |  j |  j |  j |  j |  j |  j	 |  j
 |  j  | d k rt t d |  j d |  j n  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&   3   s    (zDirNode.dumpN)r   r   r   sysstdoutr)   r&   r   r   r   r   r      s   r   c             C   s   | d k  r d  St  |  | |  | j  |  | j j |  | |  | _ t  |  | |  | j  |  | j d k r t  |  | |  | j  n  d  S)Nr   r   )_build_family_treer   r#   appendr$   r   r   r   )dirlistZ
parent_DIDZ	child_DIDr   r   r   r/   >   s     r/   c               @   ss   e  Z d  Z d Z e j d d d  Z d d 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 r7 t d   n  | d d  d k rj t d | d d    n  t d | d	 d   \ } } | r t d
 | | f d | n  | |  _ t d | d d   \ } } | d k r t d | d | d } n  | | k r&t d | d | d } n  d | >|  _ } d | >|  _ |  j d k sb|  j d k rt d |  j |  j f d | n  t d | d d   \ }	 |  _	 }
 |  _
 } } } } t |  d } t | |  \ } } | r| d 7} t d t |  | f d | n  | |  _ | |  _ t j 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 | n  | d  } d! | } d } t t d" | d d    } | | d | } t d | d# | d$ | d  } d } | d k rw| t t d f k rwnb| } xY| t t t f k r| d k rt d% | | f d | n  | | k r	d& | | f } | d k rt | d | Pn  t |   n | d k  r(t d' |   n  | | rOt d( | | | f   n  d | | <| d 7} | r| | k rt d) | | | | | d | n  d | | } | j t | | | | |    | j   } qW| r| | k rt d* | | | | | d | n  | r?t d+ t |  d | t | d, |  n  g  |  _ d } d } x`t t |   D]L} | | }  |  t t f k rqgn  |  | k r| st d- d | t d. |  | f d | d } n  t | | <d } qgn |  d@ k  r	t d/ |    n  | |  r0t d0 |  | |  f   n  d$ | |  <| d 7} | r~| | k r~t d1 | | | | | | |  d | n  d | |  } |  j j t | | | | |    qgW| rt d2 t |  j  d | t |  j d, |  t d |  n  | r| rt d+ t |  d | t | d, |  x- t | t |  j   D] }! t |  j |! <qJWt d2 t |  j  d | t |  j d, |  n  |  j |  j d |  j |  j |  j	 d3 d4 d5 d6 }" g  }# dA }$ xT t d t |"  d7  D]: }% |$ d 7}$ |# j t |$ |" |% |% d7  d |   qW|# |  _ t  |# d |# d j!  | rpx |# D] }& |& j" |  qVWn  |  j d }' |' j# d8 k st$  |' j% d k  s|' j& d k rd9 |  _' n9 |  j |  j d |  j | |' j% |' j& d3 d: d5 d  |  _' g  |  _( | d k r,	|' j& d k r,	t d; d | n  |' j& d k r3
| } | }( x | d k r	|( d k r	| | r	t d< | | | f   n  d8 | | <|( d 8}( d | | }) t t | | |) |) |    }* |  j( j |*  |  j | } qJ	W| r
t d= | |( f d | n  |( d k r*
| t k s3
t$  n  | r_
t d> d | t |  j( d, |  n  | r
t d? d | t | d |  n  d  S)BNr      zNot an OLE2 compound document      s   z)Expected "little-endian" marker, found %rz<HH   z/
CompDoc format: version=0x%04x revision=0x%04xr*   "      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=%dr   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 availablezMSAT: invalid sector id: %dz)MSAT extension corruption: seen[%d] == %dz	[3]===>>>z
SAT: len =r!   	directoryseen_idr      r	   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seenr   ))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arrayrE   listmaxEOCSIDFREESIDMSATSIDextendpop	dump_listSATxrangeEVILSID_get_streamr0   r   r1   r/   r   r&   r   AssertionErrorr   r    rC   rD   )+r'   rH   r   r(   revisionversionZsszZssszrI   ZSAT_tot_secsZ_unusedZSSAT_first_sec_sidZSSAT_tot_secsZMSATX_first_sec_sidZMSATX_tot_secsrO   rN   Z	left_overrE   Znent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_posnewsr   r   r   r)   R   s8   					#7
		 

#!


"$"	
	



(+
.		


# !zCompDoc.__init__Nr   c	             C   s%  g  }	 | }
 | d  k r x |
 d k r | d  k	 rs |  j  |
 rc t d | |
 |  j  |
 f   n  | |  j  |
 <n  | |
 | } |	 j | | | |   y | |
 }
 Wq t k
 r t d | |
 f   Yq Xq W|
 t k st  n*| } x |
 d k r| d  k	 rO|  j  |
 r?t d | |
 |  j  |
 f   n  | |  j  |
 <n  | |
 | } | } | | k rx| } n  | | 8} |	 j | | | |   y | |
 }
 Wq t k
 rt d | |
 f   Yq Xq W|
 t k st  | d k rt |  j d | | | |  n  d j |	  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
    )	rE   r
   r0   
IndexErrorrS   r]   r+   r   join)r'   rH   basesatrI   	start_sidsizer!   rA   Zsectorssre   todoZgrabr   r   r   r\     sR    ##	
	zCompDoc._get_streamc             C   s   | d } | d d   } |  j  } x | | j D] } | | j j   | j   k r1 | | j } | d k rw | | S| d k r | s t d   n  |  j | |  S| | j d  t d   q1 q1 Wd  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taildlchildetr   r   r   rq   L  s    
	zCompDoc._dir_searchc             C   s   |  j  | j d   } | d k r( d S| j |  j k rx |  j |  j d |  j |  j | j | j d | d | j	 d S|  j |  j
 d |  j |  j | j | j d | d d d Sd 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. ``u'Workbook'``.
          Should be in Unicode or convertible thereto.
        /Ni   r!   rA   r:   r   z (from SSCS))rq   splitr    rK   r\   rH   rY   rI   r   r   rC   rD   rJ   )r'   qnamerd   r   r   r   get_named_stream_  s    	zCompDoc.get_named_streamc          
   C   s&  |  j  | j d   } | d k r( d S| j |  j k r\ t d | | j |  j f   n  | j |  j k r |  j |  j d |  j |  j	 | j
 | j | | j d  } |  j r t d d |  j t |  j d	 |  j  n  | S|  j |  j d |  j |  j | j
 | j | d
 d  d | j f Sd S)ar  
        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. ``u'Workbook'``.
          Should be in Unicode or convertible thereto.
        rx   Nr   z7%r stream length (%d bytes) > file data size (%d bytes)i   r:   z
seenr*   r8   z (from SSCS))Nr   r   )rq   ry   r    rO   r
   rK   _locate_streamrH   rY   rI   r   r   r(   r,   r   rX   rE   r\   rC   rD   rJ   )r'   rz   rd   resultr   r   r   locate_named_streamt  s&    	zCompDoc.locate_named_streamc	                s  | }	 |	 d k  r% t  d |   n  d }
 d } d } g  } d } | | d | } x|	 d k rk|  j |	 r t d | d |  j t |  j d	 |  j  t  d
 | |	 |  j |	 f   n  | |  j |	 <| d 7} | | k rt  d | | | f   n  |	 |
 d k r| | 7} n: |
 d k r@| j | | f  n  | |	 | } | | } |	 }
 | |	 }	 qX W|	 t k s~t  | | k st  | s  | | f S| j | | f  d j   f d d   | D  d | f S)Nr   z%_locate_stream: start_sid (%d) is -vec   i'  i"  r   z_locate_stream(%s): seenr*   r8   z%s corruption: seen[%d] == %dz,%s: size exceeds expected %d bytes; corrupt?rg   c             3   s%   |  ] \ } }   | |  Vq d  S)Nr   ).0re   end_pos)rH   r   r   	<genexpr>  s    z)CompDoc._locate_stream.<locals>.<genexpr>iiiH)	r
   rE   r,   r   rX   r0   rS   r]   ri   )r'   rH   rj   rk   rI   rl   Zexpected_stream_sizerz   rA   rn   pre   r   ZslicesZ	tot_foundZfound_limitr   )rH   r   r|     sD     #

zCompDoc._locate_stream)r   r   r   __doc__r-   r.   r)   r\   rq   r{   r~   r|   r   r   r   r   r2   H   s   1(r2   c             C   sp   t  d | d | f d d d | x8 |  | | |  D]" } t  t |  d d d | q9 Wt  d |  d  S)Nz%5d%sz =end r*   )r,   str)aliststridefdposequalvaluer   r   r   x_dump_line  s    $ r   c                s  d     f d d  } d  } d  } x t  d t      D] } | d  k re | |  | } q@   | |     | |   k r@ | |  k r | |  d d n  | |  | } q@ q@ W| d  k	 r| d  k	 r| | k r| | d d n  d  S)Nr   c                sp   t  d |  d | f d d d  x8   |  |    D]" } t  t |  d d d  q9 Wt  d   d  S)Nz%5d%sz =r   r   r*   )r,   r   )r   r   r   )r   r   r   r   r   
_dump_line  s    $ zdump_list.<locals>._dump_liner   r   )rZ   rL   )r   r   r   r   rc   oldposr   )r   r   r   r   rX     s    
	(
$rX   )r   
__future__r   r-   structr   ZtimemachinerP   rG   rS   rT   ZSATSIDrU   r[   	Exceptionr
   objectr   r/   r2   r   r.   rX   r   r   r   r   <module>   s$   
 
 