
    XfD                     T   d 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
mZmZmZmZ ddlmZ ddlmZ  ej&                  e      Z G d dej$                  j,                        Z G d d	ej$                  j,                        Z G d
 dej$                  j,                        Z G d dej$                  j,                        Z G d dej$                  j6                        Zde
e   fdZ G d dej$                  j<                        Z G d dej$                  j>                        Zy)zoRenderers.

Renderers display the unified output format in some manner (be it text
or file or graphical output
    N)	AnyCallableDictIterableListOptionalTupleTypeVarUnion)
interfaces)	renderersc                       e Zd ZdZy)UnreadableValuezQClass that represents values which are empty because the data cannot be
    read.N__name__
__module____qualname____doc__     Z/home/panchajanya/Development/work/volatility3/volatility3/framework/renderers/__init__.pyr   r      s    r   r   c                       e Zd ZdZy)UnparsableValuezbClass that represents values which are empty because the data cannot be
    interpreted correctly.Nr   r   r   r   r   r      s    r   r   c                       e Zd ZdZy)NotApplicableValuez]Class that represents values which are empty because they don't make
    sense for this node.Nr   r   r   r   r   r      s    r   r   c                       e Zd ZdZy)NotAvailableValuea  Class that represents values which cannot be provided now (but might in
    a future run)

    This might occur when information packed with volatility (such as
    symbol information) is not available, but a future version or a
    different run may later have that information available (ie, it
    could be applicable, but we can't get it and it's not because it's
    unreadable or unparsable). Unreadable and Unparsable should be used
    in preference, and only if neither fits should this be used.
    Nr   r   r   r   r   r   $   s    	r   r   c            
          e Zd ZdZdedddeej                  j                     de	ej                  j                     ddf
d	Zdefd
Zdeeef   defdZdefdZde	ej                  j                     ddfdZdeeef   fdZede	ej                  j                     fd       Zedefd       Zedeej                  j                     fd       Zedefd       ZddededdfdZy)TreeNodez4Class representing a particular node in a tree grid.pathtreegridTreeGridparentvaluesreturnNc                     t        |t              st        d      || _        || _        || _        | j                  |        |j                  | | _        y )Nz(Treegrid must be an instance of TreeGrid)	
isinstancer"   	TypeError	_treegrid_parent_path_validate_valuesRowStructure_values)selfr    r!   r#   r$   s        r   __init__zTreeNode.__init__4   sQ     (H-FGG!
f%,x,,f5r   c                 <    d| j                    d| j                   dS )Nz<TreeNode [z] - >)r    r.   r/   s    r   __repr__zTreeNode.__repr__C   s    TYYKtDLL>;;r   itemc                 V    | j                   j                  |       j                  |      S N)r)   children__getitem__)r/   r5   s     r   r9   zTreeNode.__getitem__F   s"    ~~&&t,88>>r   c                 J    t        | j                  j                  |             S r7   )lenr)   r8   r3   s    r   __len__zTreeNode.__len__I   s    4>>**4011r   c           
      "   t        |t        j                  j                        r+t	        |      t	        | j
                  j                        k(  st        d      t        t	        | j
                  j                              D ]  }| j
                  j                  |   }||   }t        ||j                  t        j                  j                  f      rRt        dj                  ||j                  t        |      |j                               y)zqA function for raising exceptions if a given set of values is
        invalid according to the column properties.z[Values must be a list of objects made up of simple types and number the same as the columnszRValues item with index {} is the wrong type for column {} (got {} but expected {})N)r'   collectionsabcSequencer;   r)   columnsr(   rangetyper   r   BaseAbsentValueformatname)r/   r$   indexcolumnvals        r   r,   zTreeNode._validate_valuesL   s     v{778Fs4>>#9#9::m  3t~~5567 	E^^++E2F-CcFKK1E1E1U1U#VWhoov{{DIv{{ 		r   c                 6    | j                   j                         S )z0Returns the contents of the node as a dictionary)r.   _asdictr3   s    r   asdictzTreeNode.asdictc   s    ||##%%r   c                 ,    t        | j                        S )zSReturns the list of values from the particular node, based on column
        index.)listr.   r3   s    r   r$   zTreeNode.valuesg   s     DLL!!r   c                     | j                   S )zReturns a path identifying string.

        This should be seen as opaque by external classes, Parsing of
        path locations based on this string are not guaranteed to remain
        stable.
        )r+   r3   s    r   r    zTreeNode.pathm   s     zzr   c                     | j                   S )z-Returns the parent node of this node or None.)r*   r3   s    r   r#   zTreeNode.parentw   s     ||r   c                 f    t        | j                  j                  t        j                              S )z*Return the path depth of the current node.)r;   r    splitr"   path_sepr3   s    r   
path_depthzTreeNode.path_depth|   s"     499??8#4#4566r   addedc                 t   | j                   j                  t        j                        }|j                  t        j                        }t	        |      dz
  }t        ||         t        |d         k\  r!t        t        ||         |rdndz         ||<   t        j                  j                  |      | _         y)zUpdates the path based on the addition or removal of a node higher
        up in the tree.

        This should only be called by the containing TreeGrid and
        expects to only be called for affected nodes.
           N)r+   rR   r"   rS   r;   intstrjoin)r/   r    rU   
componentschangedchanged_indexs         r   path_changedzTreeNode.path_changed   s     ZZ%%h&7&78
**X../Gq(z-()S-==(+J}-.u!"E)J}% &&++J7
r   )F)r   r   r   r   rZ   r   r   r   r   r   	BaseTypesr0   r4   r   rY   slicer   r9   r<   r,   r   rL   propertyr$   r    r#   rT   boolr_   r   r   r   r   r   1   sq   >66 6 --667	6
 Z))3346 
6<# <?c5j 1 ?c ?2 2tJ,@,@,J,J'K PT .&S#X & "Z11;;< " "
 c   !5!5!>!>?   7C 7 78 8T 8d 8r   r   namesc           	      z    t        j                  d| D cg c]  }t        j                  |       c}      S c c}w )Nr-   )r>   
namedtupler"   sanitize_name)rd   rF   s     r   RowStructureConstructorrh      s3    !!%H$//5H Hs   8
c                      e Zd ZdZdZdeeeej                  j                  f      deeeeef         ddfdZededefd	       Z	 	 	 d"d
ej                  j"                  dededee   fdZedefd       Zedeej                  j0                     fd       Zedefd       Zdeej                  j6                     deej                  j6                     fdZdeej                  j6                     defdZd Zdeej                  j6                     dedefdZdeej                  j6                     dee   dedefdZ d Z!d Z" e#d      Z$	 d#deej                  j6                     d
e%ej                  j6                  e$ge$f   de$deej                  jL                     fdZ'	 d#deej                  j6                     d
e%d e$deej                  jL                     de$f
d!Z(y)$r"   a  Class providing the interface for a TreeGrid (which contains TreeNodes)

    The structure of a TreeGrid is designed to maintain the structure of the tree in a single object.
    For this reason each TreeNode does not hold its children, they are managed by the top level object.
    This leaves the Nodes as simple data carries and prevents them being used to manipulate the tree as a whole.
    This is a data structure, and is not expected to be modified much once created.

    Carrying the children under the parent makes recursion easier, but then every node is its own little tree
    and must have all the supporting tree functions.  It also allows for a node to be present in several different trees,
    and to create cycles.
    |rA   	generatorr%   Nc                    d| _         d| _        g | _        g }t        |      dk  rt	        d      |D ]{  \  }}t        || j                        }|s/t        dj                  ||j                  j                              |j                  t        j                  j                  ||             } t        |D cg c]  }|j                    c}      | _        || _        |g }t'        |      }|| _        yc c}w )a  Constructs a TreeGrid object using a specific set of columns.

        The TreeGrid itself is a root element, that can have children but no values.
        The TreeGrid does *not* contain any information about formatting,
        these are up to the renderers and plugins.

        Args:
            columns: A list of column tuples made up of (name, type).
            generator: An iterable containing row for a tree grid, each row contains a indent level followed by the values for each column in order.
        Fr   rW   z5Columns must be a list containing at least one columnz)Column {}'s type is not a simple type: {}N)
_populated
_row_count	_childrenr;   
ValueError
issubclass
base_typesr(   rE   	__class__r   appendr   r   Columnrh   rF   r-   _columnsiter
_generator)r/   rA   rk   converted_columnsrF   column_typeis_simple_typerH   s           r   r0   zTreeGrid.__init__   s      >@?Aw<!TUU!( 	UD+'T__EN!?FFk33<< 
 $$Z%9%9%@%@{%ST	U 4'89VV[[9
 *IO	# :s   :C7textc                 V    d}| j                         D ]  }|dk7  s	||dv r|ndz  } |S )N  &abcdefghiljklmnopqrstuvwxyz_0123456789_)lower)r|   outputletters      r   rg   zTreeGrid.sanitize_name   sE    jjl 	F}!II 	 r   functioninitial_accumulatorfail_on_errorsc                    |}|*dt         j                  j                  dt        dt        fd}| j                  s	 g }| j
                  D ]d  \  }}t        t        |      |      }|dkD  r||dz
     nd}	| j                  |	|      }
|d| |
gz   }|	 ||
|      }| xj                  dz  c_	        f 	 d	| _        yd	| _        y# t        $ r.}|r t        j                  d|        d	| _        |cY d}~S d}~ww xY w)
a  Populates the tree by consuming the TreeGrid's construction
        generator Func is called on every node, so can be used to create output
        on demand.

        This is equivalent to a one-time visit.

        Args:
            function: The visitor to be called on each row of the treegrid
            initial_accumulator: The initial value for an accumulator passed to the visitor to allow it to maintain state
            fail_on_errors: A boolean defining whether exceptions should be caught or bubble up
        N_x_yr%   c                      y r7   r   )r   r   s     r   r   z#TreeGrid.populate.<locals>.function   s    r   r   rW   zException during population: T)r   r   r   r   	populatedrx   minr;   _appendrn   	Exceptionvollogdebugrm   )r/   r   r   r   accumulator
prev_nodeslevelr5   parent_indexr#   treenodeexcps               r   populatezTreeGrid.populate   s   " *Z11::    ~~BD
#'?? )KE4#&s:#>L=IA=MZq(89SWF#||FD9H!+Al!;xj!HJ+&.x&EOOq(O)    !<TFCD"&s   A5C 	C9#C4.C94C9c                     | j                   S )z_Indicates that population has completed and the tree may now be
        manipulated separately.)rm   r3   s    r   r   zTreeGrid.populated  s     r   c                     | j                   S )z;Returns the available columns and their ordering and types.)rv   r3   s    r   rA   zTreeGrid.columns  s     }}r   c                     | j                   S )z%Returns the number of rows populated.)rn   r3   s    r   	row_countzTreeGrid.row_count  s     r   nodec                 V    | j                  |      D cg c]  \  }}|	 c}}S c c}}w )z3Returns the subnodes of a particular node in order.)_find_children)r/   r   r   s      r   r8   zTreeGrid.children  s'     %)$7$7$=>q>>>s   %c                     | j                   }	 |;|j                  j                  | j                        D ]  }|t	        |         \  }} |S # t
        $ r g cY S w xY w)zvReturns the children list associated with a particular node.

        Returns None if the node does not exist
        )ro   r    rR   rS   rY   
IndexError)r/   r   r8   path_componentr   s        r   r   zTreeGrid._find_children  sj    
 >>	&*iioodmm&D @N"*3~+>"?KAx@   	I	s   =A AAc                 4    |t        d      |j                  S )z\Returns the values for a particular node.

        The values returned are mutable,
        z-Node must be a valid node within the TreeGrid)r(   r$   )r/   r   s     r   r$   zTreeGrid.values*  s    
 <KLL{{r   r#   r$   c                 (    | j                  |d|      S )zyAdds a new node at the top level if parent is None, or under the
        parent node otherwise, after all other children.N)_insert)r/   r#   r$   s      r   r   zTreeGrid._append3  s    
 ||FD&11r   positionc                 l  	 d}| j                  |      }||j                  | j                  z   }||t        t	        |            z   	n1|t        |      z   	||d D ]  \  }}| j                  |	fdd        t        	| ||      }||j                  |g f       |S |j                  ||g f       |S )z8Inserts an element into the tree at a specific position.r~   Nc                 (    | j                  d      S )NT)r_   )childr   newpaths     r   <lambda>z"TreeGrid._insert.<locals>.<lambda>K  s    5+=+=gt+L r   )	r   r    rS   rZ   r;   visitr   rt   insert)
r/   r#   r   r$   parent_pathr8   r   r   	tree_itemr   s
            @r   r   zTreeGrid._insert:  s     &&v. ++5K!CH$66G!CM1G#HI. a

Ld
 WdFF;	OOYO,  OOHy"o6r   c                 L    |j                   j                  |j                         S )z?Returns true if descendent is a child, grandchild, etc of node.)r    
startswith)r/   r   
descendants      r   is_ancestorzTreeGrid.is_ancestorU  s    ))$))44r   c                 0      j                  d fdd      S )z&Returns the maximum depth of the tree.Nc                 :    t        |j                  |             S r7   )maxrT   )nar/   s     r   r   z$TreeGrid.max_depth.<locals>.<lambda>[  s    SDOOA4F-G r   r   )r   r3   s   `r   	max_depthzTreeGrid.max_depthY  s    zz$ GKKr   _Tsort_keyc                     | j                   s| j                          | j                  |      }|}|	 |||      }|?|)|t        |fd      }|j                  st        |      }| j                  ||||      }|S )a  Visits all the nodes in a tree, calling function on each one.

        function should have the signature function(node, accumulator) and return new_accumulator
        If accumulators are not needed, the function must still accept a second parameter.

        The order of that the nodes are visited is always depth first, however, the order children are traversed can
        be set based on a sort_key function which should accept a node's values and return something that can be
        sorted to receive the desired order (similar to the sort/sorted key).

        We use the private _find_children function so that we don't have to re-traverse the tree
        for every node we descend further down
        c                 .     | d   j                         S Nr   r$   xsort_key_not_nones    r   r   z TreeGrid.visit.<locals>.<lambda>  s    ,=adkk,J r   key)r   r   r   sorted	ascendingreversed_visit)r/   r   r   r   r   r8   r   r   s          @r   r   zTreeGrid.visit_  s    & ~~MMO &&t,)"4)<=K#$,!!"J  ))'1H++h+xPKr   list_of_childrenr   c                     |R|D ]M  \  }} |||      }|)|t        |fd      }|j                  st        |      }| j                  ||||      }O |S )z=Visits all the nodes in a tree, calling function on each one.c                 .     | d   j                         S r   r   r   s    r   r   z!TreeGrid._visit.<locals>.<lambda>  s    0A!A$++0N r   r   )r   r   r   r   )r/   r   r   r   r   r   r8   r   s          @r   r   zTreeGrid._visit  sy     '/ 	U8&q+6'(0%% &N H $--#+H#5"kk(Hk8T	U r   )NNTr7   ))r   r   r   r   rS   r   r	   rZ   r   r   r`   r   r   rY   r0   staticmethodrg   VisitorSignaturer   rc   r   r   rb   r   ru   rA   r   r   r8   r   r$   r   r   r   r   r
   r   r   ColumnSortKeyr   r   r   r   r   r"   r"      s   
 H&$eC!5!5!?!??@A&$ HU3:%678&$ 
	&$P 	C 	C 	 	 ;?#'#	)&&77) !) 	)
 
)	)V 4  
 j2299:   3  ?Z11::;?	j""++	,?8J,@,@,I,I#J s 2z33<<=2GJ2	2--667 3- 	
 
65L 
B BF&z++445& J00992>BC&  	&
 ://==>&Z BFz33<<=  	
 ://==> 
r   r"   c            	       >    e Zd Z	 d	dedededdfdZdee   defdZ	y)
r   r!   column_namer   r%   Nc                 4   d }d | _         || _        t        t        |j                              D ]P  }|j                  |   }|j
                  j                         |j                         k(  s>|}|j                  | _         R |t        d|       || _	        y )Nz&Column not found in TreeGrid columns: )
_typer   rB   r;   rA   rF   r   rC   rp   _index)r/   r!   r   r   r   irH   s          r   r0   zColumnSortKey.__init__  s     
"s8++,- 	)A%%a(F{{  "k&7&7&99#[[
		)
 >Ek]STTr   r$   c                    || j                      }t        |t        j                  j                        r| j
                  t        j                  k(  rt        j                  j                  }|S | j
                  t        t        fv rd}|S | j
                  t        k(  rd}|S | j
                  t        t        j                  fv rd}|S | j
                  t        k(  rd}|S )z(The key function passed as the sort key.rX   F-r   )r   r'   r   r   rD   r   datetimer   rY   floatrc   rZ   Disassemblybytes)r/   r$   values      r   __call__zColumnSortKey.__call__  s    t{{#eZ11AABzzX... ))--  U|+  t#
 	 Y%:%:;;  u$r   )T)
r   r   r   r"   rZ   rc   r0   r   r   r   r   r   r   r   r     sA    FJ /2?C	tCy S r   r   ) r   r>   collections.abcr   loggingtypingr   r   r   r   r   r   r	   r
   r   volatility3.frameworkr    volatility3.framework.interfacesr   	getLoggerr   r   rD   r   r   r   r   r   rZ   rh   r"   r   r   r   r   <module>r      s   
     W W W , 6			8	$j**:: 
j**:: 
--== 


,,<< 
^8z##,, ^8B49 Bz##,, BJJ((66 r   